// Path: src/main/java/org/hildan/fxgson/adapters/properties/NullPropertyException.java
// public class NullPropertyException extends RuntimeException {
// 
//     /**
//      * Constructs a new NullPropertyException.
//      */
//     public NullPropertyException() {
//         super("Null properties are forbidden");
//     }
// }


import java.io.IOException;
import javafx.beans.property.Property;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.hildan.fxgson.adapters.properties.NullPropertyException;
import org.jetbrains.annotations.NotNull;
package org.hildan.fxgson.adapters.properties.primitives;




/**
 * An abstract base for {@link TypeAdapter}s of primitive values. By default, it throws {@link NullPrimitiveException}
 * when used to deserialize a null JSON value (which is illegal for a primitive). It can be configured to instantiate a
 * default value instead in this case.
 *
 * @param <I>
 *         the primitive type inside the property
 * @param <P>
 *         the type that this adapter can serialize/deserialize
 */
public abstract class PrimitivePropertyTypeAdapter<I, P extends Property<?>> extends TypeAdapter<P> {

    private final TypeAdapter<I> delegate;

    private final boolean throwOnNullProperty;

    private final boolean crashOnNullValue;

    /**
     * Creates a new PrimitivePropertyTypeAdapter.
     *
     * @param innerValueTypeAdapter
     *         a delegate adapter to use for the inner value of the property
     * @param throwOnNullProperty
     *         if true, this adapter will throw {@link NullPropertyException} when given a null {@link Property} to
     *         serialize
     * @param crashOnNullValue
     *         if true, this adapter will throw {@link NullPrimitiveException} when reading a null value. If false, this
     *         adapter will call {@link #createDefaultProperty()} instead.
     */
    public PrimitivePropertyTypeAdapter(TypeAdapter<I> innerValueTypeAdapter, boolean throwOnNullProperty,
                                        boolean crashOnNullValue) {
        this.delegate = innerValueTypeAdapter;
        this.throwOnNullProperty = throwOnNullProperty;
        this.crashOnNullValue = crashOnNullValue;
    }

    @Override
    public void write(JsonWriter out, P property) throws IOException {
        if (property == null) {
            if (throwOnNullProperty) {
// Path: src/main/java/org/hildan/fxgson/adapters/properties/NullPropertyException.java
// public class NullPropertyException extends RuntimeException {
// 
//     /**
//      * Constructs a new NullPropertyException.
//      */
//     public NullPropertyException() {
//         super("Null properties are forbidden");
//     }
// }


// Path: src/main/java/org/hildan/fxgson/adapters/properties/primitives/PrimitivePropertyTypeAdapter.java
import java.io.IOException;
import javafx.beans.property.Property;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.hildan.fxgson.adapters.properties.NullPropertyException;
import org.jetbrains.annotations.NotNull;

package org.hildan.fxgson.adapters.properties.primitives;




/**
 * An abstract base for {@link TypeAdapter}s of primitive values. By default, it throws {@link NullPrimitiveException}
 * when used to deserialize a null JSON value (which is illegal for a primitive). It can be configured to instantiate a
 * default value instead in this case.
 *
 * @param <I>
 *         the primitive type inside the property
 * @param <P>
 *         the type that this adapter can serialize/deserialize
 */
public abstract class PrimitivePropertyTypeAdapter<I, P extends Property<?>> extends TypeAdapter<P> {

    private final TypeAdapter<I> delegate;

    private final boolean throwOnNullProperty;

    private final boolean crashOnNullValue;

    /**
     * Creates a new PrimitivePropertyTypeAdapter.
     *
     * @param innerValueTypeAdapter
     *         a delegate adapter to use for the inner value of the property
     * @param throwOnNullProperty
     *         if true, this adapter will throw {@link NullPropertyException} when given a null {@link Property} to
     *         serialize
     * @param crashOnNullValue
     *         if true, this adapter will throw {@link NullPrimitiveException} when reading a null value. If false, this
     *         adapter will call {@link #createDefaultProperty()} instead.
     */
    public PrimitivePropertyTypeAdapter(TypeAdapter<I> innerValueTypeAdapter, boolean throwOnNullProperty,
                                        boolean crashOnNullValue) {
        this.delegate = innerValueTypeAdapter;
        this.throwOnNullProperty = throwOnNullProperty;
        this.crashOnNullValue = crashOnNullValue;
    }

    @Override
    public void write(JsonWriter out, P property) throws IOException {
        if (property == null) {
            if (throwOnNullProperty) {
                throw new NullPropertyException();