// Path: src/main/java/de/danielbechler/diff/selector/BeanPropertyElementSelector.java
// public final class BeanPropertyElementSelector extends ElementSelector
// {
// 	private final String propertyName;
// 
// 	public BeanPropertyElementSelector(final String propertyName)
// 	{
// 		Assert.hasText(propertyName, "propertyName");
// 		this.propertyName = propertyName;
// 	}
// 
// 	public String getPropertyName()
// 	{
// 		return propertyName;
// 	}
// 
// 	@Override
// 	public String toHumanReadableString()
// 	{
// 		return propertyName;
// 	}
// 
// 	@Override
// 	public boolean equals(final Object o)
// 	{
// 		if (this == o)
// 		{
// 			return true;
// 		}
// 		if (o == null || getClass() != o.getClass())
// 		{
// 			return false;
// 		}
// 
// 		final BeanPropertyElementSelector that = (BeanPropertyElementSelector) o;
// 
// 		if (!propertyName.equals(that.propertyName))
// 		{
// 			return false;
// 		}
// 
// 		return true;
// 	}
// 
// 	@Override
// 	public int hashCode()
// 	{
// 		return propertyName.hashCode();
// 	}
// }
// 
// Path: src/main/java/de/danielbechler/util/Assert.java
// public class Assert
// {
// 	private Assert()
// 	{
// 	}
// 
// 	public static void equalTypesOrNull(final Object... objects)
// 	{
// 		final Collection<Class<?>> types = Classes.typesOf(objects);
// 		Class<?> previousType = null;
// 		for (final Class<?> type : types)
// 		{
// 			if (previousType != null && !type.equals(previousType))
// 			{
// 				throw new IllegalArgumentException("The given objects should be either null or of the same type ('" + previousType + "') = " + types);
// 			}
// 			previousType = type;
// 		}
// 	}
// 
// 	public static void notNull(final Object object, final String name)
// 	{
// 		if (object == null)
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null");
// 		}
// 	}
// 
// 	public static void notEmpty(final Collection<?> collection, final String name)
// 	{
// 		if (Collections.isEmpty(collection))
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null or empty");
// 		}
// 	}
// 
// 	/**
// 	 * Same as {@link #hasText(String, String)}.
// 	 *
// 	 * @see #hasText(String, String)
// 	 */
// 	public static void notEmpty(final String text, final String name) throws IllegalArgumentException
// 	{
// 		hasText(text, name);
// 	}
// 
// 	/**
// 	 * Ensures that the given <code>value</code> contains characters.
// 	 *
// 	 * @param value The value to check.
// 	 * @param name  The name of the variable (used for the exception message).
// 	 *
// 	 * @throws IllegalArgumentException If the given value is <code>null</code> or doesn't contain any non-whitespace
// 	 *                                  characters.
// 	 */
// 	public static void hasText(final String value, final String name) throws IllegalArgumentException
// 	{
// 		if (Strings.isEmpty(name)) // Yo dawg, I heard you like assertions, so I put an assertion in your assertion
// 		{
// 			throw new IllegalArgumentException("'name' must not be null or empty");
// 		}
// 		if (Strings.isEmpty(value))
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null or empty");
// 		}
// 	}
// }


import static java.util.Arrays.asList;
import de.danielbechler.diff.access.PropertyAwareAccessor;
import de.danielbechler.diff.selector.BeanPropertyElementSelector;
import de.danielbechler.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
			{
				return annotationClass.cast(annotation);
			}
		}
		return null;
	}

	/**
	 * @return The annotations of the getter used to access this property.
	 */
	public Set<Annotation> getReadMethodAnnotations()
	{
		return new LinkedHashSet<Annotation>(asList(readMethod.getAnnotations()));
	}

	public <T extends Annotation> T getReadMethodAnnotation(final Class<T> annotationClass)
	{
		final Set<? extends Annotation> annotations = getReadMethodAnnotations();
		assert (annotations != null) : "Something is wrong here. " +
				"The contract of getReadAnnotations() guarantees a non-null return value.";
		for (final Annotation annotation : annotations)
		{
			if (annotationClass.isAssignableFrom(annotation.annotationType()))
			{
				return annotationClass.cast(annotation);
			}
		}
		return null;
	}

