/*
 * 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;


/**
 * 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 Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -5637918246427380190L;

    /**
     * Information about the feature (name, characteristics, <i>etc.</i>).
     */
    final DefaultFeatureType 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 DefaultFeatureType 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>).
     *
     * <div class="warning"><b>Warning:</b> In a future SIS version, the return type may be changed
     * to {@code org.opengis.feature.FeatureType}. This change is pending GeoAPI revision.</div>
     *
     * @return information about the feature.
     */
    public DefaultFeatureType 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>
     *
     * <div class="warning"><b>Warning:</b> In a future SIS version, the return type may be changed
     * to {@code org.opengis.feature.Property}. This change is pending GeoAPI revision.</div>
     *
     * @param  name  the property name.
     * @return the property of the given name (never {@code null}).
     * @throws IllegalArgumentException if the given argument is not a property name of this feature.
     *
     * @see #getPropertyValue(String)
     * @see DefaultFeatureType#getProperty(String)
     */
    public Object getProperty(final String name) throws IllegalArgumentException {
        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>
     *
     * <div class="warning"><b>Warning:</b> In a future SIS version, the argument may be changed
     * to {@code org.opengis.feature.Property}. This change is pending GeoAPI revision.</div>
     *
     * @param  property  the property to set.
     * @throws IllegalArgumentException if the name of the given property is not a property name of this feature.
     * @throws IllegalArgumentException 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)
     */
    public void setProperty(final Object property) throws IllegalArgumentException {
        ArgumentChecks.ensureNonNull("property", property);
        final String name = ((Property) property).getName().toString();
        verifyPropertyType(name, (Property) property);
        if (property instanceof AbstractAttribute<?> && !Containers.isNullOrEmpty(((AbstractAttribute<?>) property).characteristics())) {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.CanNotAssignCharacteristics_1, name));
        }
        setPropertyValue(name, ((Property) 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 AbstractIdentifiedType pt = type.getProperty(name);
        if (pt instanceof DefaultAttributeType<?>) {
            return AbstractAttribute.create((DefaultAttributeType<?>) pt, value);
        } else if (pt instanceof DefaultAssociationRole) {
            return AbstractAssociation.create((DefaultAssociationRole) 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 IllegalArgumentException if the given argument is not the name of an attribute or
     *         feature association of this feature.
     */
    final Property createProperty(final String name) throws IllegalArgumentException {
        final AbstractIdentifiedType pt = type.getProperty(name);
        if (pt instanceof DefaultAttributeType<?>) {
            return ((DefaultAttributeType<?>) pt).newInstance();
        } else if (pt instanceof DefaultAssociationRole) {
            return ((DefaultAssociationRole) 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 Object 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(type.indices().get(name)) : name;
        return ((AbstractOperation) 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 IllegalArgumentException if the given argument is not an attribute or association name of this feature.
     */
    final Object getDefaultValue(final String name) throws IllegalArgumentException {
        final AbstractIdentifiedType pt = type.getProperty(name);
        if (pt instanceof DefaultAttributeType<?>) {
            return getDefaultValue((DefaultAttributeType<?>) pt);
        } else if (pt instanceof DefaultAssociationRole) {
            final int maximumOccurs = ((DefaultAssociationRole) 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 DefaultAttributeType<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>{@code AttributeType}</td>          <td>0 or 1</td>      <td>{@code Attribute.getValue()}</td>           <td>{@link Object}</td></tr>
     *   <tr><td>{@code AttributeType}</td>          <td>2 or more</td>   <td>{@code Attribute.getValues()}</td>          <td>{@code Collection<?>}</td></tr>
     *   <tr><td>{@code FeatureAssociationRole}</td> <td>0 or 1</td>      <td>{@code FeatureAssociation.getValue()}</td>  <td>{@code Feature}</td></tr>
     *   <tr><td>{@code FeatureAssociationRole}</td> <td>2 or more</td>   <td>{@code 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 IllegalArgumentException if the given argument is not an attribute or association name of this feature.
     *
     * @see AbstractAttribute#getValue()
     */
    public abstract Object getPropertyValue(final String name) throws IllegalArgumentException;

    /**
     * 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 IllegalArgumentException 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 IllegalArgumentException if the given value is not valid for a reason other than its type.
     *
     * @see AbstractAttribute#setValue(Object)
     */
    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 AbstractOperation}.
     * @return the result value of the given operation, or {@code null} if none.
     *
     * @since 0.8
     */
    protected Object getOperationValue(final String name) {
        final AbstractOperation operation = (AbstractOperation) type.getProperty(name);
        if (operation instanceof LinkOperation) {
            return getPropertyValue(((LinkOperation) operation).referentName);
        }
        final Object result = operation.apply(this, null);
        if (result instanceof AbstractAttribute<?>) {
            return getAttributeValue((AbstractAttribute<?>) result);
        } else if (result instanceof AbstractAssociation) {
            return getAssociationValue((AbstractAssociation) 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 AbstractOperation}.
     * @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 AbstractOperation operation = (AbstractOperation) type.getProperty(name);
        if (operation instanceof LinkOperation) {
            setPropertyValue(((LinkOperation) operation).referentName, value);
        } else {
            final Object result = operation.apply(this, null);
            if (result instanceof Property) {
                setPropertyValue((Property) 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 AbstractAttribute<?> 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 AbstractAssociation 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 AbstractAttribute<?>) {
            setAttributeValue((AbstractAttribute<?>) property, value);
        } else if (property instanceof AbstractAssociation) {
            setAssociationValue((AbstractAssociation) 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 AbstractAttribute<V> attribute, final Object value) {
        if (value != null) {
            final DefaultAttributeType<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()) {
                        ((AbstractAttribute) 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.
            }
        }
        ((AbstractAttribute) 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 AbstractAssociation association, final Object value) {
        if (value != null) {
            final DefaultAssociationRole role = association.getRole();
            final DefaultFeatureType base = role.getValueType();
            if (value instanceof AbstractFeature) {
                final DefaultFeatureType actual = ((AbstractFeature) value).getType();
                if (base != actual && !DefaultFeatureType.maybeAssignableFrom(base, actual)) {
                    throw new IllegalArgumentException(illegalFeatureType(role, base, actual));
                }
            } else if (value instanceof Collection<?>) {
                verifyAssociationValues(role, (Collection<?>) value);
                association.setValues((Collection<? extends AbstractFeature>) value);
                return;                                 // Skip the setter at the end of this method.
            } else {
                throw new ClassCastException(illegalValueClass(role, AbstractFeature.class, value));
            }
        }
        association.setValue((AbstractFeature) 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 AbstractFeature)) {
                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 AbstractIdentifiedType pt, base = type.getProperty(name);
        if (property instanceof AbstractAttribute<?>) {
            pt = ((AbstractAttribute<?>) property).getType();
        } else if (property instanceof AbstractAssociation) {
            pt = ((AbstractAssociation) property).getRole();
        } else {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.IllegalPropertyType_2, base.getName(), property.getClass()));
        }
        if (pt != base) {
            if (base == null) {
                throw new IllegalArgumentException(Resources.format(Resources.Keys.PropertyNotFound_2, getName(), name));
            } else {
                throw new IllegalArgumentException(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 AbstractIdentifiedType pt = type.getProperty(name);
        if (pt instanceof DefaultAttributeType<?>) {
            if (value != null) {
                return verifyAttributeValue((DefaultAttributeType<?>) pt, value);
            }
        } else if (pt instanceof DefaultAssociationRole) {
            if (value != null) {
                return verifyAssociationValue((DefaultAssociationRole) 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 DefaultAttributeType<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 DefaultAssociationRole role, final Object value) {
        final boolean isSingleton = Field.isSingleton(role.getMaximumOccurs());
        if (value instanceof AbstractFeature) {
            /*
             * 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 DefaultFeatureType valueType = ((AbstractFeature) value).getType();
            final DefaultFeatureType base = role.getValueType();
            if (base == valueType || DefaultFeatureType.maybeAssignableFrom(base, valueType)) {
                return isSingleton ? value : singletonList(AbstractFeature.class, role.getMinimumOccurs(), value);
            } else {
                throw new IllegalArgumentException(illegalFeatureType(role, base, valueType));
            }
        } else if (!isSingleton && value instanceof Collection<?>) {
            verifyAssociationValues(role, (Collection<?>) value);
            return CheckedArrayList.castOrCopy((Collection<?>) value, AbstractFeature.class);
        } else {
            throw new ClassCastException(illegalValueClass(role, AbstractFeature.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 DefaultAssociationRole role, final Collection<?> values) {
        final DefaultFeatureType base = role.getValueType();
        int index = 0;
        for (final Object value : values) {
            ArgumentChecks.ensureNonNullElement("values", index, value);
            if (!(value instanceof AbstractFeature)) {
                throw new ClassCastException(illegalValueClass(role, AbstractFeature.class, value));
            }
            final DefaultFeatureType type = ((AbstractFeature) value).getType();
            if (base != type && !DefaultFeatureType.maybeAssignableFrom(base, type)) {
                throw new IllegalArgumentException(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 AbstractIdentifiedType 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 {@code 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 AbstractIdentifiedType 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 DefaultAssociationRole 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 AbstractIdentifiedType 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 AbstractIdentifiedType pt : type.getProperties(true)) {
                final String name = pt.getName().toString();
                if (!Objects.equals(getPropertyValue(name), that.getPropertyValue(name))) {
                    return false;
                }
            }
        }
        return true;
    }
}
