/*
 * 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.referencing.operation;

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Collections;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import org.opengis.util.InternationalString;
import org.opengis.metadata.citation.Citation;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.operation.Formula;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.parameter.GeneralParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.Workaround;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.internal.referencing.WKTKeywords;
import org.apache.sis.internal.jaxb.gco.StringAdapter;
import org.apache.sis.internal.jaxb.referencing.CC_OperationMethod;
import org.apache.sis.internal.referencing.NilReferencingObject;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.metadata.Identifiers;
import org.apache.sis.internal.metadata.MetadataUtilities;
import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
import org.apache.sis.parameter.Parameterized;
import org.apache.sis.referencing.NamedIdentifier;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.referencing.AbstractIdentifiedObject;
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.io.wkt.ElementKind;
import org.apache.sis.io.wkt.FormattableObject;

import static org.apache.sis.util.ArgumentChecks.*;


/**
 * Describes the algorithm and parameters used to perform a coordinate operation. An {@code OperationMethod}
 * is a kind of metadata: it does not perform any coordinate operation (e.g. map projection) by itself, but
 * tells us what is needed in order to perform such operation.
 *
 * <p>The most important parts of an {@code OperationMethod} are its {@linkplain #getName() name} and its
 * {@linkplain #getParameters() group of parameter descriptors}. The parameter descriptors do not contain
 * any value, but tell us what are the expected parameters, together with their units of measurement.</p>
 *
 * <div class="note"><b>Example:</b>
 * An operation method named “<cite>Mercator (variant A)</cite>” (EPSG:9804) expects the following parameters:
 * <ul>
 *   <li>“<cite>Latitude of natural origin</cite>” in degrees. Default value is 0°.</li>
 *   <li>“<cite>Longitude of natural origin</cite>” in degrees. Default value is 0°.</li>
 *   <li>“<cite>Scale factor at natural origin</cite>” as a dimensionless number. Default value is 1.</li>
 *   <li>“<cite>False easting</cite>” in metres. Default value is 0 m.</li>
 *   <li>“<cite>False northing</cite>” in metres. Default value is 0 m.</li>
 * </ul></div>
 *
 * In Apache SIS implementation, the {@linkplain #getName() name} is the only mandatory property. However it is
 * recommended to provide also {@linkplain #getIdentifiers() identifiers} (e.g. “EPSG:9804” in the above example)
 * since names can sometime be ambiguous or be spelled in different ways.
 *
 * <h2>Departure from the ISO 19111 standard</h2>
 * The following properties are mandatory according ISO 19111,
 * but may be missing under some conditions in Apache SIS:
 * <ul>
 *   <li>The {@linkplain #getFormula() formula} if it has not been provided to the
 *     {@linkplain #DefaultOperationMethod(Map, Integer, Integer, ParameterDescriptorGroup) constructor}, or if it
 *     can not be {@linkplain #DefaultOperationMethod(MathTransform) inferred from the given math transform}.</li>
 *   <li>The {@linkplain #getParameters() parameters} if the {@link #DefaultOperationMethod(MathTransform)}
 *     constructor can not infer them.</li>
 * </ul>
 *
 * <h2>Relationship with other classes or interfaces</h2>
 * {@code OperationMethod} describes parameters without providing any value (except sometime default values).
 * When values have been assigned to parameters, the result is a {@link SingleOperation}.
 * Note that there is different kinds of {@code SingleOperation} depending on the nature and accuracy of the
 * coordinate operation. See {@link #getOperationType()} for more information.
 *
 * <p>The interface performing the actual work of taking coordinates in the
 * {@linkplain AbstractCoordinateOperation#getSourceCRS() source CRS} and calculating the new coordinates in the
 * {@linkplain AbstractCoordinateOperation#getTargetCRS() target CRS} is {@link MathTransform}.
 * In order to allow Apache SIS to instantiate those {@code MathTransform}s from given parameter values,
 * {@code DefaultOperationMethod} subclasses should implement the
 * {@link org.apache.sis.referencing.operation.transform.MathTransformProvider} interface.</p>
 *
 * <h2>Immutability and thread safety</h2>
 * This class is immutable and thread-safe if all properties given to the constructor are also immutable and thread-safe.
 * It is strongly recommended for all subclasses to be thread-safe, especially the
 * {@link org.apache.sis.referencing.operation.transform.MathTransformProvider} implementations to be used with
 * {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory}.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.7
 *
 * @see DefaultConversion
 * @see DefaultTransformation
 * @see org.apache.sis.referencing.operation.transform.MathTransformProvider
 *
 * @since 0.5
 * @module
 */
