// Path: impl/src/main/java/com/guigarage/binding/Binding.java
// public class Binding {
// 
//     public static <T> ConvertableBidirectionalBindable<T> bind(Property<T> property) {
//         return new ConvertableBidirectionalBindable<T>() {
// 
//             private Consumer<Throwable> errorHandler = e -> e.printStackTrace();
// 
//             private boolean bindingCalled = false;
// 
//             @Override
//             public <U> Subscription bidirectionalTo(Property<U> toProperty, Function<U, T> converter, Function<T, U> converter2) {
//                 Subscription subscription1 = to(toProperty, converter);
//                 Subscription subscription2 = bind(property, toProperty, converter2);
//                 return () -> {
//                     subscription1.unsubscribe();
//                     subscription2.unsubscribe();
//                 };
//             }
// 
//             @Override
//             public <U> Subscription to(Observable<U> observable, Function<U, T> converter) {
//                 return bind(observable, property, converter);
//             }
// 
//             private <U, V> Subscription bind(Observable<U> observable, Property<V> property, Function<U, V> converter) {
//                 return observable.onChanged(e -> {
//                     if(!bindingCalled) {
//                         bindingCalled = true;
//                         try {
//                             property.setValue(converter.apply(e.getValue()));
//                         } catch (Exception ex) {
//                             errorHandler.accept(ex);
//                         } finally {
//                             bindingCalled = false;
//                         }
//                     }
//                 });
//             }
// 
//             @Override
//             public ConvertableBindable<T> withErrorHandler(Consumer<Throwable> handler) {
//                 this.errorHandler = errorHandler;
//                 return this;
//             }
// 
//         };
//     }
// }
// 
// Path: impl/src/main/java/com/guigarage/observer/BasicProperty.java
// public class BasicProperty<V> extends BasicObservable<V> implements Property<V> {
// 
//     @Override
//     public void setValue(V value) {
//         updateValue(value);
//     }
// }
// 
// Path: api/src/main/java/javax/observer/Property.java
// public interface Property<V> extends Observable<V> {
// 
//     /**
//      * Replaces the internal value with the given new value. This should end in calling the
//      * {@link ValueChangeListener#valueChanged(ValueChangeEvent)} method on all registered
//      * listeners.
//      * @param value the new value
//      */
//     void setValue(V value);
// }


import com.guigarage.binding.Binding;
import com.guigarage.observer.BasicProperty;
import javax.observer.Property;
package com.guigarage.examples;



public class BindingExample {

    public static void main(String[] args) {
// Path: impl/src/main/java/com/guigarage/binding/Binding.java
// public class Binding {
// 
//     public static <T> ConvertableBidirectionalBindable<T> bind(Property<T> property) {
//         return new ConvertableBidirectionalBindable<T>() {
// 
//             private Consumer<Throwable> errorHandler = e -> e.printStackTrace();
// 
//             private boolean bindingCalled = false;
// 
//             @Override
//             public <U> Subscription bidirectionalTo(Property<U> toProperty, Function<U, T> converter, Function<T, U> converter2) {
//                 Subscription subscription1 = to(toProperty, converter);
//                 Subscription subscription2 = bind(property, toProperty, converter2);
//                 return () -> {
//                     subscription1.unsubscribe();
//                     subscription2.unsubscribe();
//                 };
//             }
// 
//             @Override
//             public <U> Subscription to(Observable<U> observable, Function<U, T> converter) {
//                 return bind(observable, property, converter);
//             }
// 
//             private <U, V> Subscription bind(Observable<U> observable, Property<V> property, Function<U, V> converter) {
//                 return observable.onChanged(e -> {
//                     if(!bindingCalled) {
//                         bindingCalled = true;
//                         try {
//                             property.setValue(converter.apply(e.getValue()));
//                         } catch (Exception ex) {
//                             errorHandler.accept(ex);
//                         } finally {
//                             bindingCalled = false;
//                         }
//                     }
//                 });
//             }
// 
//             @Override
//             public ConvertableBindable<T> withErrorHandler(Consumer<Throwable> handler) {
//                 this.errorHandler = errorHandler;
//                 return this;
//             }
// 
//         };
//     }
// }
// 
// Path: impl/src/main/java/com/guigarage/observer/BasicProperty.java
// public class BasicProperty<V> extends BasicObservable<V> implements Property<V> {
// 
//     @Override
//     public void setValue(V value) {
//         updateValue(value);
//     }
// }
// 
// Path: api/src/main/java/javax/observer/Property.java
// public interface Property<V> extends Observable<V> {
// 
//     /**
//      * Replaces the internal value with the given new value. This should end in calling the
//      * {@link ValueChangeListener#valueChanged(ValueChangeEvent)} method on all registered
//      * listeners.
//      * @param value the new value
//      */
//     void setValue(V value);
// }


// Path: impl/src/main/java/com/guigarage/examples/BindingExample.java
import com.guigarage.binding.Binding;
import com.guigarage.observer.BasicProperty;
import javax.observer.Property;

package com.guigarage.examples;



public class BindingExample {

    public static void main(String[] args) {
        Property<String> stringProperty1 = new BasicProperty<>();