/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.feature;

import java.util.Objects;
import java.util.Iterator;
import java.util.Collection;
import java.util.Collections;
import java.io.Serializable;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.metadata.quality.DataQuality;
import org.opengis.metadata.maintenance.ScopeCode;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.CorruptedObjectException;
import org.apache.sis.internal.util.CheckedArrayList;
import org.apache.sis.internal.feature.Resources;

// Branch-dependent imports
import org.opengis.feature.Property;
import org.opengis.feature.PropertyType;
import org.opengis.feature.PropertyNotFoundException;
import org.opengis.feature.InvalidPropertyValueException;
import org.opengis.feature.Attribute;
import org.opengis.feature.AttributeType;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
import org.opengis.feature.FeatureAssociation;
import org.opengis.feature.FeatureAssociationRole;
import org.opengis.feature.IdentifiedType;
import org.opengis.feature.Operation;


/**
 * An instance of a {@linkplain DefaultFeatureType feature type} containing values for a real-world phenomena.
 * Each feature instance can provide values for the following properties:
 *
 * <ul>
 *   <li>{@linkplain AbstractAttribute   Attributes}</li>
 *   <li>{@linkplain AbstractAssociation Associations to other features}</li>
 *   <li>{@linkplain AbstractOperation   Operations}</li>
 * </ul>
 *
 * {@code AbstractFeature} can be instantiated by calls to {@link DefaultFeatureType#newInstance()}.
 *
 * <h2>Simple features</h2>
 * A feature is said “simple” if it complies to the following conditions:
 * <ul>
 *   <li>the feature allows only attributes and operations (no associations),</li>
 *   <li>the cardinality of all attributes is constrained to [1 … 1].</li>
 * </ul>
 *
 * <h2>Limitations</h2>
 * <ul>
 *   <li><b>Multi-threading:</b> {@code AbstractFeature} instances are <strong>not</strong> thread-safe.
 *       Synchronization, if needed, shall be done externally by the caller.</li>
 *   <li><b>Serialization:</b> serialized objects of this class are not guaranteed to be compatible with future
 *       versions. Serialization should be used only for short term storage or RMI between applications running
 *       the same SIS version.</li>
 * </ul>
 *
 * @author  Travis L. Pinney
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 *
 * @see DefaultFeatureType#newInstance()
 *
 * @since 0.5
 * @module
 */