@XmlType(name = "OperationMethodType", propOrder = {
    "formulaCitation",
    "formulaDescription",
    "sourceDimensions",
    "targetDimensions",
    "descriptors"
})
@XmlRootElement(name = "OperationMethod")
public class DefaultOperationMethod extends AbstractIdentifiedObject implements OperationMethod {
    /*
     * NOTE FOR JAVADOC WRITER:
     * The "method" word is ambiguous here, because it can be "Java method" or "coordinate operation method".
     * In this class, we reserve the "method" word for "coordinate operation method" as much as possible.
     */

    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = 2870579345991143357L;

    /**
     * Formula(s) or procedure used by this operation method. This may be a reference to a publication.
     * Note that the operation method may not be analytic, in which case this attribute references or
     * contains the procedure, not an analytic formula.
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setFormulaCitation(Citation)}
     * or {@link #setFormulaDescription(String)}.</p>
     */
    private Formula formula;

    /**
     * Number of dimensions in the source CRS of this operation method.
     * May be {@code null} if this method can work with any number of
     * source dimensions (e.g. <cite>Affine Transform</cite>).
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setSourceDimensions(Integer)}</p>
     *
     * @see #getSourceDimensions()
     */
    private Integer sourceDimensions;

    /**
     * Number of dimensions in the target CRS of this operation method.
     * May be {@code null} if this method can work with any number of
     * target dimensions (e.g. <cite>Affine Transform</cite>).
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setTargetDimensions(Integer)}</p>
     *
     * @see #getTargetDimensions()
     */
    private Integer targetDimensions;

    /**
     * The set of parameters, or {@code null} if none.
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setDescriptors(GeneralParameterDescriptor[])}</p>
     */
    private ParameterDescriptorGroup parameters;

    /**
     * Constructs an operation method from a set of properties and a descriptor group. The properties map is given
     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
     * In addition to the properties documented in the parent constructor,
     * the following properties are understood by this constructor:
     *
     * <table class="sis">
     *   <caption>Recognized properties (non exhaustive list)</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Value type</th>
     *     <th>Returned by</th>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.operation.OperationMethod#FORMULA_KEY}</td>
     *     <td>{@link Formula}, {@link Citation} or {@link CharSequence}</td>
     *     <td>{@link #getFormula()}</td>
     *   </tr>
     *   <tr>
     *     <th colspan="3" class="hsep">Defined in parent classes (reminder)</th>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
     *     <td>{@link #getName()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
     *     <td>{@link org.opengis.util.GenericName} or {@link CharSequence} (optionally as array)</td>
     *     <td>{@link #getAlias()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
     *     <td>{@link #getIdentifiers()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
     *     <td>{@link InternationalString} or {@link String}</td>
     *     <td>{@link #getRemarks()}</td>
     *   </tr>
     * </table>
     *
     * The source and target dimensions may be {@code null} if this method can work
     * with any number of dimensions (e.g. <cite>Affine Transform</cite>).
     *
     * @param  properties        set of properties. Shall contain at least {@code "name"}.
     * @param  sourceDimensions  number of dimensions in the source CRS of this operation method, or {@code null}.
     * @param  targetDimensions  number of dimensions in the target CRS of this operation method, or {@code null}.
     * @param  parameters        description of parameters expected by this operation.
     */
    public DefaultOperationMethod(final Map<String,?> properties,
                                  final Integer sourceDimensions,
                                  final Integer targetDimensions,
                                  final ParameterDescriptorGroup parameters)
    {
        super(properties);
        if (sourceDimensions != null) ensurePositive("sourceDimensions", sourceDimensions);
        if (targetDimensions != null) ensurePositive("targetDimensions", targetDimensions);
        ensureNonNull("parameters", parameters);

        Object value = properties.get(FORMULA_KEY);
        if (value == null || value instanceof Formula) {
            formula = (Formula) value;
        } else if (value instanceof Citation) {
            formula = new DefaultFormula((Citation) value);
        } else if (value instanceof CharSequence) {
            formula = new DefaultFormula((CharSequence) value);
        } else {
            throw new IllegalArgumentException(Errors.getResources(properties)
                    .getString(Errors.Keys.IllegalPropertyValueClass_2, FORMULA_KEY, value.getClass()));
        }
        this.parameters       = parameters;
        this.sourceDimensions = sourceDimensions;
        this.targetDimensions = targetDimensions;
    }

