// Path: core/src/main/java/net/sf/beanlib/CollectionPropertyName.java
// public class CollectionPropertyName<T> {
// 
//     public static final CollectionPropertyName<?>[] EMPTY_ARRAY = {};
// 
//     private final Class<T> declaringClass;
// 
//     private final String collectionProperty;
// 
//     private final int hashCode;
// 
//     private final BeanGetter beanGetter = new BeanGetter();
// 
//     /** Convenient factory method. */
//     public static <T> CollectionPropertyName<T>[] createCollectionPropertyNames(Class<T> declaringClass, String[] collectionProperties) {
//         Set<CollectionPropertyName<T>> set = new HashSet<>();
// 
//         for (String s : collectionProperties) {
//             set.add(new CollectionPropertyName<>(declaringClass, s));
//         }
// 
//         @SuppressWarnings("unchecked")
//         CollectionPropertyName<T>[] ret = (CollectionPropertyName<T>[]) set.toArray(EMPTY_ARRAY);
//         return ret;
//     }
// 
//     /**
//      * @param declaringClass declaring class of the Collection or Map property.
//      * @param collectionProperty Collection or Map property name.
//      */
//     public CollectionPropertyName(Class<T> declaringClass, String collectionProperty) {
//         this.declaringClass = declaringClass;
//         this.collectionProperty = collectionProperty;
//         this.hashCode = beanGetter.getBeanHashCode(this);
//     }
// 
//     public Class<T> getDeclaringClass() {
//         return declaringClass;
//     }
// 
//     public String getCollectionProperty() {
//         return collectionProperty;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (!(obj instanceof CollectionPropertyName)) {
//             return false;
//         }
//         CollectionPropertyName<?> that = (CollectionPropertyName<?>) obj;
//         return new EqualsBuilder().append(this.declaringClass, that.declaringClass).append(this.collectionProperty, that.collectionProperty)
//                 .isEquals();
//     }
// 
//     @Override
//     public int hashCode() {
//         return this.hashCode;
//     }
// }
// 
// Path: core/src/main/java/net/sf/beanlib/spi/PropertyFilter.java
// public interface PropertyFilter {
// 
//     /**
//      * Returns true if the given JavaBean property should be propagated; false otherwise.
//      *
//      * @param propertyName JavaBean property name.
//      * @param readerMethod reader method of the JavaBean property name.
//      * @return true if the given JavaBean property should be propagated.
//      */
//     boolean propagate(String propertyName, Method readerMethod);
// }


import static net.sf.beanlib.utils.ClassUtils.fqcn;
import static net.sf.beanlib.utils.ClassUtils.immutable;
import static net.sf.beanlib.utils.ClassUtils.isJavaPackage;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import net.sf.beanlib.CollectionPropertyName;
import net.sf.beanlib.spi.PropertyFilter;
    }

    public boolean propagateImpl(String propertyName, Method readerMethod) {
        Class<?> returnType = UnEnhancer.unenhanceClass(readerMethod.getReturnType());

        if (immutable(returnType)) {
            return true;
        }

        if (returnType.isArray()) {
            if (immutable(returnType.getComponentType())) {
                return true;
            }
        }

        if (entityBeanClassSet == null) {
            // All entity bean to be populated.
            if (collectionPropertyNameSet == null) {
                // all fields to be populated
                return true;
            }
            return checkCollectionProperty(propertyName, readerMethod);
        }
        // Only a selected set of entity bean to be populated.
        if (isJavaPackage(returnType)) {
            // Not an entity bean.
            if (collectionPropertyNameSet == null) {
                // All Collection/Map properties to be populated.
                return true;
            }
// Path: core/src/main/java/net/sf/beanlib/CollectionPropertyName.java
// public class CollectionPropertyName<T> {
// 
//     public static final CollectionPropertyName<?>[] EMPTY_ARRAY = {};
// 
//     private final Class<T> declaringClass;
// 
//     private final String collectionProperty;
// 
//     private final int hashCode;
// 
//     private final BeanGetter beanGetter = new BeanGetter();
// 
//     /** Convenient factory method. */
//     public static <T> CollectionPropertyName<T>[] createCollectionPropertyNames(Class<T> declaringClass, String[] collectionProperties) {
//         Set<CollectionPropertyName<T>> set = new HashSet<>();
// 
//         for (String s : collectionProperties) {
//             set.add(new CollectionPropertyName<>(declaringClass, s));
//         }
// 
//         @SuppressWarnings("unchecked")
//         CollectionPropertyName<T>[] ret = (CollectionPropertyName<T>[]) set.toArray(EMPTY_ARRAY);
//         return ret;
//     }
// 
//     /**
//      * @param declaringClass declaring class of the Collection or Map property.
//      * @param collectionProperty Collection or Map property name.
//      */
//     public CollectionPropertyName(Class<T> declaringClass, String collectionProperty) {
//         this.declaringClass = declaringClass;
//         this.collectionProperty = collectionProperty;
//         this.hashCode = beanGetter.getBeanHashCode(this);
//     }
// 
//     public Class<T> getDeclaringClass() {
//         return declaringClass;
//     }
// 
//     public String getCollectionProperty() {
//         return collectionProperty;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (!(obj instanceof CollectionPropertyName)) {
//             return false;
//         }
//         CollectionPropertyName<?> that = (CollectionPropertyName<?>) obj;
//         return new EqualsBuilder().append(this.declaringClass, that.declaringClass).append(this.collectionProperty, that.collectionProperty)
//                 .isEquals();
//     }
// 
//     @Override
//     public int hashCode() {
//         return this.hashCode;
//     }
// }
// 
// Path: core/src/main/java/net/sf/beanlib/spi/PropertyFilter.java
// public interface PropertyFilter {
// 
//     /**
//      * Returns true if the given JavaBean property should be propagated; false otherwise.
//      *
//      * @param propertyName JavaBean property name.
//      * @param readerMethod reader method of the JavaBean property name.
//      * @return true if the given JavaBean property should be propagated.
//      */
//     boolean propagate(String propertyName, Method readerMethod);
// }


// Path: hibernate/src/main/java/net/sf/beanlib/hibernate/HibernatePropertyFilter.java
import static net.sf.beanlib.utils.ClassUtils.fqcn;
import static net.sf.beanlib.utils.ClassUtils.immutable;
import static net.sf.beanlib.utils.ClassUtils.isJavaPackage;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import net.sf.beanlib.CollectionPropertyName;
import net.sf.beanlib.spi.PropertyFilter;

    }

    public boolean propagateImpl(String propertyName, Method readerMethod) {
        Class<?> returnType = UnEnhancer.unenhanceClass(readerMethod.getReturnType());

        if (immutable(returnType)) {
            return true;
        }

        if (returnType.isArray()) {
            if (immutable(returnType.getComponentType())) {
                return true;
            }
        }

        if (entityBeanClassSet == null) {
            // All entity bean to be populated.
            if (collectionPropertyNameSet == null) {
                // all fields to be populated
                return true;
            }
            return checkCollectionProperty(propertyName, readerMethod);
        }
        // Only a selected set of entity bean to be populated.
        if (isJavaPackage(returnType)) {
            // Not an entity bean.
            if (collectionPropertyNameSet == null) {
                // All Collection/Map properties to be populated.
                return true;
            }
            return checkCollectionProperty(propertyName, readerMethod);