// Path: src/main/java/org/vaadin/easybinder/data/converters/NullConverter.java
// @SuppressWarnings("serial")
// public class NullConverter<T> implements Converter<T, T> {
// 
// 	protected T nullRepresentation;
// 
// 	public NullConverter(T nullRepresentation) {
// 		this.nullRepresentation = nullRepresentation;
// 	}
// 
// 	@Override
// 	public Result<T> convertToModel(T value, ValueContext context) {
// 		return (nullRepresentation == null && value == null)
// 				|| (nullRepresentation != null && nullRepresentation.equals(value)) ? Result.ok(null)
// 						: Result.ok(value);
// 	}
// 
// 	@Override
// 	public T convertToPresentation(T value, ValueContext context) {
// 		return value == null ? nullRepresentation : value;
// 	}
// }
// 
// Path: src/main/java/org/vaadin/easybinder/data/converters/NullConverterPrimitiveTarget.java
// @SuppressWarnings("serial")
// public class NullConverterPrimitiveTarget<T> implements Converter<T, T> {
// 
// 	@Override
// 	public Result<T> convertToModel(T value, ValueContext context) {
// 		return value == null ? Result.error("Null not allowed") : Result.ok(value);
// 	}
// 
// 	@Override
// 	public T convertToPresentation(T value, ValueContext context) {
// 		return value;
// 	}
// }


import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.validation.constraints.Min;
import org.vaadin.easybinder.data.converters.NullConverter;
import org.vaadin.easybinder.data.converters.NullConverterPrimitiveTarget;
import com.googlecode.gentyref.GenericTypeReflector;
import com.vaadin.data.BeanPropertySet;
import com.vaadin.data.BeanPropertySet.NestedBeanPropertyDefinition;
import com.vaadin.data.Converter;
import com.vaadin.data.HasItems;
import com.vaadin.data.HasValue;
import com.vaadin.data.PropertyDefinition;
import com.vaadin.data.PropertySet;
import com.vaadin.data.RequiredFieldConfigurator;
import com.vaadin.data.ValueProvider;
import com.vaadin.data.provider.DataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.server.Setter;
import com.vaadin.util.ReflectTools;

		EasyBinding<BEAN, PRESENTATION, MODEL> binding = bind(field, (ValueProvider) getter, (Setter) setter,
				propertyName, (Converter) converter);

		boundProperties.put(propertyName, binding);

		Optional<Field> modelField = getDeclaredFieldByName(definition.getPropertyHolderType(), getTopLevelName(definition));
		if (Arrays.asList(modelField.get().getAnnotations()).stream().anyMatch(requiredConfigurator)) {
			field.setRequiredIndicatorVisible(true);
		}

		return binding;
	}

	@SuppressWarnings("unchecked")
	protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(Class<PRESENTATION> presentationType,
			Class<MODEL> modelType, PRESENTATION emptyValue) {
		Objects.requireNonNull(presentationType);
		Objects.requireNonNull(modelType);

		Converter<PRESENTATION, MODEL> converter = converterRegistry.getConverter(presentationType, modelType);
		if (converter != null) {
			log.log(Level.INFO, "Converter for {0}->{1} found by lookup", new Object[] { presentationType, modelType });
		} else if (ReflectTools.convertPrimitiveType(presentationType)
				.equals(ReflectTools.convertPrimitiveType(modelType))) {
			if (modelType.isPrimitive()) {
				converter = (Converter<PRESENTATION, MODEL>) new NullConverterPrimitiveTarget<PRESENTATION>();
				log.log(Level.INFO, "Converter for primitive {0}->{1} found by identity",
						new Object[] { presentationType, modelType });
			} else {
// Path: src/main/java/org/vaadin/easybinder/data/converters/NullConverter.java
// @SuppressWarnings("serial")
// public class NullConverter<T> implements Converter<T, T> {
// 
// 	protected T nullRepresentation;
// 
// 	public NullConverter(T nullRepresentation) {
// 		this.nullRepresentation = nullRepresentation;
// 	}
// 
// 	@Override
// 	public Result<T> convertToModel(T value, ValueContext context) {
// 		return (nullRepresentation == null && value == null)
// 				|| (nullRepresentation != null && nullRepresentation.equals(value)) ? Result.ok(null)
// 						: Result.ok(value);
// 	}
// 
// 	@Override
// 	public T convertToPresentation(T value, ValueContext context) {
// 		return value == null ? nullRepresentation : value;
// 	}
// }
// 
// Path: src/main/java/org/vaadin/easybinder/data/converters/NullConverterPrimitiveTarget.java
// @SuppressWarnings("serial")
// public class NullConverterPrimitiveTarget<T> implements Converter<T, T> {
// 
// 	@Override
// 	public Result<T> convertToModel(T value, ValueContext context) {
// 		return value == null ? Result.error("Null not allowed") : Result.ok(value);
// 	}
// 
// 	@Override
// 	public T convertToPresentation(T value, ValueContext context) {
// 		return value;
// 	}
// }


// Path: src/main/java/org/vaadin/easybinder/data/ReflectionBinder.java
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.validation.constraints.Min;
import org.vaadin.easybinder.data.converters.NullConverter;
import org.vaadin.easybinder.data.converters.NullConverterPrimitiveTarget;
import com.googlecode.gentyref.GenericTypeReflector;
import com.vaadin.data.BeanPropertySet;
import com.vaadin.data.BeanPropertySet.NestedBeanPropertyDefinition;
import com.vaadin.data.Converter;
import com.vaadin.data.HasItems;
import com.vaadin.data.HasValue;
import com.vaadin.data.PropertyDefinition;
import com.vaadin.data.PropertySet;
import com.vaadin.data.RequiredFieldConfigurator;
import com.vaadin.data.ValueProvider;
import com.vaadin.data.provider.DataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.server.Setter;
import com.vaadin.util.ReflectTools;


		EasyBinding<BEAN, PRESENTATION, MODEL> binding = bind(field, (ValueProvider) getter, (Setter) setter,
				propertyName, (Converter) converter);

		boundProperties.put(propertyName, binding);

		Optional<Field> modelField = getDeclaredFieldByName(definition.getPropertyHolderType(), getTopLevelName(definition));
		if (Arrays.asList(modelField.get().getAnnotations()).stream().anyMatch(requiredConfigurator)) {
			field.setRequiredIndicatorVisible(true);
		}

		return binding;
	}

	@SuppressWarnings("unchecked")
	protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(Class<PRESENTATION> presentationType,
			Class<MODEL> modelType, PRESENTATION emptyValue) {
		Objects.requireNonNull(presentationType);
		Objects.requireNonNull(modelType);

		Converter<PRESENTATION, MODEL> converter = converterRegistry.getConverter(presentationType, modelType);
		if (converter != null) {
			log.log(Level.INFO, "Converter for {0}->{1} found by lookup", new Object[] { presentationType, modelType });
		} else if (ReflectTools.convertPrimitiveType(presentationType)
				.equals(ReflectTools.convertPrimitiveType(modelType))) {
			if (modelType.isPrimitive()) {
				converter = (Converter<PRESENTATION, MODEL>) new NullConverterPrimitiveTarget<PRESENTATION>();
				log.log(Level.INFO, "Converter for primitive {0}->{1} found by identity",
						new Object[] { presentationType, modelType });
			} else {
				converter = (Converter<PRESENTATION, MODEL>) new NullConverter<PRESENTATION>(emptyValue);