    /**
     * Convenience constructor that creates an operation method from a math transform.
     * The information provided in the newly created object are approximations, and
     * usually acceptable only as a fallback when no other information are available.
     *
     * @param  transform  the math transform to describe.
     */
    public DefaultOperationMethod(final MathTransform transform) {
        super(getProperties(transform));
        sourceDimensions = transform.getSourceDimensions();
        targetDimensions = transform.getTargetDimensions();
        if (transform instanceof Parameterized) {
            parameters = ((Parameterized) transform).getParameterDescriptors();
        } else {
            parameters = null;
        }
        formula = null;
    }

    /**
     * Work around for RFE #4093999 in Sun's bug database
     * ("Relax constraint on placement of this()/super() call in constructors").
     */
    @Workaround(library="JDK", version="1.7")
    private static Map<String,?> getProperties(final MathTransform transform) {
        ensureNonNull("transform", transform);
        if (transform instanceof Parameterized) {
            final ParameterDescriptorGroup parameters = ((Parameterized) transform).getParameterDescriptors();
            if (parameters != null) {
                return getProperties(parameters, null);
            }
        }
        return Collections.singletonMap(NAME_KEY, NilReferencingObject.UNNAMED);
    }

    /**
     * Returns the properties to be given to an identified object derived from the specified one.
     * This method returns the same properties than the supplied argument
     * (as of <code>{@linkplain IdentifiedObjects#getProperties getProperties}(info)</code>),
     * except for the following:
     *
     * <ul>
     *   <li>The {@linkplain IdentifiedObject#getName() name}'s authority is replaced by the specified one.</li>
     *   <li>All {@linkplain IdentifiedObject#getIdentifiers identifiers} are removed, because the new object
     *       to be created is probably not endorsed by the original authority.</li>
     * </ul>
     *
     * This method returns a mutable map. Consequently, callers can add their own identifiers
     * directly to this map if they wish.
     *
     * @param  info       the identified object to view as a properties map.
     * @param  authority  the new authority for the object to be created,
     *                    or {@code null} if it is not going to have any declared authority.
     * @return the identified object properties in a mutable map.
     */
    private static Map<String,Object> getProperties(final IdentifiedObject info, final Citation authority) {
        final Map<String,Object> properties = new HashMap<>(IdentifiedObjects.getProperties(info));
        properties.put(NAME_KEY, new NamedIdentifier(authority, info.getName().getCode()));
        properties.remove(IDENTIFIERS_KEY);
        return properties;
    }

    /**
     * Creates a new operation method with the same values than the specified one.
     * This copy constructor provides a way to convert an arbitrary implementation into a SIS one
     * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API.
     *
     * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p>
     *
     * @param  method  the operation method to copy.
     *
     * @see #castOrCopy(OperationMethod)
     */
    protected DefaultOperationMethod(final OperationMethod method) {
        super(method);
        formula          = method.getFormula();
        parameters       = method.getParameters();
        sourceDimensions = method.getSourceDimensions();
        targetDimensions = method.getTargetDimensions();
    }

    /**
     * Returns a SIS operation method implementation with the same values than the given arbitrary implementation.
     * If the given object is {@code null}, then {@code null} is returned.
     * Otherwise if the given object is already a SIS implementation, then the given object is returned unchanged.
     * Otherwise a new SIS implementation is created and initialized to the attribute values of the given object.
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultOperationMethod castOrCopy(final OperationMethod object) {
        return (object == null) || (object instanceof DefaultOperationMethod)
               ? (DefaultOperationMethod) object : new DefaultOperationMethod(object);
    }

    /**
     * Constructs a new operation method with the same values than the specified one except the dimensions.
     * The source and target dimensions may be {@code null} if this method can work with any number of dimensions
     * (e.g. <cite>Affine Transform</cite>).
     *
     * @param  method            the operation method to copy.
     * @param  sourceDimensions  number of dimensions in the source CRS of this operation method.
     * @param  targetDimensions  number of dimensions in the target CRS of this operation method.
     */
    private DefaultOperationMethod(final OperationMethod method,
                                   final Integer sourceDimensions,
                                   final Integer targetDimensions)
    {
        super(method);
        this.formula    = method.getFormula();
        this.parameters = method.getParameters();
        this.sourceDimensions = sourceDimensions;
        this.targetDimensions = targetDimensions;
    }