public abstract class AbstractFeature implements Feature, Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -5637918246427380190L;

    /**
     * Information about the feature (name, characteristics, <i>etc.</i>).
     */
    final FeatureType type;

    /**
     * Creates a new feature of the given type.
     *
     * @param type  information about the feature (name, characteristics, <i>etc.</i>).
     *
     * @see DefaultFeatureType#newInstance()
     */
    protected AbstractFeature(final FeatureType type) {
        ArgumentChecks.ensureNonNull("type", type);
        this.type = type;
    }

    /**
     * Return the {@linkplain #type} name as a non-null string. This is used mostly for formatting error message.
     * This method shall not be invoked when a null name should be considered as an error.
     */
    final String getName() {
        return String.valueOf(type.getName());
    }

    /**
     * Returns information about the feature (name, characteristics, <i>etc.</i>).
     *
     * @return information about the feature.
     */
    @Override
    public FeatureType getType() {
        return type;
    }

    /**
     * Returns the property (attribute, feature association or operation result) of the given name.
     * If the property type is a parameterless {@linkplain AbstractOperation operation}, then this
     * method may return the result of {@linkplain AbstractOperation#apply executing} the operation
     * on this feature, at implementation choice.
     *
     * <p>This method returns the property <em>instance</em>. If only the property <em>value</em> is
     * desired, then {@link #getPropertyValue(String)} is preferred since it gives to SIS a chance to
     * avoid the creation of {@link AbstractAttribute} or {@link AbstractAssociation} instances.</p>
     *
     * <div class="note"><b>Note for subclass implementers:</b>
     * the default implementation returns an instance that redirect all read and write operations to
     * {@link #getPropertyValue(String)} and {@link #setPropertyValue(String, Object)} respectively.
     * That default implementation is intended to make easier for developers to create their own
     * customized <code>AbstractFacture</code> implementations, but has drawbacks:
     * a new {@code Property} instance is created every time that this {@code getProperty(String)} method is invoked,
     * and the returned {@code Property} implementation is not very efficient
     * since it has to perform multiple lookups and type checks.
     * Implementers are encouraged to override this method if they can provide a more efficient implementation.
     * Note that this is already the case when using implementations created by {@link DefaultFeatureType#newInstance()}.</div>
     *
     * @param  name  the property name.
     * @return the property of the given name (never {@code null}).
     * @throws PropertyNotFoundException if the given argument is not a property name of this feature.
     *
     * @see #getPropertyValue(String)
     * @see DefaultFeatureType#getProperty(String)
     */
    @Override
    public Property getProperty(final String name) throws PropertyNotFoundException {
        return PropertyView.create(this, type.getProperty(name));
    }

    /**
     * Sets the property (attribute or feature association).
     * The given property shall comply to the following conditions:
     *
     * <ul>
     *   <li>It must be non-null.</li>
     *   <li>Its {@linkplain Property#getName() name} shall be the name of the property to set in this feature.</li>
     *   <li>Its type shall be the same instance than the {@linkplain DefaultFeatureType#getProperty(String)
     *       property type} defined by the feature type for the above name.
     *       In other words, the following condition shall hold:</li>
     * </ul>
     *
     * {@preformat java
     *     assert property.getType() == getType().getProperty(property.getName());
     * }
     *
     * This method is useful for storing non-default {@code Attribute} or {@code FeatureAssociation} implementations
     * in this feature. When default implementations are sufficient, the {@link #setPropertyValue(String, Object)}
     * method is preferred.
     *
     * <div class="note"><b>Note for subclass implementers:</b>
     * the default implementation verifies that the given property has the expected type and a null or empty
     * {@linkplain AbstractAttribute#characteristics() map of characteristics}, then delegates to
     * {@link #setPropertyValue(String, Object)}.
     * That default implementation is intended to make easier for developers to create their own
     * customized <code>AbstractFacture</code> implementations, but has drawbacks:
     * the given {@code Property} instance is not stored (only its {@linkplain AbstractAttribute#getValue() value}
     * is stored), and it can not have custom {@linkplain AbstractAttribute#characteristics() characteristics}.
     * Implementers are encouraged to override this method if they can provide a better implementation.
     * Note that this is already the case when using implementations created by {@link DefaultFeatureType#newInstance()}.</div>
     *
     * @param  property  the property to set.
     * @throws PropertyNotFoundException if the name of the given property is not a property name of this feature.
     * @throws InvalidPropertyValueException if the value of the given property is not valid.
     * @throws IllegalArgumentException if the property can not be set for another reason.
     *
     * @see #setPropertyValue(String, Object)
     */
    @Override
    public void setProperty(final Property property) throws IllegalArgumentException {
        ArgumentChecks.ensureNonNull("property", property);
        final String name = property.getName().toString();
        verifyPropertyType(name, property);
        if (property instanceof Attribute<?> && !Containers.isNullOrEmpty(((Attribute<?>) property).characteristics())) {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.CanNotAssignCharacteristics_1, name));
        }
        setPropertyValue(name, property.getValue());
    }

    /**
     * Wraps the given value in a {@link Property} object. This method is invoked only by
     * {@link #getProperty(String)} when it needs to converts its {@code properties} data.
     *
     * @param  name   the name of the property to create.
     * @param  value  the value to wrap.
     * @return a {@code Property} wrapping the given value.
     */
    final Property createProperty(final String name, final Object value) {
        final PropertyType pt = type.getProperty(name);
        if (pt instanceof AttributeType<?>) {
            return AbstractAttribute.create((AttributeType<?>) pt, value);
        } else if (pt instanceof FeatureAssociationRole) {
            return AbstractAssociation.create((FeatureAssociationRole) pt, value);
        } else {
            // Should never happen, unless the user gave us some mutable FeatureType.
            throw new CorruptedObjectException(Errors.format(Errors.Keys.UnknownType_1, pt));
        }
    }

    /**
     * Creates a new property initialized to its default value.
     *
     * @param  name  the name of the property to create.
     * @return a {@code Property} of the given name.
     * @throws PropertyNotFoundException if the given argument is not the name of an attribute or
     *         feature association of this feature.
     */
    final Property createProperty(final String name) throws PropertyNotFoundException {
        final PropertyType pt = type.getProperty(name);
        if (pt instanceof AttributeType<?>) {
            return ((AttributeType<?>) pt).newInstance();
        } else if (pt instanceof FeatureAssociationRole) {
            return ((FeatureAssociationRole) pt).newInstance();
        } else {
            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
        }
    }

    /**
     * Executes the parameterless operation of the given name and returns its result.
     *
     * @see #getOperationValue(String)
     */
    final Property getOperationResult(final String name) {
        /*
         * The (Operation) cast below should never fail (unless the DefaultFeatureType in not really immutable,
         * which would be a contract violation) because all callers shall ensure that this method is invoked in
         * a context where the following assertion holds.
         */
        assert DefaultFeatureType.OPERATION_INDEX.equals(((DefaultFeatureType) type).indices().get(name)) : name;
        return ((Operation) type.getProperty(name)).apply(this, null);
    }

    /**
     * Returns the default value to be returned by {@link #getPropertyValue(String)}
     * for the property of the given name.
     *
     * @param  name  the name of the property for which to get the default value.
     * @return the default value for the {@code Property} of the given name.
     * @throws PropertyNotFoundException if the given argument is not an attribute or association name of this feature.
     */
    final Object getDefaultValue(final String name) throws PropertyNotFoundException {
        final PropertyType pt = type.getProperty(name);
        if (pt instanceof AttributeType<?>) {
            return getDefaultValue((AttributeType<?>) pt);
        } else if (pt instanceof FeatureAssociationRole) {
            final int maximumOccurs = ((FeatureAssociationRole) pt).getMaximumOccurs();
            return maximumOccurs > 1 ? Collections.EMPTY_LIST : null;       // No default value for associations.
        } else {
            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
        }
    }

    /**
     * Returns the default value to be returned by {@link #getPropertyValue(String)} for the given attribute type.
     */
    private static <V> Object getDefaultValue(final AttributeType<V> attribute) {
        final V defaultValue = attribute.getDefaultValue();
        if (Field.isSingleton(attribute.getMaximumOccurs())) {
            return defaultValue;
        } else {
            // Following is for compliance with getPropertyValue(String) method contract - see its javadoc.
            return (defaultValue != null) ? Collections.singletonList(defaultValue) : Collections.emptyList();
        }
    }

    /**
     * Returns the value for the property of the given name.
     * This convenience method is equivalent to invoking {@link #getProperty(String)} for the given name,
     * then to perform one of the following actions depending on the property type and the multiplicity:
     *
     * <table class="sis">
     *   <caption>Class of returned value</caption>
     *   <tr><th>Property type</th>                  <th>max. occurs</th> <th>Method invoked</th>                         <th>Return type</th></tr>
     *   <tr><td>{@link AttributeType}</td>          <td>0 or 1</td>      <td>{@link Attribute#getValue()}</td>           <td>{@link Object}</td></tr>
     *   <tr><td>{@code AttributeType}</td>          <td>2 or more</td>   <td>{@link Attribute#getValues()}</td>          <td>{@code Collection<?>}</td></tr>
     *   <tr><td>{@link FeatureAssociationRole}</td> <td>0 or 1</td>      <td>{@link FeatureAssociation#getValue()}</td>  <td>{@link Feature}</td></tr>
     *   <tr><td>{@code FeatureAssociationRole}</td> <td>2 or more</td>   <td>{@link FeatureAssociation#getValues()}</td> <td>{@code Collection<Feature>}</td></tr>
     * </table>
     *
     * <div class="note"><b>Note:</b> “max. occurs” is the {@linkplain DefaultAttributeType#getMaximumOccurs() maximum
     * number of occurrences} and does not depend on the actual number of values. If an attribute allows more than one
     * value, then this method will always return a collection for that attribute even if the collection is empty.</div>
     *
     * <h4>Multi-valued properties and collections</h4>
     * In the case of multi-valued properties (“max. occurs” &gt; 1), the collection returned by this method may
     * or may not be modifiable, at implementation choice. Generally the caller can not add new elements into the
     * returned collection anyway since {@code Collection<?>} does not allow such operations, and more specific
     * casts (e.g. {@code Collection<String>} can not be checked at runtime (at least as of Java 8).
     * If a type-safe modifiable collection is desired, the following approach can be used instead:
     *
     * {@preformat java
     *   Attribute<String> attribute = Features.cast((Attribute<?>) feature.getProperty(name), String.class);
     *   Collection<String> values = attribute.getValues();    // This collection is guaranteed to be "live".
     * }
     *
     * @param  name  the property name.
     * @return the value for the given property, or {@code null} if none.
     * @throws PropertyNotFoundException if the given argument is not an attribute or association name of this feature.
     *
     * @see AbstractAttribute#getValue()
     */
    @Override
    public abstract Object getPropertyValue(final String name) throws PropertyNotFoundException;

    /**
     * Sets the value for the property of the given name.
     *
     * <h4>Validation</h4>
     * The amount of validation performed by this method is implementation dependent.
     * Usually, only the most basic constraints are verified. This is so for performance reasons
     * and also because some rules may be temporarily broken while constructing a feature.
     * A more exhaustive verification can be performed by invoking the {@link #quality()} method.
     *
     * @param  name   the attribute name.
     * @param  value  the new value for the given attribute (may be {@code null}).
     * @throws PropertyNotFoundException if the given name is not an attribute or association name of this feature.
     * @throws ClassCastException if the value is not assignable to the expected value class.
     * @throws InvalidPropertyValueException if the given value is not valid for a reason other than its type.
     *
     * @see AbstractAttribute#setValue(Object)
     */
    @Override
    public abstract void setPropertyValue(final String name, final Object value) throws IllegalArgumentException;

    /**
     * Executes the parameterless operation of the given name and returns the value of its result.
     * This is a convenience method for sub-classes where some properties may be operations that
     * {@linkplain AbstractOperation#getDependencies() depend} on other properties of this {@code Feature} instance
     * (for example a {@linkplain FeatureOperations#link link} to another property value).
     * Invoking this method is equivalent to performing the following steps:
     *
     * {@preformat java
     *     Operation operation = (Operation) type.getProperty(name);
     *     Property result = operation.apply(this, null);
     *     if (result instanceof Attribute<?>) {
     *         return ...;                                      // the attribute value.
     *     } else if (result instanceof FeatureAssociation) {
     *         return ...;                                      // the associated feature.
     *     } else {
     *         return null;
     *     }
     * }
     *
     * @param  name  the name of the operation to execute. The caller is responsible to ensure that the
     *               property type for that name is an instance of {@link Operation}.
     * @return the result value of the given operation, or {@code null} if none.
     *
     * @since 0.8
     */
    protected Object getOperationValue(final String name) {
        final Operation operation = (Operation) type.getProperty(name);
        if (operation instanceof LinkOperation) {
            return getPropertyValue(((LinkOperation) operation).referentName);
        }
        final Property result = operation.apply(this, null);
        if (result instanceof Attribute<?>) {
            return getAttributeValue((Attribute<?>) result);
        } else if (result instanceof FeatureAssociation) {
            return getAssociationValue((FeatureAssociation) result);
        } else {
            return null;
        }
    }

    /**
     * Executes the parameterless operation of the given name and sets the value of its result.
     * This method is the complement of {@link #getOperationValue(String)} for subclasses where
     * some properties may be operations. Not all operations accept assignments,
     * but the {@linkplain FeatureOperations#link link} operation for instance does.
     *
     * @param  name   the name of the operation to execute. The caller is responsible to ensure that the
     *                property type for that name is an instance of {@link Operation}.
     * @param  value  the value to assign to the result of the named operation.
     * @throws IllegalStateException if the operation of the given name does not accept assignment.
     *
     * @since 0.8
     */
    protected void setOperationValue(final String name, final Object value) {
        final Operation operation = (Operation) type.getProperty(name);
        if (operation instanceof LinkOperation) {
            setPropertyValue(((LinkOperation) operation).referentName, value);
        } else {
            final Property result = operation.apply(this, null);
            if (result != null) {
                setPropertyValue(result, value);
            } else {
                throw new IllegalStateException(Resources.format(Resources.Keys.CanNotSetPropertyValue_1, name));
            }
        }
    }

    /**
     * Returns the value of the given attribute, as a singleton or as a collection depending
     * on the maximum number of occurrences.
     */
    static Object getAttributeValue(final Attribute<?> property) {
        return Field.isSingleton(property.getType().getMaximumOccurs()) ? property.getValue() : property.getValues();
    }

    /**
     * Returns the value of the given association, as a singleton or as a collection depending
     * on the maximum number of occurrences.
     */
    static Object getAssociationValue(final FeatureAssociation property) {
        return Field.isSingleton(property.getRole().getMaximumOccurs()) ? property.getValue() : property.getValues();
    }

    /**
     * Sets the value of the given property, with some minimal checks.
     */
    static void setPropertyValue(final Property property, final Object value) {
        if (property instanceof Attribute<?>) {
            setAttributeValue((Attribute<?>) property, value);
        } else if (property instanceof FeatureAssociation) {
            setAssociationValue((FeatureAssociation) property, value);
        } else {
            throw new IllegalArgumentException(unsupportedPropertyType(property.getName()));
        }
    }

    /**
     * Sets the attribute value after verification of its type. This method is invoked only for checking
     * that we are not violating the Java parameterized type contract. For a more exhaustive validation,
     * use {@link Validator} instead.
     */
    @SuppressWarnings("unchecked")
    private static <V> void setAttributeValue(final Attribute<V> attribute, final Object value) {
        if (value != null) {
            final AttributeType<V> pt = attribute.getType();
            final Class<?> base = pt.getValueClass();
            if (!base.isInstance(value)) {
                Object element = value;
                if (value instanceof Collection<?>) {
                    /*
                     * If the given value is a collection, verify the class of all values
                     * before to delegate to Attribute.setValues(Collection<? extends V>).
                     */
                    final Iterator<?> it = ((Collection<?>) value).iterator();
                    do if (!it.hasNext()) {
                        ((Attribute) attribute).setValues((Collection) value);
                        return;
                    } while ((element = it.next()) == null || base.isInstance(element));
                    // Found an illegal value. Exeption is thrown below.
                }
                throw new ClassCastException(illegalValueClass(pt, base, element));         // 'element' can not be null here.
            }
        }
        ((Attribute) attribute).setValue(value);
    }

    /**
     * Sets the association value after verification of its type.
     * For a more exhaustive validation, use {@link Validator} instead.
     */
    @SuppressWarnings("unchecked")
    private static void setAssociationValue(final FeatureAssociation association, final Object value) {
        if (value != null) {
            final FeatureAssociationRole role = association.getRole();
            final FeatureType base = role.getValueType();
            if (value instanceof Feature) {
                final FeatureType actual = ((Feature) value).getType();
                if (base != actual && !DefaultFeatureType.maybeAssignableFrom(base, actual)) {
                    throw new InvalidPropertyValueException(illegalFeatureType(role, base, actual));
                }
            } else if (value instanceof Collection<?>) {
                verifyAssociationValues(role, (Collection<?>) value);
                association.setValues((Collection<? extends Feature>) value);
                return;                                 // Skip the setter at the end of this method.
            } else {
                throw new ClassCastException(illegalValueClass(role, Feature.class, value));
            }
        }
        association.setValue((Feature) value);
    }

    /**
     * Returns {@code true} if the caller can skip the call to {@link #verifyPropertyValue(String, Object)}.
     * This is a slight optimization for the case when we replaced an attribute value by a new value of
     * the same class. Since the type check has already been done by the previous assignation, we do not
     * need to perform it again.
     *
     * @param  previous  the previous value, or {@code null}.
     * @param  value     the new value, or {@code null}.
     * @return {@code true} if the caller can skip the verification performed by {@code verifyPropertyValue}.
     */
    static boolean canSkipVerification(final Object previous, final Object value) {
        if (previous != null) {
            if (value == null) {
                return true;
            }
            if (previous.getClass() == value.getClass() && !(value instanceof Feature)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Verifies if the given property can be assigned to this feature.
     *
     * @param  name      shall be {@code property.getName().toString()}.
     * @param  property  the property to verify.
     */
    final void verifyPropertyType(final String name, final Property property) {
        final PropertyType pt, base = type.getProperty(name);
        if (property instanceof Attribute<?>) {
            pt = ((Attribute<?>) property).getType();
        } else if (property instanceof FeatureAssociation) {
            pt = ((FeatureAssociation) property).getRole();
        } else {
            throw new InvalidPropertyValueException(Resources.format(Resources.Keys.IllegalPropertyType_2, base.getName(), property.getClass()));
        }
        if (pt != base) {
            if (base == null) {
                throw new PropertyNotFoundException(Resources.format(Resources.Keys.PropertyNotFound_2, getName(), name));
            } else {
                throw new InvalidPropertyValueException(Resources.format(Resources.Keys.MismatchedPropertyType_1, name));
            }
        }
    }

    /**
     * Verifies the validity of the given value for the property of the given name, then returns the value to store.
     * The returned value is usually the same than the given one, except in the case of collections.
     */
    final Object verifyPropertyValue(final String name, final Object value) {
        final PropertyType pt = type.getProperty(name);
        if (pt instanceof AttributeType<?>) {
            if (value != null) {
                return verifyAttributeValue((AttributeType<?>) pt, value);
            }
        } else if (pt instanceof FeatureAssociationRole) {
            if (value != null) {
                return verifyAssociationValue((FeatureAssociationRole) pt, value);
            }
        } else {
            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
        }
        return value;
    }

    /**
     * Verifies the validity of the given attribute value, and returns the value to store in the feature.
     * An attribute:
     * <ul>
     *   <li>May be a singleton,  in which case the value class is verified.</li>
     *   <li>May be a collection, in which case the class each elements in the collection is verified.</li>
     * </ul>
     *
     * @param  value  the value, which shall be non-null.
     */
    private static <T> Object verifyAttributeValue(final AttributeType<T> type, final Object value) {
        final Class<T> valueClass = type.getValueClass();
        final boolean isSingleton = Field.isSingleton(type.getMaximumOccurs());
        if (valueClass.isInstance(value)) {
            return isSingleton ? value : singletonList(valueClass, type.getMinimumOccurs(), value);
        } else if (!isSingleton && value instanceof Collection<?>) {
            return CheckedArrayList.castOrCopy((Collection<?>) value, valueClass);
        } else {
            throw new ClassCastException(illegalValueClass(type, valueClass, value));
        }
    }

    /**
     * Verifies the validity of the given association value, and returns the value to store in the feature.
     * An association:
     * <ul>
     *   <li>May be a singleton,  in which case the feature type is verified.</li>
     *   <li>May be a collection, in which case the class each elements in the collection is verified.</li>
     * </ul>
     *
     * @param  value  the value, which shall be non-null.
     */
    private static Object verifyAssociationValue(final FeatureAssociationRole role, final Object value) {
        final boolean isSingleton = Field.isSingleton(role.getMaximumOccurs());
        if (value instanceof Feature) {
            /*
             * If the user gave us a single value, first verify its validity.
             * Then wrap it in a list of 1 element if this property is multi-valued.
             */
            final FeatureType valueType = ((Feature) value).getType();
            final FeatureType base = role.getValueType();
            if (base == valueType || DefaultFeatureType.maybeAssignableFrom(base, valueType)) {
                return isSingleton ? value : singletonList(Feature.class, role.getMinimumOccurs(), value);
            } else {
                throw new InvalidPropertyValueException(illegalFeatureType(role, base, valueType));
            }
        } else if (!isSingleton && value instanceof Collection<?>) {
            verifyAssociationValues(role, (Collection<?>) value);
            return CheckedArrayList.castOrCopy((Collection<?>) value, Feature.class);
        } else {
            throw new ClassCastException(illegalValueClass(role, Feature.class, value));
        }
    }

    /**
     * Verifies if all values in the given collection are valid instances of feature for the given association role.
     */
    private static void verifyAssociationValues(final FeatureAssociationRole role, final Collection<?> values) {
        final FeatureType base = role.getValueType();
        int index = 0;
        for (final Object value : values) {
            ArgumentChecks.ensureNonNullElement("values", index, value);
            if (!(value instanceof Feature)) {
                throw new ClassCastException(illegalValueClass(role, Feature.class, value));
            }
            final FeatureType type = ((Feature) value).getType();
            if (base != type && !DefaultFeatureType.maybeAssignableFrom(base, type)) {
                throw new InvalidPropertyValueException(illegalFeatureType(role, base, type));
            }
            index++;
        }
    }

    /**
     * Creates a collection which will initially contain only the given value.
     * At the difference of {@link Collections#singletonList(Object)}, this method returns a modifiable list.
     */
    @SuppressWarnings("unchecked")
    private static <V> Collection<V> singletonList(final Class<V> valueClass, final int minimumOccurs, final Object value) {
        final CheckedArrayList<V> values = new CheckedArrayList<>(valueClass, Math.max(minimumOccurs, 4));
        values.add((V) value);                              // Type will be checked by CheckedArrayList.
        return values;
    }

    /**
     * Returns the exception message for a property not found. The message will differ depending
     * on whether the property is not found because ambiguous or because it does not exist.
     *
     * @param  feature   the name of the feature where a property where searched ({@link String} or {@link GenericName}).
     * @param  property  the name of the property which has not been found.
     */
    static String propertyNotFound(final FeatureType type, final Object feature, final String property) {
        GenericName ambiguous = null;
        for (final IdentifiedType p : type.getProperties(true)) {
            final GenericName next = p.getName();
            GenericName name = next;
            do {
                if (property.equalsIgnoreCase(name.toString())) {
                    if (ambiguous == null) {
                        ambiguous = next;
                    } else {
                        return Errors.format(Errors.Keys.AmbiguousName_3, ambiguous, next, property);
                    }
                }
            } while (name instanceof ScopedName && (name = ((ScopedName) name).tail()) != null);
        }
        return Resources.format(Resources.Keys.PropertyNotFound_2, feature, property);
    }

    /**
     * Returns the exception message for a property type which is neither an attribute or an association.
     * This method is invoked after a {@link PropertyType} has been found for the user-supplied name,
     * but that property can not be stored in or extracted from a {@link Property} instance.
     */
    static String unsupportedPropertyType(final GenericName name) {
        return Resources.format(Resources.Keys.CanNotInstantiateProperty_1, name);
    }

    /**
     * Returns the exception message for a property value of wrong Java class.
     *
     * @param  value  the value, which shall be non-null.
     */
    private static String illegalValueClass(final IdentifiedType property, final Class<?> expected, final Object value) {
        return Resources.format(Resources.Keys.IllegalPropertyValueClass_3,
                                property.getName(), expected, value.getClass());
    }

    /**
     * Returns the exception message for an association value of wrong type.
     */
    private static String illegalFeatureType(
            final FeatureAssociationRole association, final FeatureType expected, final FeatureType actual)
    {
        return Resources.format(Resources.Keys.IllegalFeatureType_3,
                                association.getName(), expected.getName(), actual.getName());
    }

    /**
     * Evaluates the quality of this feature at this method invocation time. The data quality reports
     * may include information about whether the property values met the constraints defined by the
     * property types, or any other criterion at implementation choice.
     *
     * <p>The default implementation reports data quality with at least the following information:</p>
     * <ul>
     *   <li>
     *     The {@linkplain org.apache.sis.metadata.iso.quality.DefaultDataQuality#getScope() scope}
     *     {@linkplain org.apache.sis.metadata.iso.quality.DefaultScope#getLevel() level} is set to
     *     {@link org.opengis.metadata.maintenance.ScopeCode#FEATURE}.
     *   </li><li>
     *     The {@linkplain org.apache.sis.metadata.iso.quality.DefaultDataQuality#getReports() reports} list contains
     *     at most one {@linkplain org.apache.sis.metadata.iso.quality.DefaultDomainConsistency domain consistency}
     *     element per property. Implementations are free to omit element for properties having nothing to report.
     *   </li><li>
     *     Each report may have one or more {@linkplain org.apache.sis.metadata.iso.quality.DefaultConformanceResult
     *     conformance result}, as documented on {@link AbstractAttribute#quality()} javadoc.
     *   </li>
     * </ul>
     *
     * This feature is valid if this method does not report any
     * {@linkplain org.apache.sis.metadata.iso.quality.DefaultConformanceResult conformance result} having a
     * {@linkplain org.apache.sis.metadata.iso.quality.DefaultConformanceResult#pass() pass} value of {@code false}.
     *
     * <div class="note"><b>Example:</b> given a feature with an attribute named “population”.
     * If this attribute is mandatory ([1 … 1] multiplicity) but no value has been assigned to it,
     * then this {@code quality()} method will return the following data quality report:
     *
     * {@preformat text
     *   Data quality
     *     ├─Scope
     *     │   └─Level………………………………………………… Feature
     *     └─Report
     *         ├─Measure identification
     *         │   └─Code………………………………………… population
     *         ├─Evaluation method type…… Direct internal
     *         └─Result
     *             ├─Explanation……………………… Missing value for “population” property.
     *             └─Pass………………………………………… false
     * }
     * </div>
     *
     * @return reports on all constraint violations found.
     *
     * @see AbstractAttribute#quality()
     * @see AbstractAssociation#quality()
     */
    public DataQuality quality() {
        final Validator v = new Validator(ScopeCode.FEATURE);
        v.validate(type, this);
        return v.quality;
    }

    /**
     * Formats this feature in a tabular format.
     *
     * @return a string representation of this feature in a tabular format.
     *
     * @see FeatureFormat
     */
    @Override
    public String toString() {
        return FeatureFormat.sharedFormat(this);
    }

    /**
     * Returns a hash code value for this feature.
     * The default implementation performs the following algorithm:
     *
     * <ul>
     *   <li>Iterate over all properties returned by {@code type.getProperty(true)} –
     *       thus including properties inherited from parent types (if any):
     *   <ul>
     *     <li>For each property type, get the value with {@link #getPropertyValue(String)}.</li>
     *     <li>Compute the hash code from the property name and value, ignoring the properties
     *         having a null value.</li>
     *   </ul></li>
     * </ul>
     *
     * Subclasses should override this method with a more efficient algorithm for their internal structure.
     * There is no need to reproduce the same hash code value than the one computed by this default method.
     *
     * @return a hash code value.
     *
     * @since 0.8
     */
    @Override
    public int hashCode() {
        int code = type.hashCode() * 37;
        for (final PropertyType pt : type.getProperties(true)) {
            final String name = pt.getName().toString();
            if (name != null) {                                             // Paranoiac check.
                final Object value = getPropertyValue(name);
                if (value != null) {
                    code += name.hashCode() ^ value.hashCode();
                }
            }
        }
        return code;
    }

    /**
     * Compares this feature with the given object for equality.
     * The default implementation performs the following algorithm:
     *
     * <ul>
     *   <li>Verify that both objects are non-null and of the same class.</li>
     *   <li>Iterate over all properties returned by {@code type.getProperty(true)} –
     *       thus including properties inherited from parent types (if any):
     *   <ul>
     *     <li>For each property type, get the value from both {@code FeatureType}
     *         by a call to {@link #getPropertyValue(String)}.</li>
     *     <li>Verify that the two values are either both null, or equal in the sense of
     *         {@link Object#equals(Object)}.</li>
     *   </ul></li>
     * </ul>
     *
     * Subclasses should override this method with a more efficient algorithm for their internal structure.
     *
     * @return {@code true} if both objects are equal.
     *
     * @since 0.8
     */
    @Override
    public boolean equals(final Object obj) {
        if (obj != this) {
            if (obj == null || obj.getClass() != getClass()) {
                return false;
            }
            final AbstractFeature that = (AbstractFeature) obj;
            if (!type.equals(that.type)) {
                return false;
            }
            for (final PropertyType pt : type.getProperties(true)) {
                final String name = pt.getName().toString();
                if (!Objects.equals(getPropertyValue(name), that.getPropertyValue(name))) {
                    return false;
                }
            }
        }
        return true;
    }
}
