// Path: api/src/main/java/javax/observer/Observable.java
// public interface Observable<V> {
// 
//     /**
//      * Returns the current value.
//      * @return the value
//      */
//     V getValue();
// 
//     /**
//      * Returns an {@link Optional} that contains the current value or {@code null}. This is a
//      * convenience method that can be used to acces the value by using a fluent API based on
//      * the {@link Optional} API.
//      * @return an {@link Optional} that contains the current value or {@code null}
//      */
//     default Optional<V> value() {
//         return Optional.ofNullable(getValue());
//     }
// 
//     Subscription onChanged(ValueChangedListener<? super V> listener);
// 
//     default Subscription onChangedAndCall(final ValueChangedListener<? super V> listener) {
//         final Subscription subscription = onChanged(listener);
//         listener.valueChanged(new ValueChangedEvent<V>() {
//             @Override
//             public Observable<V> getObservable() {
//                 return Observable.this;
//             }
// 
//             @Override
//             public V getValue() {
//                 return Observable.this.getValue();
//             }
//         });
//         return subscription;
//     }
// 
//     Subscription onWillChange(ValueWillChangeListener<? super V> listener);
// }
// 
// Path: api/src/main/java/javax/observer/Subscription.java
// @FunctionalInterface
// public interface Subscription {
// 
//     void unsubscribe();
// }
// 
// Path: api/src/main/java/javax/observer/ValueChangedEvent.java
// public interface ValueChangedEvent<V> {
// 
//     Observable<V> getObservable();
// 
//     default Optional<V> value() {
//         return Optional.ofNullable(getValue());
//     }
// 
//     V getValue();
// }
// 
// Path: api/src/main/java/javax/observer/ValueChangedListener.java
// @FunctionalInterface
// public interface ValueChangedListener<V> extends EventListener {
// 
//     void valueChanged(ValueChangedEvent<? extends V> event);
// 
// }
// 
// Path: api/src/main/java/javax/observer/ValueWillChangeListener.java
// @FunctionalInterface
// public interface ValueWillChangeListener<V> extends EventListener {
// 
//     void valueWillChange(ValueWillChangeEvent<? extends V> event);
// 
// }


import javax.observer.Observable;
import javax.observer.Subscription;
import javax.observer.ValueChangedEvent;
import javax.observer.ValueChangedListener;
import javax.observer.ValueWillChangeListener;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

        if(inWillChangeEvent) {
            throw new IllegalStateException("Value can not change while willChangeEvents are handled!");
        }
        if (this.value != value) {
            boolean canChange = fireWillChangeEvent(value);
            if(canChange) {
                try {
                    this.value = value;
                } finally {
                    fireChangedEvent(this.value);
                }
            }
        }
    }

    private boolean fireWillChangeEvent(final V newValue) {
        inWillChangeEvent = true;
        try {
            final ValueWillChangeEventImpl<V> event = new ValueWillChangeEventImpl<>(this, newValue);
            Iterator<ValueWillChangeListener<? super V>> listenerIterator = willChangeListeners.iterator();
            while (listenerIterator.hasNext() && !event.isVetoCalled()) {
                listenerIterator.next().valueWillChange(event);
            }
            return !event.isVetoCalled();
        } finally {
            inWillChangeEvent = false;
        }
    }

    private void fireChangedEvent(final V newValue) {

// Path: api/src/main/java/javax/observer/Observable.java
// public interface Observable<V> {
// 
//     /**
//      * Returns the current value.
//      * @return the value
//      */
//     V getValue();
// 
//     /**
//      * Returns an {@link Optional} that contains the current value or {@code null}. This is a
//      * convenience method that can be used to acces the value by using a fluent API based on
//      * the {@link Optional} API.
//      * @return an {@link Optional} that contains the current value or {@code null}
//      */
//     default Optional<V> value() {
//         return Optional.ofNullable(getValue());
//     }
// 
//     Subscription onChanged(ValueChangedListener<? super V> listener);
// 
//     default Subscription onChangedAndCall(final ValueChangedListener<? super V> listener) {
//         final Subscription subscription = onChanged(listener);
//         listener.valueChanged(new ValueChangedEvent<V>() {
//             @Override
//             public Observable<V> getObservable() {
//                 return Observable.this;
//             }
// 
//             @Override
//             public V getValue() {
//                 return Observable.this.getValue();
//             }
//         });
//         return subscription;
//     }
// 
//     Subscription onWillChange(ValueWillChangeListener<? super V> listener);
// }
// 
// Path: api/src/main/java/javax/observer/Subscription.java
// @FunctionalInterface
// public interface Subscription {
// 
//     void unsubscribe();
// }
// 
// Path: api/src/main/java/javax/observer/ValueChangedEvent.java
// public interface ValueChangedEvent<V> {
// 
//     Observable<V> getObservable();
// 
//     default Optional<V> value() {
//         return Optional.ofNullable(getValue());
//     }
// 
//     V getValue();
// }
// 
// Path: api/src/main/java/javax/observer/ValueChangedListener.java
// @FunctionalInterface
// public interface ValueChangedListener<V> extends EventListener {
// 
//     void valueChanged(ValueChangedEvent<? extends V> event);
// 
// }
// 
// Path: api/src/main/java/javax/observer/ValueWillChangeListener.java
// @FunctionalInterface
// public interface ValueWillChangeListener<V> extends EventListener {
// 
//     void valueWillChange(ValueWillChangeEvent<? extends V> event);
// 
// }


// Path: impl/src/main/java/com/guigarage/observer/BasicObservable.java
import javax.observer.Observable;
import javax.observer.Subscription;
import javax.observer.ValueChangedEvent;
import javax.observer.ValueChangedListener;
import javax.observer.ValueWillChangeListener;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

        if(inWillChangeEvent) {
            throw new IllegalStateException("Value can not change while willChangeEvents are handled!");
        }
        if (this.value != value) {
            boolean canChange = fireWillChangeEvent(value);
            if(canChange) {
                try {
                    this.value = value;
                } finally {
                    fireChangedEvent(this.value);
                }
            }
        }
    }

    private boolean fireWillChangeEvent(final V newValue) {
        inWillChangeEvent = true;
        try {
            final ValueWillChangeEventImpl<V> event = new ValueWillChangeEventImpl<>(this, newValue);
            Iterator<ValueWillChangeListener<? super V>> listenerIterator = willChangeListeners.iterator();
            while (listenerIterator.hasNext() && !event.isVetoCalled()) {
                listenerIterator.next().valueWillChange(event);
            }
            return !event.isVetoCalled();
        } finally {
            inWillChangeEvent = false;
        }
    }

    private void fireChangedEvent(final V newValue) {

        final ValueChangedEvent<V> event = new ValueChangedEvent<V>() {