    /**
     * Returns an operation method with different dimensions, if we are allowed to change dimensionality.
     * This method accepts to change a dimension only if the value specified by the original method
     * is {@code null}. Otherwise an {@link IllegalArgumentException} is thrown.
     *
     * @param  method            the operation method to redimension.
     * @param  sourceDimensions  the desired new source dimensions.
     * @param  methodSource      the current number of source dimensions (may be {@code null}).
     * @param  targetDimensions  the desired new target dimensions.
     * @param  methodTarget      the current number of target dimensions (may be {@code null}).
     * @throws IllegalArgumentException if the given dimensions are illegal for this operation method.
     */
    private static OperationMethod redimension(final OperationMethod method,
            final int sourceDimensions, final Integer methodSource,
            final int targetDimensions, final Integer methodTarget)
    {
        boolean sourceValids = (methodSource != null) && (methodSource == sourceDimensions);
        boolean targetValids = (methodTarget != null) && (methodTarget == targetDimensions);
        if (sourceValids && targetValids) {
            return method;
        }
        sourceValids |= (methodSource == null);
        targetValids |= (methodTarget == null);
        ensurePositive("sourceDimensions", sourceDimensions);
        ensurePositive("targetDimensions", targetDimensions);
        if (!sourceValids || !targetValids) {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.IllegalOperationDimension_3,
                    method.getName().getCode(), sourceDimensions, targetDimensions));
        }
        return new DefaultOperationMethod(method, sourceDimensions, targetDimensions);
    }

    /**
     * Returns an operation method with different dimensions, if we are allowed to change dimensionality.
     * The need to change an {@code OperationMethod} dimensionality may occur in two contexts:
     *
     * <ul class="verbose">
     *   <li>When the original method can work with any number of dimensions. Those methods do not know
     *     in advance the number of dimensions, which is fixed only after the actual {@link MathTransform}
     *     instance has been created.
     *     Example: <cite>Affine</cite> conversion.</li>
     *   <li>When a three-dimensional method can also be used in the two-dimensional case, typically by
     *     assuming that the ellipsoidal height is zero everywhere.
     *     Example: <cite>Molodensky</cite> transform.</li>
     * </ul>
     *
     * This {@code redimension(…)} implementation performs the following choice:
     *
     * <ul class="verbose">
     *   <li>If the given method is an instance of {@code DefaultOperationMethod}, then delegate to
     *     {@link #redimension(int, int)} in order to allow subclasses to defines their own policy.
     *     For example the <cite>Molodensky</cite> method needs to override.</li>
     *   <li>Otherwise for each dimension (<var>source</var> and <var>target</var>):
     *     <ul>
     *       <li>If the corresponding dimension of the given method is {@code null}, then
     *         set that dimension to the given value in a new {@code OperationMethod}.</li>
     *       <li>Otherwise if the given value is not equal to the corresponding dimension
     *         in the given method, throw an {@link IllegalArgumentException}.</li>
     *     </ul>
     *   </li>
     * </ul>
     *
     * @param  method            the operation method to redimension, or {@code null}.
     * @param  sourceDimensions  the desired number of input dimensions.
     * @param  targetDimensions  the desired number of output dimensions.
     * @return the redimensioned operation method, or {@code null} if the given method was null,
     *         or {@code method} if no change is needed.
     * @throws IllegalArgumentException if the given dimensions are illegal for the given operation method.
     */
    public static OperationMethod redimension(OperationMethod method,
            final int sourceDimensions, final int targetDimensions)
    {
        if (method != null) {
            if (method instanceof DefaultOperationMethod) {
                return ((DefaultOperationMethod) method).redimension(sourceDimensions, targetDimensions);
            } else {
                method = redimension(method, sourceDimensions, method.getSourceDimensions(),
                                             targetDimensions, method.getTargetDimensions());
            }
        }
        return method;
    }

    /**
     * Returns this operation method with different dimensions, if we are allowed to change dimensionality.
     * See {@link #redimension(OperationMethod, int, int)} for more information.
     *
     * <p>The default implementation performs the following choice:
     * for each dimension (<var>source</var> and <var>target</var>):</p>
     * <ul>
     *   <li>If the corresponding dimension of the given method is {@code null}, then
     *       set that dimension to the given value in a new {@code OperationMethod}.</li>
     *   <li>Otherwise if the given value is not equal to the corresponding dimension
     *       in the given method, throw an {@link IllegalArgumentException}.</li>
     * </ul>
     *
     * Subclasses should override this method if they can work with different number of dimensions.
     * For example a <cite>Molodensky</cite> transform usually works in a three-dimensional space,
     * but can also work in a two-dimensional space by assuming that the ellipsoidal height is zero
     * everywhere.
     *
     * @param  sourceDimensions  the desired number of input dimensions.
     * @param  targetDimensions  the desired number of output dimensions.
     * @return the redimensioned operation method, or {@code this} if no change is needed.
     * @throws IllegalArgumentException if the given dimensions are illegal for this operation method.
     *
     * @since 0.6
     */
    public OperationMethod redimension(final int sourceDimensions, final int targetDimensions) {
        return redimension(this, sourceDimensions, this.sourceDimensions,
                                 targetDimensions, this.targetDimensions);
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The SIS implementation returns {@code OperationMethod.class}.
     *
     * <div class="note"><b>Note for implementers:</b>
     * Subclasses usually do not need to override this information since GeoAPI does not define {@code OperationMethod}
     * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with their
     * own set of interfaces.</div>
     *
     * @return {@code OperationMethod.class} or a user-defined sub-interface.
     */
    @Override
    public Class<? extends OperationMethod> getInterface() {
        return OperationMethod.class;
    }

    /**
     * Returns the base interface of the {@code CoordinateOperation} instances that use this method.
     * The base {@code CoordinateOperation} interface is usually one of the following subtypes:
     *
     * <ul class="verbose">
     *   <li>{@link org.opengis.referencing.operation.Transformation}
     *     if the coordinate operation has some errors (typically of a few metres) because of the empirical process by
     *     which the operation parameters were determined. Those errors do not depend on the floating point precision
     *     or the accuracy of the implementation algorithm.</li>
     *   <li class="verbose">{@link org.opengis.referencing.operation.Conversion}
     *     if the coordinate operation is theoretically of infinite precision, ignoring the limitations of floating
     *     point arithmetic (including rounding errors) and the approximations implied by finite series expansions.</li>
     *   <li>{@link org.opengis.referencing.operation.Projection}
     *     if the coordinate operation is a conversion (as defined above) converting geodetic latitudes and longitudes
     *     to plane (map) coordinates. This type can optionally be refined with one of the
     *     {@link org.opengis.referencing.operation.CylindricalProjection},
     *     {@link org.opengis.referencing.operation.ConicProjection} or
     *     {@link org.opengis.referencing.operation.PlanarProjection} subtypes.</li>
     * </ul>
     *
     * In case of doubt, {@code getOperationType()} can conservatively return the base type.
     * The default implementation returns {@code SingleOperation.class},
     * which is the most conservative return value.
     *
     * @return interface implemented by all coordinate operations that use this method.
     *
     * @see org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory#getAvailableMethods(Class)
     */
    public Class<? extends SingleOperation> getOperationType() {
        return SingleOperation.class;
    }

    /**
     * Formula(s) or procedure used by this operation method. This may be a reference to a
     * publication. Note that the operation method may not be analytic, in which case this
     * attribute references or contains the procedure, not an analytic formula.
     *
     * <div class="note"><b>Departure from the ISO 19111 standard:</b>
     * this property is mandatory according ISO 19111, but optional in Apache SIS.</div>
     *
     * @return the formula used by this method, or {@code null} if unknown.
     *
     * @see DefaultFormula
     * @see org.apache.sis.referencing.operation.transform.MathTransformProvider
     */
    @Override
    public Formula getFormula() {
        return formula;
    }

    /**
     * Number of dimensions in the source CRS of this operation method.
     * May be null if unknown, as in an <cite>Affine Transform</cite>.
     *
     * @return the dimension of source CRS, or {@code null} if unknown.
     *
     * @see org.apache.sis.referencing.operation.transform.AbstractMathTransform#getSourceDimensions()
     */
    @Override
    @XmlElement(name = "sourceDimensions")
    @XmlSchemaType(name = "positiveInteger")
    public Integer getSourceDimensions() {
        return sourceDimensions;
    }

    /**
     * Number of dimensions in the target CRS of this operation method.
     * May be null if unknown, as in an <cite>Affine Transform</cite>.
     *
     * @return the dimension of target CRS, or {@code null} if unknown.
     *
     * @see org.apache.sis.referencing.operation.transform.AbstractMathTransform#getTargetDimensions()
     */
    @Override
    @XmlElement(name = "targetDimensions")
    @XmlSchemaType(name = "positiveInteger")
    public Integer getTargetDimensions() {
        return targetDimensions;
    }

    /**
     * Returns the set of parameters.
     *
     * <div class="note"><b>Departure from the ISO 19111 standard:</b>
     * this property is mandatory according ISO 19111, but may be null in Apache SIS if the
     * {@link #DefaultOperationMethod(MathTransform)} constructor has been unable to infer it
     * or if this {@code OperationMethod} has been read from an incomplete GML document.</div>
     *
     * @return the parameters, or {@code null} if unknown.
     *
     * @see DefaultConversion#getParameterDescriptors()
     * @see DefaultConversion#getParameterValues()
     */
    @Override
    public ParameterDescriptorGroup getParameters() {
        return parameters;
    }

    /**
     * Compares this operation method with the specified object for equality.
     * If the {@code mode} argument value is {@link ComparisonMode#STRICT STRICT} or
     * {@link ComparisonMode#BY_CONTRACT BY_CONTRACT}, then all available properties
     * are compared including the {@linkplain #getFormula() formula}.
     *
     * @param  object  the object to compare to {@code this}.
     * @param  mode    {@link ComparisonMode#STRICT STRICT} for performing a strict comparison, or
     *                 {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} for comparing only
     *                 properties relevant to transformations.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        if (object == this) {
            return true;                                                // Slight optimization.
        }
        if (super.equals(object, mode)) {
            switch (mode) {
                case STRICT: {
                    // Name and identifiers have been compared by super.equals(object, mode).
                    final DefaultOperationMethod that = (DefaultOperationMethod) object;
                    return Objects.equals(this.formula,          that.formula) &&
                           Objects.equals(this.sourceDimensions, that.sourceDimensions) &&
                           Objects.equals(this.targetDimensions, that.targetDimensions) &&
                           Objects.equals(this.parameters,       that.parameters);
                }
                case BY_CONTRACT: {
                    // Name and identifiers have been compared by super.equals(object, mode).
                    if (!Objects.equals(getFormula(), ((OperationMethod) object).getFormula())) {
                        return false;
                    }
                    break;
                }
                default: {
                    /*
                     * Name and identifiers have been ignored by super.equals(object, mode).
                     * Since they are significant for OperationMethod, we compare them here.
                     *
                     * According ISO 19162 (Well Known Text representation of Coordinate Reference Systems),
                     * identifiers shall have precedence over name at least in the case of operation methods
                     * and parameters.
                     */
                    final OperationMethod that = (OperationMethod) object;
                    final Boolean match = Identifiers.hasCommonIdentifier(getIdentifiers(), that.getIdentifiers());
                    if (match != null) {
                        if (!match) {
                            return false;
                        }
                    } else if (!isHeuristicMatchForName(that.getName().getCode())
                            && !IdentifiedObjects.isHeuristicMatchForName(that, getName().getCode()))
                    {
                        return false;
                    }
                    break;
                }
            }
            final OperationMethod that = (OperationMethod) object;
            return Objects.equals(getSourceDimensions(), that.getSourceDimensions()) &&
                   Objects.equals(getTargetDimensions(), that.getTargetDimensions()) &&
                   Utilities.deepEquals(getParameters(), that.getParameters(), mode);
        }
        return false;
    }

    /**
     * Invoked by {@code hashCode()} for computing the hash code when first needed.
     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
     * for more information.
     *
     * @return the hash code value. This value may change in any future Apache SIS version.
     */
    @Override
    protected long computeHashCode() {
        return super.computeHashCode() + Objects.hash(sourceDimensions, targetDimensions, parameters);
    }

    /**
     * Formats this operation as a <cite>Well Known Text</cite> {@code Method[…]} element.
     *
     * @return {@code "Method"} (WKT 2) or {@code "Projection"} (WKT 1).
     *
     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#118">WKT 2 specification §17.2.3</a>
     */
    @Override
    protected String formatTo(final Formatter formatter) {
        final boolean isWKT1 = formatter.getConvention().majorVersion() == 1;
        /*
         * The next few lines below are basically a copy of the work done by super.formatTo(formatter),
         * which search for the name to write inside METHOD["name"]. The difference is in the fallback
         * executed if we do not find a name for the given authority.
         */
        final Citation authority = formatter.getNameAuthority();
        String name = IdentifiedObjects.getName(this, authority);
        ElementKind kind = ElementKind.METHOD;
        if (name == null) {
            /*
             * No name found for the given authority. We may use the primary name as a fallback.
             * But before doing that, maybe we can find the name that we are looking for in the
             * hard-coded values in the 'org.apache.sis.internal.referencing.provider' package.
             * The typical use case is when this DefaultOperationMethod has been instantiated
             * by the EPSG factory using only the information found in the EPSG database.
             *
             * We can find the hard-coded names by looking at the ParameterDescriptorGroup of the
             * enclosing ProjectedCRS or DerivedCRS. This is because that parameter descriptor was
             * typically provided by the 'org.apache.sis.internal.referencing.provider' package in
             * order to create the MathTransform associated with the enclosing CRS.  The enclosing
             * CRS is either the immediate parent in WKT 1, or the parent of the parent in WKT 2.
             */
            final FormattableObject parent = formatter.getEnclosingElement(isWKT1 ? 1 : 2);
            if (parent instanceof GeneralDerivedCRS) {
                final Conversion conversion = ((GeneralDerivedCRS) parent).getConversionFromBase();
                if (conversion != null) {   // Should never be null, but let be safe.
                    final ParameterDescriptorGroup descriptor;
                    if (conversion instanceof Parameterized) {  // Usual case in SIS implementation.
                        descriptor = ((Parameterized) conversion).getParameterDescriptors();
                    } else {
                        descriptor = conversion.getParameterValues().getDescriptor();
                    }
                    name = IdentifiedObjects.getName(descriptor, authority);
                }
            }
            if (name == null) {
                name = IdentifiedObjects.getName(this, null);
                if (name == null) {
                    name = Vocabulary.getResources(formatter.getLocale()).getString(Vocabulary.Keys.Unnamed);
                    kind = ElementKind.NAME;  // Because the "Unnamed" string is not a real OperationMethod name.
                }
            }
        }
        formatter.append(name, kind);
        if (isWKT1) {
            /*
             * The WKT 1 keyword is "PROJECTION", which imply that the operation method should be of type
             * org.opengis.referencing.operation.Projection. So strictly speaking only the first check in
             * the following 'if' statement is relevant.
             *
             * Unfortunately in many cases we do not know the operation type, because the method that we
             * invoked - getOperationType() - is not a standard OGC/ISO property, so this information is
             * usually not provided in XML documents for example.  The user could also have instantiated
             * DirectOperationMethod directly without creating a subclass. Consequently we also accept to
             * format the keyword as "PROJECTION" if the operation type *could* be a projection. This is
             * the second check in the following 'if' statement.
             *
             * In other words, the combination of those two checks exclude the following operation types:
             * Transformation, ConcatenatedOperation, PassThroughOperation, or any user-defined type that
             * do not extend Projection. All other operation types are accepted.
             */
            final Class<? extends SingleOperation> type = getOperationType();
            if (Projection.class.isAssignableFrom(type) || type.isAssignableFrom(Projection.class)) {
                return WKTKeywords.Projection;
            }
            formatter.setInvalidWKT(this, null);
        }
        return WKTKeywords.Method;
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               XML support with JAXB                              ////////
    ////////                                                                                  ////////
    ////////        The following methods are invoked by JAXB using reflection (even if       ////////
    ////////        they are private) or are helpers for other methods invoked by JAXB.       ////////
    ////////        Those methods can be safely removed if Geographic Markup Language         ////////
    ////////        (GML) support is not needed.                                              ////////
    ////////                                                                                  ////////
    //////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Creates a new object in which every attributes are set to a null value.
     * <strong>This is not a valid object.</strong> This constructor is strictly
     * reserved to JAXB, which will assign values to the fields using reflexion.
     */
    private DefaultOperationMethod() {
        super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
    }

    /**
     * Invoked by JAXB at unmarshalling time.
     *
     * @see #getSourceDimensions()
     */
    private void setSourceDimensions(final Integer value) {
        if (sourceDimensions == null) {
            sourceDimensions = value;
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultOperationMethod.class, "setSourceDimensions", "sourceDimensions");
        }
    }

    /**
     * Invoked by JAXB at unmarshalling time.
     *
     * @see #getTargetDimensions()
     */
    private void setTargetDimensions(final Integer value) {
        if (targetDimensions == null) {
            targetDimensions = value;
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultOperationMethod.class, "setTargetDimensions", "targetDimensions");
        }
    }

    /**
     * Invoked by JAXB for marshalling a citation to the formula. In principle at most one of
     * {@code getFormulaCitation()} and {@link #getFormulaDescription()} methods can return a
     * non-null value. However SIS accepts both coexist (but this is invalid GML).
     */
    @XmlElement(name = "formulaCitation")
    private Citation getFormulaCitation() {
        final Formula formula = getFormula();   // Give to users a chance to override.
        return (formula != null) ? formula.getCitation() : null;
    }

    /**
     * Invoked by JAXB for marshalling the formula literally. In principle at most one of
     * {@code getFormulaDescription()} and {@link #getFormulaCitation()} methods can return
     * a non-null value. However SIS accepts both to coexist (but this is invalid GML).
     */
    @XmlElement(name = "formula")
    private String getFormulaDescription() {
        final Formula formula = getFormula();   // Give to users a chance to override.
        return (formula != null) ? StringAdapter.toString(formula.getFormula()) : null;
    }

    /**
     * Invoked by JAXB for setting the citation to the formula.
     */
    private void setFormulaCitation(final Citation citation) {
        if (formula == null || formula.getCitation() == null) {
            formula = (formula == null) ? new DefaultFormula(citation)
                      : new DefaultFormula(formula.getFormula(), citation);
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultOperationMethod.class, "setFormulaCitation", "formulaCitation");
        }
    }

    /**
     * Invoked by JAXB for setting the formula description.
     */
    private void setFormulaDescription(final String description) {
        if (formula == null || formula.getFormula() == null) {
            formula = (formula == null) ? new DefaultFormula(description)
                      : new DefaultFormula(new SimpleInternationalString(description), formula.getCitation());
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultOperationMethod.class, "setFormulaDescription", "formula");
        }
    }

    /**
     * Invoked by JAXB for getting the parameters to marshal. This method usually marshals the sequence of
     * descriptors without their {@link ParameterDescriptorGroup} wrapper, because GML is defined that way.
     * The {@code ParameterDescriptorGroup} wrapper is a GeoAPI addition done for allowing usage of its
     * methods as a convenience (e.g. {@link ParameterDescriptorGroup#descriptor(String)}).
     *
     * <p>However it could happen that the user really wanted to specify a {@code ParameterDescriptorGroup} as
     * the sole {@code <gml:parameter>} element. We currently have no easy way to distinguish those cases.</p>
     *
     * <div class="note"><b>Tip:</b>
     * One possible way to distinguish the two cases would be to check that the parameter group does not contain
     * any property that this method does not have:
     *
     * {@preformat java
     *   if (IdentifiedObjects.getProperties(this).entrySet().containsAll(
     *       IdentifiedObjects.getProperties(parameters).entrySet())) ...
     * }
     *
     * But we would need to make sure that {@link AbstractSingleOperation#getParameters()} is consistent
     * with the decision taken by this method.</div>
     *
     * <p><b>Historical note:</b> older, deprecated, names for the parameters were:
     * <ul>
     *   <li>{@code includesParameter}</li>
     *   <li>{@code generalOperationParameter} - note that this name was used by the EPSG registry</li>
     *   <li>{@code usesParameter}</li>
     * </ul>
     *
     * @see #getParameters()
     * @see AbstractSingleOperation#getParameters()
     */
    @XmlElement(name = "parameter")
    private GeneralParameterDescriptor[] getDescriptors() {
        if (parameters != null) {
            final List<GeneralParameterDescriptor> descriptors = parameters.descriptors();
            if (descriptors != null) {      // Paranoiac check (should not be allowed).
                return CC_OperationMethod.filterImplicit(descriptors.toArray(
                        new GeneralParameterDescriptor[descriptors.size()]));
            }
        }
        return null;
    }

    /**
     * Invoked by JAXB for setting the unmarshalled parameters.
     * This method wraps the given descriptors in a {@link DefaultParameterDescriptorGroup}.
     *
     * <p>The parameter descriptors created by this method are incomplete since we can not
     * provide a non-null value for {@link ParameterDescriptor#getValueClass()}. The value
     * class will be provided either by replacing this {@code OperationMethod} by one of the
     * pre-defined methods, or by unmarshalling the enclosing {@link AbstractSingleOperation}.</p>
     *
     * <p><b>Maintenance note:</b> the {@code "setDescriptors"} method name is also hard-coded in
     * {@link org.apache.sis.internal.jaxb.referencing.CC_GeneralOperationParameter} for logging purpose.</p>
     *
     * @see AbstractSingleOperation#setParameters
     */
    private void setDescriptors(final GeneralParameterDescriptor[] descriptors) {
        if (parameters == null) {
            parameters = CC_OperationMethod.group(super.getName(), descriptors);
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultOperationMethod.class, "setDescriptors", "parameter");
        }
    }

    /**
     * Invoked by {@link AbstractSingleOperation} for completing the parameter descriptor.
     */
    final void updateDescriptors(final GeneralParameterDescriptor[] descriptors) {
        final ParameterDescriptorGroup previous = parameters;
        parameters = new DefaultParameterDescriptorGroup(IdentifiedObjects.getProperties(previous),
                previous.getMinimumOccurs(), previous.getMaximumOccurs(), descriptors);
    }
}