// Path: src/main/java/de/danielbechler/diff/selector/BeanPropertyElementSelector.java
// public final class BeanPropertyElementSelector extends ElementSelector
// {
// 	private final String propertyName;
// 
// 	public BeanPropertyElementSelector(final String propertyName)
// 	{
// 		Assert.hasText(propertyName, "propertyName");
// 		this.propertyName = propertyName;
// 	}
// 
// 	public String getPropertyName()
// 	{
// 		return propertyName;
// 	}
// 
// 	@Override
// 	public String toHumanReadableString()
// 	{
// 		return propertyName;
// 	}
// 
// 	@Override
// 	public boolean equals(final Object o)
// 	{
// 		if (this == o)
// 		{
// 			return true;
// 		}
// 		if (o == null || getClass() != o.getClass())
// 		{
// 			return false;
// 		}
// 
// 		final BeanPropertyElementSelector that = (BeanPropertyElementSelector) o;
// 
// 		if (!propertyName.equals(that.propertyName))
// 		{
// 			return false;
// 		}
// 
// 		return true;
// 	}
// 
// 	@Override
// 	public int hashCode()
// 	{
// 		return propertyName.hashCode();
// 	}
// }
// 
// Path: src/main/java/de/danielbechler/util/Assert.java
// public class Assert
// {
// 	private Assert()
// 	{
// 	}
// 
// 	public static void equalTypesOrNull(final Object... objects)
// 	{
// 		final Collection<Class<?>> types = Classes.typesOf(objects);
// 		Class<?> previousType = null;
// 		for (final Class<?> type : types)
// 		{
// 			if (previousType != null && !type.equals(previousType))
// 			{
// 				throw new IllegalArgumentException("The given objects should be either null or of the same type ('" + previousType + "') = " + types);
// 			}
// 			previousType = type;
// 		}
// 	}
// 
// 	public static void notNull(final Object object, final String name)
// 	{
// 		if (object == null)
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null");
// 		}
// 	}
// 
// 	public static void notEmpty(final Collection<?> collection, final String name)
// 	{
// 		if (Collections.isEmpty(collection))
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null or empty");
// 		}
// 	}
// 
// 	/**
// 	 * Same as {@link #hasText(String, String)}.
// 	 *
// 	 * @see #hasText(String, String)
// 	 */
// 	public static void notEmpty(final String text, final String name) throws IllegalArgumentException
// 	{
// 		hasText(text, name);
// 	}
// 
// 	/**
// 	 * Ensures that the given <code>value</code> contains characters.
// 	 *
// 	 * @param value The value to check.
// 	 * @param name  The name of the variable (used for the exception message).
// 	 *
// 	 * @throws IllegalArgumentException If the given value is <code>null</code> or doesn't contain any non-whitespace
// 	 *                                  characters.
// 	 */
// 	public static void hasText(final String value, final String name) throws IllegalArgumentException
// 	{
// 		if (Strings.isEmpty(name)) // Yo dawg, I heard you like assertions, so I put an assertion in your assertion
// 		{
// 			throw new IllegalArgumentException("'name' must not be null or empty");
// 		}
// 		if (Strings.isEmpty(value))
// 		{
// 			throw new IllegalArgumentException("'" + name + "' must not be null or empty");
// 		}
// 	}
// }


// Path: src/main/java/de/danielbechler/diff/introspection/PropertyAccessor.java
import static java.util.Arrays.asList;
import de.danielbechler.diff.access.PropertyAwareAccessor;
import de.danielbechler.diff.selector.BeanPropertyElementSelector;
import de.danielbechler.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

			{
				return annotationClass.cast(annotation);
			}
		}
		return null;
	}

	/**
	 * @return The annotations of the getter used to access this property.
	 */
	public Set<Annotation> getReadMethodAnnotations()
	{
		return new LinkedHashSet<Annotation>(asList(readMethod.getAnnotations()));
	}

	public <T extends Annotation> T getReadMethodAnnotation(final Class<T> annotationClass)
	{
		final Set<? extends Annotation> annotations = getReadMethodAnnotations();
		assert (annotations != null) : "Something is wrong here. " +
				"The contract of getReadAnnotations() guarantees a non-null return value.";
		for (final Annotation annotation : annotations)
		{
			if (annotationClass.isAssignableFrom(annotation.annotationType()))
			{
				return annotationClass.cast(annotation);
			}
		}
		return null;
	}

	public BeanPropertyElementSelector getElementSelector()