/*
 * 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.ListIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.function.Predicate;
import javax.measure.IncommensurableException;

import org.opengis.util.FactoryException;
import org.opengis.util.NoSuchIdentifierException;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.quality.PositionalAccuracy;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.operation.*;

import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.NamedIdentifier;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.referencing.AbstractIdentifiedObject;
import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
import org.apache.sis.referencing.factory.MissingFactoryResourceException;
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.internal.referencing.CoordinateOperations;
import org.apache.sis.internal.referencing.DeferredCoordinateOperation;
import org.apache.sis.internal.referencing.EllipsoidalHeightCombiner;
import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.referencing.provider.Affine;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.system.Semaphores;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Deprecable;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.collection.BackingStoreException;
import org.apache.sis.util.resources.Vocabulary;


/**
 * Base class of code that search for coordinate operation, either by looking in a registry maintained by an authority
 * or by trying to infer the coordinate operation by itself. For maintenance and testing purposes, we separate the task
 * in two classes for the two main strategies used for finding coordinate operations:
 *
 * <ul>
 *   <li>{@code CoordinateOperationRegistry} implements the <cite>late-binding</cite> approach
 *       (i.e. search coordinate operation paths specified by authorities like the ones listed
 *       in the EPSG dataset), which is the preferred approach.</li>
 *   <li>{@link CoordinateOperationFinder} adds an <cite>early-binding</cite> approach
 *       (i.e. find a coordinate operation path by inspecting the properties associated to the CRS).
 *       That approach is used only as a fallback when the late-binding approach gave no result.</li>
 * </ul>
 *
 * When <code>{@linkplain #createOperations createOperations}(sourceCRS, targetCRS)</code> is invoked,
 * this class fetches the authority codes for source and target CRS and submits them to the authority factory
 * through a call to its <code>{@linkplain GeodeticAuthorityFactory#createFromCoordinateReferenceSystemCodes
 * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method.
 * If the authority factory does not know about the specified CRS,
 * then {@link CoordinateOperationFinder} will use its own fallback.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.7
 * @module
 */
class CoordinateOperationRegistry {
    /**
     * The identifier for an identity operation.
     */
    static final Identifier IDENTITY = createIdentifier(Vocabulary.Keys.Identity);

    /**
     * The identifier for conversion using an affine transform for axis swapping and/or unit conversions.
     */
    static final Identifier AXIS_CHANGES = createIdentifier(Vocabulary.Keys.AxisChanges);

    /**
     * The identifier for a transformation which is a datum shift without
     * {@link org.apache.sis.referencing.datum.BursaWolfParameters}.
     * Only the changes in ellipsoid axis-length are taken in account.
     * Such ellipsoid shifts are approximations and may have 1 kilometre error.
     *
     * @see org.apache.sis.internal.referencing.PositionalAccuracyConstant#DATUM_SHIFT_OMITTED
     */
    static final Identifier ELLIPSOID_CHANGE = createIdentifier(Vocabulary.Keys.EllipsoidChange);

    /**
     * The identifier for a transformation which is a datum shift.
     *
     * @see org.apache.sis.internal.referencing.PositionalAccuracyConstant#DATUM_SHIFT_APPLIED
     */
    static final Identifier DATUM_SHIFT = createIdentifier(Vocabulary.Keys.DatumShift);

    /**
     * The identifier for a geocentric conversion.
     */
    static final Identifier GEOCENTRIC_CONVERSION = createIdentifier(Vocabulary.Keys.GeocentricConversion);

    /**
     * The identifier for an inverse operation.
     */
    private static final Identifier INVERSE_OPERATION = createIdentifier(Vocabulary.Keys.InverseOperation);

    /**
     * Creates an identifier in the Apache SIS namespace for the given vocabulary key.
     */
    private static Identifier createIdentifier(final short key) {
        return new NamedIdentifier(Citations.SIS, Vocabulary.formatInternational(key));
    }

    /**
     * The object to use for finding authority codes, or {@code null} if none.
     * An instance is fetched at construction time from the {@link #registry} if possible.
     */
    private final IdentifiedObjectFinder codeFinder;

    /**
     * The factory to use for creating operations as defined by authority, or {@code null} if none.
     * This is the factory used by the <cite>late-binding</cite> approach.
     */
    protected final CoordinateOperationAuthorityFactory registry;

    /**
     * The factory to use for creating coordinate operations not found in the registry.
     * This is the factory used by the <cite>early-binding</cite> approach.
     */
    protected final CoordinateOperationFactory factory;

    /**
     * Used only when we need a SIS-specific method.
     */
    final DefaultCoordinateOperationFactory factorySIS;

    /**
     * The spatiotemporal area of interest, or {@code null} if none.
     * When a new {@code CoordinateOperationFinder} instance is created with a non-null
     * {@link CoordinateOperationContext}, the context is used for initializing this value.
     * After initialization, this field may be updated as {@code CoordinateOperationFinder}
     * progresses in its search for a coordinate operation.
     *
     * @see CoordinateOperationContext#getAreaOfInterest()
     */
    protected Extent areaOfInterest;

    /**
     * The desired accuracy in metres, or 0 for the best accuracy available.
     *
     * @see CoordinateOperationContext#getDesiredAccuracy()
     */
    protected double desiredAccuracy;

    /**
     * {@code true} if {@link #search(CoordinateReferenceSystem, CoordinateReferenceSystem)}
     * should stop after the first coordinate operation found. This field is set to {@code true}
     * when the caller is interested only in the "best" operation instead of all of possibilities.
     */
    boolean stopAtFirst;

    /**
     * A filter that can be used for applying additional restrictions on the coordinate operation,
     * or {@code null} if none.
     */
    private Predicate<CoordinateOperation> filter;

    /**
     * Creates a new instance for the given factory and context.
     *
     * @param  registry  the factory to use for creating operations as defined by authority.
     * @param  factory   the factory to use for creating operations not found in the registry.
     * @param  context   the area of interest and desired accuracy, or {@code null} if none.
     * @throws FactoryException if an error occurred while initializing this {@link CoordinateOperationRegistry}.
     */
    CoordinateOperationRegistry(final CoordinateOperationAuthorityFactory registry,
                                final CoordinateOperationFactory          factory,
                                final CoordinateOperationContext          context) throws FactoryException
    {
        ArgumentChecks.ensureNonNull("factory", factory);
        this.registry = registry;
        this.factory  = factory;
        factorySIS    = (factory instanceof DefaultCoordinateOperationFactory)
                        ? (DefaultCoordinateOperationFactory) factory : CoordinateOperations.factory();
        IdentifiedObjectFinder codeFinder = null;
        if (registry != null) {
            if (registry instanceof GeodeticAuthorityFactory) {
                codeFinder = ((GeodeticAuthorityFactory) registry).newIdentifiedObjectFinder();
            } else try {
                codeFinder = IdentifiedObjects.newFinder(Citations.toCodeSpace(registry.getAuthority()));
            } catch (NoSuchAuthorityFactoryException e) {
                Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
                        CoordinateOperationRegistry.class, "<init>", e);
            }
            if (codeFinder != null) {
                codeFinder.setIgnoringAxes(true);
            }
        }
        this.codeFinder = codeFinder;
        if (context != null) {
            areaOfInterest  = context.getAreaOfInterest();
            desiredAccuracy = context.getDesiredAccuracy();
            filter          = context.getOperationFilter();
        }
    }

    /**
     * If the authority defines an object equal, ignoring metadata, to the given object, returns that authority object.
     * Otherwise returns the given object unchanged. We do not invoke this method for user-supplied CRS, but only for
     * CRS or other objects created by {@code CoordinateOperationRegistry} as intermediate step.
     */
    final <T extends IdentifiedObject> T toAuthorityDefinition(final Class<T> type, final T object) throws FactoryException {
        if (codeFinder != null) {
            codeFinder.setIgnoringAxes(false);
            final IdentifiedObject candidate = codeFinder.findSingleton(object);
            codeFinder.setIgnoringAxes(true);
            if (Utilities.equalsIgnoreMetadata(object, candidate)) {
                return type.cast(candidate);
            }
        }
        return object;
    }

    /**
     * Finds the authority codes for the given coordinate reference system.
     * This method does not trust the code given by the user in its CRS - we verify it.
     * This method may return codes even if the axis order does not match;
     * it will be caller's responsibility to make necessary adjustments.
     */
    private List<String> findCode(final CoordinateReferenceSystem crs) throws FactoryException {
        final List<String> codes = new ArrayList<>();
        if (codeFinder != null) {
            for (final IdentifiedObject candidate : codeFinder.find(crs)) {
                final Identifier identifier = IdentifiedObjects.getIdentifier(candidate, registry.getAuthority());
                if (identifier != null) {
                    final String code = identifier.getCode();
                    if (Utilities.deepEquals(candidate, crs, ComparisonMode.APPROXIMATE)) {
                        codes.add(0, code);     // If axis order match, give precedence to that CRS.
                    } else {
                        codes.add(code);
                    }
                }
            }
        }
        return codes;
    }

    /**
     * Finds or infers operations for conversions or transformations between two coordinate reference systems.
     * {@code CoordinateOperationRegistry} implements the <cite>late-binding</cite> approach (see definition
     * of terms in class javadoc) by extracting the authority codes from the supplied {@code sourceCRS} and
     * {@code targetCRS}, then by submitting those codes to the
     * <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
     * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method.
     *
     * <p>Operations in the returned list are ordered in preference order (preferred operation first).
     * If no operation is found for those codes, then this method returns an empty list.
     * Note that it does not mean that no path exist;
     * it only means that it was not defined explicitly in the registry.</p>
     *
     * @param  sourceCRS  input coordinate reference system.
     * @param  targetCRS  output coordinate reference system.
     * @return coordinate operations from {@code sourceCRS} to {@code targetCRS},
     *         or an empty list if no such operation is explicitly defined in the underlying database.
     * @throws FactoryException if the operation creation failed.
     */
    public List<CoordinateOperation> createOperations(final CoordinateReferenceSystem sourceCRS,
                                                      final CoordinateReferenceSystem targetCRS)
            throws FactoryException
    {
        CoordinateReferenceSystem source = sourceCRS;
        CoordinateReferenceSystem target = targetCRS;
        for (int combine=0; ;combine++) {
            /*
             * First, try directly the provided (sourceCRS, targetCRS) pair. If that pair does not work,
             * try to use different combinations of user-provided CRS and two-dimensional components of
             * those CRS. The code below assumes that the user-provided CRS are three-dimensional, but
             * actually it works for other kind of CRS too without testing twice the same combinations.
             */
            switch (combine) {
                case 0:  break;                                                         // 3D → 3D
                case 1:  target = CRS.getHorizontalComponent(targetCRS);                // 3D → 2D
                         if (target == targetCRS) continue;
                         break;
                case 2:  source = CRS.getHorizontalComponent(sourceCRS);                // 2D → 2D
                         if (source == sourceCRS) continue;
                         break;
                case 3:  if (source == sourceCRS || target == targetCRS) continue;
                         target = targetCRS;                                            // 2D → 3D
                         break;
                default: return Collections.emptyList();
            }
            if (source != null && target != null) try {
                final List<CoordinateOperation> operations = search(source, target);
                if (operations != null) {
                    /*
                     * Found an operation. If we had to extract the horizontal part of some 3D CRS, then we
                     * need to modify the coordinate operation in order to match the new number of dimensions.
                     */
                    if (combine != 0) {
                        for (int i=operations.size(); --i >= 0;) {
                            CoordinateOperation operation = operations.get(i);
                            operation = propagateVertical(sourceCRS, source != sourceCRS,
                                                          targetCRS, target != targetCRS, operation);
                            if (operation != null) {
                                operation = complete(operation, sourceCRS, targetCRS);
                                operations.set(i, operation);
                            } else {
                                operations.remove(i);
                            }
                        }
                    }
                    if (!operations.isEmpty()) {
                        return operations;
                    }
                }
            } catch (IllegalArgumentException | IncommensurableException e) {
                String message = Resources.format(Resources.Keys.CanNotInstantiateGeodeticObject_1, new CRSPair(sourceCRS, targetCRS));
                String details = e.getLocalizedMessage();
                if (details != null) {
                    message = message + ' ' + details;
                }
                throw new FactoryException(message, e);
            }
        }
    }

    /**
     * Returns operations for conversions or transformations between two coordinate reference systems.
     * This method extracts the authority code from the supplied {@code sourceCRS} and {@code targetCRS},
     * and submit them to the {@link #registry}. If no operation is found for those codes, then this method
     * returns {@code null}.
     *
     * @param  sourceCRS  source coordinate reference system.
     * @param  targetCRS  target coordinate reference system.
     * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}, or {@code null}
     *         if no such operation is explicitly defined in the underlying database.
     * @throws IllegalArgumentException if the coordinate systems are not of the same type or axes do not match.
     * @throws IncommensurableException if the units are not compatible or a unit conversion is non-linear.
     * @throws FactoryException if an error occurred while creating the operation.
     */
    private List<CoordinateOperation> search(final CoordinateReferenceSystem sourceCRS,
                                             final CoordinateReferenceSystem targetCRS)
            throws IllegalArgumentException, IncommensurableException, FactoryException
    {
        final List<String> sources = findCode(sourceCRS); if (sources.isEmpty()) return null;
        final List<String> targets = findCode(targetCRS); if (targets.isEmpty()) return null;
        final List<CoordinateOperation> operations = new ArrayList<>();
        boolean foundDirectOperations = false;
        boolean useDeprecatedOperations = false;
        for (final String sourceID : sources) {
            for (final String targetID : targets) {
                if (sourceID.equals(targetID)) {
                    /*
                     * Above check is necessary because this method may be invoked in some situations where the code
                     * are equal while the CRS are not. Such situation should be illegal, but unfortunately it still
                     * happen because many software products are not compliant with EPSG definition of axis order.
                     * In such cases we will need to compute a transform from sourceCRS to targetCRS ignoring the
                     * source and target codes. The CoordinateOperationFinder class can do that, providing that we
                     * prevent this CoordinateOperationRegistry to (legitimately) claims that the operation from
                     * sourceCode to targetCode is the identity transform.
                     */
                    return null;
                }
                /*
                 * Some pairs of CRS have a lot of coordinate operations backed by datum shift grids.
                 * We do not want to load all of them until we found the right coordinate operation.
                 * The non-public Semaphores.METADATA_ONLY mechanism instructs EPSGDataAccess to
                 * instantiate DeferredCoordinateOperation instead of full coordinate operations.
                 */
                final boolean mdOnly = Semaphores.queryAndSet(Semaphores.METADATA_ONLY);
                try {
                    Collection<CoordinateOperation> authoritatives;
                    try {
                        authoritatives = registry.createFromCoordinateReferenceSystemCodes(sourceID, targetID);
                        final boolean inverse = Containers.isNullOrEmpty(authoritatives);
                        if (inverse) {
                            /*
                             * No operation from 'source' to 'target' available. But maybe there is an inverse operation.
                             * This is typically the case when the user wants to convert from a projected to a geographic CRS.
                             * The EPSG database usually contains transformation paths for geographic to projected CRS only.
                             */
                            if (foundDirectOperations) {
                                continue;                       // Ignore inverse operations if we already have direct ones.
                            }
                            authoritatives = registry.createFromCoordinateReferenceSystemCodes(targetID, sourceID);
                            if (Containers.isNullOrEmpty(authoritatives)) {
                                continue;
                            }
                        } else if (!foundDirectOperations) {
                            foundDirectOperations = true;
                            operations.clear();                 // Keep only direct operations.
                        }
                    } catch (NoSuchAuthorityCodeException | MissingFactoryResourceException e) {
                        /*
                         * sourceCode or targetCode is unknown to the underlying authority factory.
                         * Ignores the exception and fallback on the generic algorithm provided by
                         * CoordinateOperationFinder.
                         */
                        log(null, e);
                        continue;
                    }
                    /*
                     * If we found at least one non-deprecated operation, we will stop the search at
                     * the first deprecated one (assuming that deprecated operations are sorted last).
                     * Deprecated operations are kept only if there is no non-deprecated operations.
                     */
                    try {
                        for (final CoordinateOperation candidate : authoritatives) {
                            if (candidate != null) {                                    // Paranoiac check.
                                if ((candidate instanceof Deprecable) && ((Deprecable) candidate).isDeprecated()) {
                                    if (!useDeprecatedOperations && !operations.isEmpty()) break;
                                    useDeprecatedOperations = true;
                                } else if (useDeprecatedOperations) {
                                    useDeprecatedOperations = false;
                                    operations.clear();              // Replace deprecated operations by non-deprecated ones.
                                }
                                operations.add(candidate);
                            }
                        }
                    } catch (BackingStoreException exception) {
                        throw exception.unwrapOrRethrow(FactoryException.class);
                    }
                } finally {
                    if (!mdOnly) {
                        Semaphores.clear(Semaphores.METADATA_ONLY);
                    }
                }
            }
        }
        /*
         * At this point we got the list of coordinate operations. Now, sort them in preference order.
         * We will loop over all coordinate operations and select the one having the largest intersection
         * with the area of interest. Note that if the user did not specified an area of interest himself,
         * then we need to get one from the CRS. This is necessary for preventing the transformation from
         * NAD27 to NAD83 in Idaho to select the transform for Alaska (since the later has a larger area).
         */
        CoordinateOperationSorter.sort(operations, Extents.getGeographicBoundingBox(areaOfInterest));
        final ListIterator<CoordinateOperation> it = operations.listIterator();
        while (it.hasNext()) {
            /*
             * At this point we filtered a CoordinateOperation by looking only at its metadata.
             * Code following this point will need the full coordinate operation, including its
             * MathTransform. So if we got a deferred operation, we need to resolve it now.
             * Conversely, we should not use metadata below this point because the call to
             * inverse(CoordinateOperation) is not guaranteed to preserve all metadata.
             */
            CoordinateOperation operation = it.next();
            try {
                if (operation instanceof DeferredCoordinateOperation) {
                    operation = ((DeferredCoordinateOperation) operation).create();
                }
                if (operation instanceof SingleOperation && operation.getMathTransform() == null) {
                    operation = fromDefiningConversion((SingleOperation) operation,
                                    foundDirectOperations ? sourceCRS : targetCRS,
                                    foundDirectOperations ? targetCRS : sourceCRS);
                    if (operation == null) {
                        it.remove();
                        continue;
                    }
                }
                if (!foundDirectOperations) {
                    operation = inverse(operation);
                }
            } catch (NoninvertibleTransformException | MissingFactoryResourceException e) {
                /*
                 * If we failed to get the real CoordinateOperation instance, remove it from
                 * the collection and try again in order to get the next best choices.
                 */
                log(null, e);
                it.remove();
                continue;                                   // Try again with the next best case.
            }
            /*
             * It is possible that the CRS given to this method were not quite right.  For example the user
             * may have created his CRS from a WKT using a different axis order than the order specified by
             * the authority and still (wrongly) call those CRS "EPSG:xxxx".  So we check if the source and
             * target CRS for the operation we just created are equivalent to the CRS specified by the user.
             *
             * NOTE: FactoryException may be thrown if we fail to create a transform from the user-provided
             * CRS to the authority-provided CRS. That transform should have been only an identity transform,
             * or a simple affine transform if the user specified wrong CRS as explained in above paragraph.
             * If we fail here, we are likely to fail for all other transforms. So we are better to let the
             * FactoryException propagate.
             */
            operation = complete(operation, sourceCRS, targetCRS);
            if (filter(operation)) {
                if (stopAtFirst) {
                    operations.clear();
                    operations.add(operation);
                    break;
                }
                it.set(operation);
            } else {
                it.remove();
            }
        }
        return operations;
    }

    /**
     * Returns {@code true} if the given operation can be accepted.
     */
    final boolean filter(final CoordinateOperation op) {
        return filter == null || filter.test(op);
    }

    /**
     * Creates the inverse of the given single operation.
     * If this operation succeed, then the returned coordinate operations has the following properties:
     *
     * <ul>
     *   <li>Its {@code sourceCRS} is the {@code targetCRS} of the given operation.</li>
     *   <li>Its {@code targetCRS} is the {@code sourceCRS} of the given operation.</li>
     *   <li>Its {@code interpolationCRS} is {@code null}.</li>
     *   <li>Its {@code MathTransform} is the
     *       {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#inverse() inverse}
     *       of the {@code MathTransform} of this operation.</li>
     *   <li>Its domain of validity and accuracy is the same.</li>
     * </ul>
     *
     * <div class="note"><b>Note:</b>
     * in many cases, the inverse operation is numerically less accurate than the direct operation because it
     * uses approximations like series expansions or iterative methods. However the numerical errors caused by
     * those approximations are not of interest here, because they are usually much smaller than the inaccuracy
     * due to the stochastic nature of coordinate transformations (not to be confused with coordinate conversions;
     * see ISO 19111 for more information).</div>
     */
    final CoordinateOperation inverse(final SingleOperation op) throws NoninvertibleTransformException, FactoryException {
        final CoordinateReferenceSystem sourceCRS = op.getSourceCRS();
        final CoordinateReferenceSystem targetCRS = op.getTargetCRS();
        final MathTransform transform = op.getMathTransform().inverse();
        final OperationMethod method = InverseOperationMethod.create(op.getMethod());
        final Map<String,Object> properties = properties(INVERSE_OPERATION);
        InverseOperationMethod.properties(op, properties);
        /*
         * Find a hint about whether the coordinate operation is a transformation or a conversion,
         * but do not set any conversion subtype. In particular, do not specify a Projection type,
         * because the inverse of a Projection does not implement the Projection interface.
         */
        Class<? extends CoordinateOperation> type = null;
        if (op instanceof Transformation)  type = Transformation.class;
        else if (op instanceof Conversion) type = Conversion.class;
        return createFromMathTransform(properties, targetCRS, sourceCRS, transform, method, null, type);
    }

    /**
     * Creates the inverse of the given operation, which may be single or compound.
     *
     * <p><b>Design note:</b>
     * we do not provide a {@code AbstractCoordinateOperation.inverse()} method. If the user wants an inverse method,
     * he should invoke {@code CRS.findOperation(targetCRS, sourceCRS, null)} or something equivalent. This is because
     * a new query of EPSG database may be necessary, and if no explicit definition is found there is too many arbitrary
     * values to set in a default inverse operation for making that API public.</p>
     *
     * @param  operation  the operation to invert, or {@code null}.
     * @return the inverse of {@code operation}, or {@code null} if none.
     * @throws NoninvertibleTransformException if the operation is not invertible.
     * @throws FactoryException if the operation creation failed for an other reason.
     */
    private CoordinateOperation inverse(final CoordinateOperation operation)
            throws NoninvertibleTransformException, FactoryException
    {
        if (SubTypes.isSingleOperation(operation)) {
            return inverse((SingleOperation) operation);
        }
        if (operation instanceof ConcatenatedOperation) {
            final List<? extends CoordinateOperation> operations = ((ConcatenatedOperation) operation).getOperations();
            final CoordinateOperation[] inverted = new CoordinateOperation[operations.size()];
            for (int i=0; i<inverted.length;) {
                final CoordinateOperation op = inverse(operations.get(i));
                if (op == null) {
                    return null;
                }
                inverted[inverted.length - ++i] = op;
            }
            return factory.createConcatenatedOperation(properties(INVERSE_OPERATION), inverted);
        }
        return null;
    }

    /**
     * Completes (if necessary) the given coordinate operation for making sure that the source CRS
     * is the given one and the target CRS is the given one.  In principle, the given CRS shall be
     * equivalent to the operation source/target CRS. However discrepancies happen if the user CRS
     * have flipped axis order, or if we looked for 2D operation while the user provided 3D CRS.
     *
     * @param  operation  the coordinate operation to complete.
     * @param  sourceCRS  the source CRS requested by the user.
     * @param  targetCRS  the target CRS requested by the user.
     * @return a coordinate operation for the given source and target CRS.
     * @throws IllegalArgumentException if the coordinate systems are not of the same type or axes do not match.
     * @throws IncommensurableException if the units are not compatible or a unit conversion is non-linear.
     * @throws FactoryException if the operation can not be constructed.
     */
    private CoordinateOperation complete(final CoordinateOperation       operation,
                                         final CoordinateReferenceSystem sourceCRS,
                                         final CoordinateReferenceSystem targetCRS)
            throws IllegalArgumentException, IncommensurableException, FactoryException
    {
        CoordinateReferenceSystem source = operation.getSourceCRS();
        CoordinateReferenceSystem target = operation.getTargetCRS();
        final MathTransformFactory mtFactory = factorySIS.getMathTransformFactory();
        final MathTransform prepend = swapAndScaleAxes(sourceCRS, source, mtFactory);
        final MathTransform append  = swapAndScaleAxes(target, targetCRS, mtFactory);
        if (prepend != null) source = sourceCRS;
        if (append  != null) target = targetCRS;
        return transform(source, prepend, operation, append, target, mtFactory);
    }

    /**
     * Returns an affine transform between two coordinate systems.
     * Only units and axes order are taken in account by this method.
     *
     * @param  sourceCRS  the source coordinate reference system.
     * @param  targetCRS  the target coordinate reference system.
     * @param  mtFactory  the math transform factory to use.
     * @return the transform from the given source to the given target CRS, or {@code null} if none is needed.
     * @throws IllegalArgumentException if the coordinate systems are not of the same type or axes do not match.
     * @throws IncommensurableException if the units are not compatible or a unit conversion is non-linear.
     * @throws FactoryException if an error occurred while creating a math transform.
     */
    private static MathTransform swapAndScaleAxes(final CoordinateReferenceSystem sourceCRS,
                                                  final CoordinateReferenceSystem targetCRS,
                                                  final MathTransformFactory      mtFactory)
            throws IllegalArgumentException, IncommensurableException, FactoryException
    {
        /*
         * Assertion: source and target CRS must be equals, ignoring change in axis order or units.
         * The first line is for disabling this check if the number of dimensions are not the same
         * (e.g. as in the "geographic 3D to geographic 2D" conversion) because ALLOW_VARIANT mode
         * still requires a matching number of dimensions.
         */
        assert ReferencingUtilities.getDimension(sourceCRS) != ReferencingUtilities.getDimension(targetCRS)
                || Utilities.deepEquals(sourceCRS, targetCRS, ComparisonMode.ALLOW_VARIANT);
        final Matrix m = CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(), targetCRS.getCoordinateSystem());
        return (m.isIdentity()) ? null : mtFactory.createAffineTransform(m);
    }

    /**
     * Appends or prepends the specified math transforms to the transform of the given operation.
     * The new coordinate operation (if any) will share the same metadata than the original operation,
     * except the authority code.
     *
     * <p>This method is used in order to change axis order when the user-specified CRS disagree
     * with the authority-supplied CRS.</p>
     *
     * @param  sourceCRS  the source CRS to give to the new operation.
     * @param  prepend    the transform to prepend to the operation math transform, or {@code null} if none.
     * @param  operation  the operation in which to prepend the math transforms.
     * @param  append     the transform to append to the operation math transform, or {@code null} if none.
     * @param  targetCRS  the target CRS to give to the new operation.
     * @param  mtFactory  the math transform factory to use.
     * @return a new operation, or {@code operation} if {@code prepend} and {@code append} were nulls or identity transforms.
     * @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
     * @throws FactoryException if the operation can not be constructed.
     */
    private CoordinateOperation transform(final CoordinateReferenceSystem sourceCRS,
                                          final MathTransform             prepend,
                                                CoordinateOperation       operation,
                                          final MathTransform             append,
                                          final CoordinateReferenceSystem targetCRS,
                                          final MathTransformFactory      mtFactory)
            throws IllegalArgumentException, FactoryException
    {
        if ((prepend == null || prepend.isIdentity()) && (append == null || append.isIdentity())) {
            return operation;
        }
        /*
         * In the particular case of concatenated operations, we can not prepend or append a math transform to
         * the operation as a whole (the math transform for a concatenated operation is computed automatically
         * as the concatenation of the transforms from every single operations, and we need to stay consistent
         * with that). Instead, prepend to the first single operation and append to the last single operation.
         */
        if (operation instanceof ConcatenatedOperation) {
            final List<? extends CoordinateOperation> c = ((ConcatenatedOperation) operation).getOperations();
            final CoordinateOperation[] op = c.toArray(new CoordinateOperation[c.size()]);
            switch (op.length) {
                case 0: break;                              // Illegal, but we are paranoiac.
                case 1: operation = op[0]; break;           // Useless ConcatenatedOperation.
                default: {
                    final int n = op.length - 1;
                    final CoordinateOperation first = op[0];
                    final CoordinateOperation last  = op[n];
                    op[0] = transform(sourceCRS, prepend, first, null, first.getTargetCRS(), mtFactory);
                    op[n] = transform(last.getSourceCRS(), null, last, append, targetCRS,    mtFactory);
                    return factory.createConcatenatedOperation(derivedFrom(operation), op);
                }
            }
        }
        /*
         * Single operation case.
         */
        MathTransform transform = operation.getMathTransform();
        if (prepend != null) transform = mtFactory.createConcatenatedTransform(prepend, transform);
        if (append  != null) transform = mtFactory.createConcatenatedTransform(transform, append);
        assert !transform.equals(operation.getMathTransform()) : transform;
        return recreate(operation, sourceCRS, targetCRS, transform, null);
    }

    /**
     * Creates a new coordinate operation with the same method than the given operation, but different CRS.
     * The CRS may differ either in the number of dimensions (i.e. let the vertical coordinate pass through),
     * or in axis order (i.e. axis order in user CRS were not compliant with authority definition).
     *
     * @param  operation  the operation specified by the authority.
     * @param  sourceCRS  the source CRS specified by the user.
     * @param  targetCRS  the target CRS specified by the user
     * @param  transform  the math transform to use in replacement to the one in {@code operation}.
     * @param  method     the operation method, or {@code null} for attempting an automatic detection.
     * @return a new operation from the given source CRS to target CRS using the given transform.
     * @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
     * @throws FactoryException if an error occurred while creating the new operation.
     */
    private CoordinateOperation recreate(final CoordinateOperation       operation,
                                               CoordinateReferenceSystem sourceCRS,
                                               CoordinateReferenceSystem targetCRS,
                                         final MathTransform             transform,
                                               OperationMethod           method)
            throws IllegalArgumentException, FactoryException
    {
        /*
         * If the user-provided CRS are approximately equal to the coordinate operation CRS, keep the later.
         * The reason is that coordinate operation CRS are built from the definitions provided by the authority,
         * while the user-provided CRS can be anything (e.g. parsed from a quite approximated WKT).
         */
        CoordinateReferenceSystem crs;
        if (Utilities.equalsApproximately(sourceCRS, crs = operation.getSourceCRS())) sourceCRS = crs;
        if (Utilities.equalsApproximately(targetCRS, crs = operation.getTargetCRS())) targetCRS = crs;
        final Map<String,Object> properties = new HashMap<>(derivedFrom(operation));
        /*
         * Determine whether the operation to create is a Conversion or a Transformation
         * (could also be a Conversion subtype like Projection, but this is less important).
         * We want the GeoAPI interface, not the implementation class.
         * The most reliable way is to ask to the 'AbstractOperation.getInterface()' method,
         * but this is SIS-specific. The fallback uses reflection.
         */
        final Class<? extends IdentifiedObject> type;
        if (operation instanceof AbstractIdentifiedObject) {
             type = ((AbstractIdentifiedObject) operation).getInterface();
        } else {
             type = Classes.getLeafInterfaces(operation.getClass(), CoordinateOperation.class)[0];
        }
        properties.put(CoordinateOperations.OPERATION_TYPE_KEY, type);
        /*
         * Reuse the same operation method, but we may need to change its number of dimension.
         * The capability to resize an OperationMethod is specific to Apache SIS, so we must
         * be prepared to see the 'redimension' call fails. In such case, we will try to get
         * the SIS implementation of the operation method and try again.
         */
        if (SubTypes.isSingleOperation(operation)) {
            final SingleOperation single = (SingleOperation) operation;
            properties.put(CoordinateOperations.PARAMETERS_KEY, single.getParameterValues());
            if (method == null) {
                final int sourceDimensions = transform.getSourceDimensions();
                final int targetDimensions = transform.getTargetDimensions();
                method = single.getMethod();
                try {
                    method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
                } catch (IllegalArgumentException ex) {
                    try {
                        method = factory.getOperationMethod(method.getName().getCode());
                        method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
                    } catch (NoSuchIdentifierException | IllegalArgumentException se) {
                        ex.addSuppressed(se);
                        throw ex;
                    }
                }
            }
        }
        return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS,
                AbstractCoordinateOperation.getInterpolationCRS(operation), method, transform);
    }

    /**
     * Creates a complete coordinate operation from a defining conversion. Defining conversions usually have
     * null source and target CRS, but this method nevertheless checks that, in order to reuse the operation
     * CRS if it happens to have some.
     *
     * @param  operation  the operation specified by the authority.
     * @param  sourceCRS  the source CRS specified by the user.
     * @param  targetCRS  the target CRS specified by the user
     * @return a new operation from the given source CRS to target CRS.
     * @throws FactoryException if an error occurred while creating the new operation.
     */
    private CoordinateOperation fromDefiningConversion(final SingleOperation     operation,
                                                       CoordinateReferenceSystem sourceCRS,
                                                       CoordinateReferenceSystem targetCRS)
            throws FactoryException
    {
        final ParameterValueGroup parameters = operation.getParameterValues();
        if (parameters != null) {
            CoordinateReferenceSystem crs;
            if (Utilities.equalsApproximately(sourceCRS, crs = operation.getSourceCRS())) sourceCRS = crs;
            if (Utilities.equalsApproximately(targetCRS, crs = operation.getTargetCRS())) targetCRS = crs;
            final MathTransformFactory mtFactory = factorySIS.getMathTransformFactory();
            if (mtFactory instanceof DefaultMathTransformFactory) {
                MathTransform mt = ((DefaultMathTransformFactory) mtFactory).createParameterizedTransform(
                        parameters, ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
                return factorySIS.createSingleOperation(IdentifiedObjects.getProperties(operation),
                        sourceCRS, targetCRS, null, operation.getMethod(), mt);
            }
        } else {
            // Should never happen because parameters are mandatory, but let be safe.
            log(Resources.forLocale(null).getLogRecord(Level.WARNING, Resources.Keys.MissingParameterValues_1,
                    IdentifiedObjects.getIdentifierOrName(operation)), null);
        }
        return null;
    }

    /**
     * Returns a new coordinate operation with the ellipsoidal height added either in the source coordinates,
     * in the target coordinates or both. If there is an ellipsoidal transform, then this method updates the
     * transforms in order to use the ellipsoidal height (it has an impact on the transformed values).
     *
     * <p>This method requires that the EPSG factory insert explicit <cite>"Geographic3D to 2D conversion"</cite>
     * operations (EPSG:9659) in the operations chain, or an equivalent operation (recognized by its matrix shape).
     * This method tries to locate and remove EPSG:9659 or equivalent operation from the operation chain in order
     * to get three-dimensional domains.</p>
     *
     * <p>This method is not guaranteed to succeed in adding the ellipsoidal height. It works on a
     * <cite>best effort</cite> basis. In any cases, the {@link #complete} method should be invoked
     * after this one in order to ensure that the source and target CRS are the expected ones.</p>
     *
     * @param  sourceCRS the potentially three-dimensional source CRS
     * @param  source3D  {@code true} for adding ellipsoidal height in source coordinates.
     * @param  targetCRS the potentially three-dimensional target CRS
     * @param  target3D  {@code true} for adding ellipsoidal height in target coordinates.
     * @param  operation the original (typically two-dimensional) coordinate operation.
     * @return a coordinate operation with the source and/or target coordinates made 3D,
     *         or {@code null} if this method does not know how to create the operation.
     * @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
     * @throws FactoryException if an error occurred while creating the coordinate operation.
     */
    private CoordinateOperation propagateVertical(final CoordinateReferenceSystem sourceCRS, final boolean source3D,
                                                  final CoordinateReferenceSystem targetCRS, final boolean target3D,
                                                  final CoordinateOperation operation)
            throws IllegalArgumentException, FactoryException
    {
        final List<CoordinateOperation> operations = new ArrayList<>();
        if (operation instanceof ConcatenatedOperation) {
            operations.addAll(((ConcatenatedOperation) operation).getOperations());
        } else {
            operations.add(operation);
        }
        if ((source3D && !propagateVertical(sourceCRS, targetCRS, operations.listIterator(), true)) ||
            (target3D && !propagateVertical(sourceCRS, targetCRS, operations.listIterator(operations.size()), false)))
        {
            return null;
        }
        switch (operations.size()) {
            case 0:  return null;
            case 1:  return operations.get(0);
            default: return factory.createConcatenatedOperation(derivedFrom(operation),
                            operations.toArray(new CoordinateOperation[operations.size()]));

        }
    }

    /**
     * Appends a vertical axis in the source CRS of the first step {@code forward = true} or in
     * the target CRS of the last step {@code forward = false} of the given operations chain.
     *
     * @param  source3D    the potentially three-dimensional source CRS
     * @param  target3D    the potentially three-dimensional target CRS
     * @param  operations  the chain of operations in which to add a vertical axis.
     * @param  forward     {@code true} for adding the vertical axis at the beginning, or
     *                     {@code false} for adding the vertical axis at the end.
     * @return {@code true} on success.
     * @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
     */
    private boolean propagateVertical(final CoordinateReferenceSystem source3D,
                                      final CoordinateReferenceSystem target3D,
                                      final ListIterator<CoordinateOperation> operations,
                                      final boolean forward)
            throws IllegalArgumentException, FactoryException
    {
        while (forward ? operations.hasNext() : operations.hasPrevious()) {
            final CoordinateOperation op = forward ? operations.next() : operations.previous();
            /*
             * We will accept to increase the number of dimensions only for operations between geographic CRS.
             * We do not increase the number of dimensions for operations between other kind of CRS because we
             * would not know which value to give to the new dimension.
             */
            CoordinateReferenceSystem sourceCRS, targetCRS;
            if ( !((sourceCRS = op.getSourceCRS()) instanceof GeodeticCRS
                && (targetCRS = op.getTargetCRS()) instanceof GeodeticCRS
                && sourceCRS.getCoordinateSystem() instanceof EllipsoidalCS
                && targetCRS.getCoordinateSystem() instanceof EllipsoidalCS))
            {
                break;
            }
            /*
             * We can process mostly linear operations, otherwise it is hard to know how to add a dimension.
             * Examples of linear operations are:
             *
             *   - Longitude rotation (EPSG:9601). Note that this is a transformation rather than a conversion.
             *   - Geographic3D to 2D conversion (EPSG:9659).
             *
             * However there is a few special cases where we may be able to add a dimension in a non-linear operation.
             * We can attempt those special cases by just giving the same parameters to the math transform factory
             * together with the desired CRS. Examples of such special cases are:
             *
             *   - Geocentric translations (geog2D domain)
             *   - Coordinate Frame Rotation (geog2D domain)
             *   - Position Vector transformation (geog2D domain)
             */
            Matrix matrix = MathTransforms.getMatrix(op.getMathTransform());
            if (matrix == null) {
                if (SubTypes.isSingleOperation(op)) {
                    final MathTransformFactory mtFactory = factorySIS.getMathTransformFactory();
                    if (mtFactory instanceof DefaultMathTransformFactory) {
                        if (forward) sourceCRS = toGeodetic3D(sourceCRS, source3D);
                        else         targetCRS = toGeodetic3D(targetCRS, target3D);
                        final MathTransform mt;
                        try {
                            mt = ((DefaultMathTransformFactory) mtFactory).createParameterizedTransform(
                                    ((SingleOperation) op).getParameterValues(),
                                    ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
                        } catch (InvalidGeodeticParameterException e) {
                            log(null, e);
                            break;
                        }
                        operations.set(recreate(op, sourceCRS, targetCRS, mt, mtFactory.getLastMethodUsed()));
                        return true;
                    }
                }
                break;
            }
            /*
             * We can process only one of the following cases:
             *
             *   - Replace a 2D → 2D operation by a 3D → 3D one (i.e. add a passthrough operation).
             *   - Usually remove (or otherwise edit) the operation that change the number of dimensions
             *     between the 2D and 3D cases.
             */
            final int numRow = matrix.getNumRow();
            final int numCol = matrix.getNumCol();
            final boolean is2D     = (numCol == 3 && numRow == 3);         // 2D → 2D operation.
            if (!(is2D || (forward ? (numCol == 3 && numRow == 4)          // 2D → 3D operation.
                                   : (numCol == 4 && numRow == 3))))       // 3D → 2D operation.
            {
                break;
            }
            matrix = Matrices.resizeAffine(matrix, 4, 4);
            if (matrix.isIdentity()) {
                operations.remove();
            } else {
                /*
                 * If we can not just remove the operation, build a new one with the expected number of dimensions.
                 * The new operation will inherit the same properties except the identifiers, since it is no longer
                 * conform to the definition provided by the authority.
                 */
                final MathTransform mt = factorySIS.getMathTransformFactory().createAffineTransform(matrix);
                operations.set(recreate(op, toGeodetic3D(sourceCRS, source3D), toGeodetic3D(targetCRS, target3D), mt, null));
            }
            /*
             * If we processed the operation that change the number of dimensions, we are done.
             */
            if (!is2D) {
                return true;
            }
        }
        return false;
    }

    /**
     * If the given CRS is two-dimensional, append an ellipsoidal height to it.
     * It is caller's responsibility to ensure that the given CRS is geographic.
     */
    private CoordinateReferenceSystem toGeodetic3D(CoordinateReferenceSystem crs,
            final CoordinateReferenceSystem candidate) throws FactoryException
    {
        assert (crs instanceof GeodeticCRS) && (crs.getCoordinateSystem() instanceof EllipsoidalCS) : crs;
        if (crs.getCoordinateSystem().getDimension() != 2) {
            return crs;
        }
        /*
         * The check for same class is a cheap way to ensure that the two CRS implement the same GeoAPI interface.
         * This test is stricter than necessary, but the result should still not wrong if we miss an opportunity
         * to return the existing instance.
         */
        if (crs.getClass() == candidate.getClass() && candidate.getCoordinateSystem().getDimension() == 3) {
            if (Utilities.equalsIgnoreMetadata(((SingleCRS) crs).getDatum(), ((SingleCRS) candidate).getDatum())) {
                return candidate;               // Keep the existing instance since it may contain useful metadata.
            }
        }
        final EllipsoidalHeightCombiner c = new EllipsoidalHeightCombiner(factorySIS.getCRSFactory(), factorySIS.getCSFactory(), factory);
        return toAuthorityDefinition(CoordinateReferenceSystem.class, c.createCompoundCRS(derivedFrom(crs), crs, CommonCRS.Vertical.ELLIPSOIDAL.crs()));
    }

    /**
     * Returns the properties of the given object, excluding the identifiers.
     * This is used for new objects derived from an object specified by the authority.
     * Since the new object is not strictly as defined by the authority, we can not keep its identifier code.
     */
    private static Map<String,?> derivedFrom(final IdentifiedObject object) {
        return IdentifiedObjects.getProperties(object, CoordinateOperation.IDENTIFIERS_KEY);
    }

    /**
     * Returns the specified identifier in a map to be given to coordinate operation constructors.
     * In the special case where the {@code name} identifier is {@link #DATUM_SHIFT} or {@link #ELLIPSOID_CHANGE},
     * the map will contain extra information like positional accuracy.
     *
     * <div class="note"><b>Note:</b>
     * in the datum shift case, an operation version is mandatory but unknown at this time.
     * However, we noticed that the EPSG database do not always defines a version neither.
     * Consequently, the Apache SIS implementation relaxes the rule requiring an operation
     * version and we do not try to provide this information here for now.</div>
     *
     * @param  name  the name to put in a map.
     * @return a modifiable map containing the given name. Callers can put other entries in this map.
     */
    static Map<String,Object> properties(final Identifier name) {
        final Map<String,Object> properties = new HashMap<>(4);
        properties.put(CoordinateOperation.NAME_KEY, name);
        if ((name == DATUM_SHIFT) || (name == ELLIPSOID_CHANGE)) {
            properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, new PositionalAccuracy[] {
                      (name == DATUM_SHIFT) ? PositionalAccuracyConstant.DATUM_SHIFT_APPLIED
                                            : PositionalAccuracyConstant.DATUM_SHIFT_OMITTED});
        }
        return properties;
    }

    /**
     * Creates a coordinate operation from a math transform.
     * The method performs the following steps:
     *
     * <ul class="verbose">
     *   <li>If the given {@code transform} is already an instance of {@code CoordinateOperation} and if its properties
     *       (operation method, source and target CRS) are compatible with the arguments values, then that operation is
     *       returned as-is.
     *
     *       <div class="note"><b>Note:</b> we do not have many objects that are both a {@code CoordinateOperation}
     *       and a {@code MathTransform}, but that combination is not forbidden. Since such practice is sometime
     *       convenient for the implementer, Apache SIS allows that.</div></li>
     *
     *   <li>If the given {@code type} is null, then this method infers the type from whether the given properties
     *       specify and accuracy or not. If those properties were created by the {@link #properties(Identifier)}
     *       method, then the operation will be a {@link Transformation} instance instead of {@link Conversion} if
     *       the {@code name} identifier was {@link #DATUM_SHIFT} or {@link #ELLIPSOID_CHANGE}.</li>
     *
     *   <li>If the given {@code method} is {@code null}, then infer an operation method by inspecting the given transform.
     *       The transform needs to implement the {@link org.apache.sis.parameter.Parameterized} interface in order to allow
     *       operation method discovery.</li>
     *
     *   <li>Delegate to {@link DefaultCoordinateOperationFactory#createSingleOperation
     *       DefaultCoordinateOperationFactory.createSingleOperation(…)}.</li>
     * </ul>
     *
     * @param  properties  the properties to give to the operation, as a modifiable map.
     * @param  sourceCRS   the source coordinate reference system.
     * @param  targetCRS   the destination coordinate reference system.
     * @param  transform   the math transform.
     * @param  method      the operation method, or {@code null} if unknown.
     * @param  parameters  the operations parameters, or {@code null} for automatic detection (not always reliable).
     * @param  type        {@code Conversion.class}, {@code Transformation.class}, or {@code null} if unknown.
     * @return a coordinate operation using the specified math transform.
     * @throws FactoryException if the operation can not be created.
     */
    final CoordinateOperation createFromMathTransform(final Map<String,Object>        properties,
                                                      final CoordinateReferenceSystem sourceCRS,
                                                      final CoordinateReferenceSystem targetCRS,
                                                      final MathTransform             transform,
                                                            OperationMethod           method,
                                                      final ParameterValueGroup       parameters,
                                                      Class<? extends CoordinateOperation> type)
            throws FactoryException
    {
        /*
         * If the specified math transform is already a coordinate operation, and if its properties (method,
         * source and target CRS) are compatible with the specified ones, then that operation is returned as-is.
         */
        if (transform instanceof CoordinateOperation) {
            final CoordinateOperation operation = (CoordinateOperation) transform;
            if (Objects.equals(operation.getSourceCRS(),     sourceCRS) &&
                Objects.equals(operation.getTargetCRS(),     targetCRS) &&
                Objects.equals(operation.getMathTransform(), transform) &&
                (method == null || !(operation instanceof SingleOperation) ||
                    Objects.equals(((SingleOperation) operation).getMethod(), method)))
            {
                return operation;
            }
        }
        /*
         * If the operation type was not explicitly specified, infers it from whether an accuracy is specified
         * or not. In principle, only transformations has an accuracy property; conversions do not. This policy
         * is applied by the properties(Identifier) method in this class.
         */
        if (type == null) {
            type = properties.containsKey(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY)
                    ? Transformation.class : Conversion.class;
        }
        /*
         * The operation method is mandatory. If the user did not provided one, we need to infer it ourselves.
         * If we fail to infer an OperationMethod, let it to null - the exception will be thrown by the factory.
         */
        if (method == null) {
            final Matrix matrix = MathTransforms.getMatrix(transform);
            if (matrix != null) {
                method = Affine.getProvider(transform.getSourceDimensions(), transform.getTargetDimensions(), Matrices.isAffine(matrix));
            } else {
                final ParameterDescriptorGroup descriptor = AbstractCoordinateOperation.getParameterDescriptors(transform);
                if (descriptor != null) {
                    final Identifier name = descriptor.getName();
                    if (name != null) {
                        method = factory.getOperationMethod(name.getCode());
                    }
                    if (method == null) {
                        method = factory.createOperationMethod(properties,
                                sourceCRS.getCoordinateSystem().getDimension(),
                                targetCRS.getCoordinateSystem().getDimension(),
                                descriptor);
                    }
                }
            }
        }
        if (parameters != null) {
            properties.put(CoordinateOperations.PARAMETERS_KEY, parameters);
        }
        properties.put(CoordinateOperations.OPERATION_TYPE_KEY, type);
        if (Conversion.class.isAssignableFrom(type) && transform.isIdentity()) {
            properties.replace(IdentifiedObject.NAME_KEY, AXIS_CHANGES, IDENTITY);
        }
        return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS, null, method, transform);
    }

    /**
     * Logs an unexpected but ignorable exception. This method pretends that the logging
     * come from {@link CoordinateOperationFinder} since this is the public API which
     * use this {@code CoordinateOperationRegistry} class.
     *
     * @param record     the record to log, or {@code null} for creating from the exception.
     * @param exception  the exception which occurred, or {@code null} if a {@code record} is specified instead.
     */
    private static void log(LogRecord record, final Exception exception) {
        if (record == null) {
            record = new LogRecord(Level.WARNING, exception.getLocalizedMessage());
        }
        record.setLoggerName(Loggers.COORDINATE_OPERATION);
        /*
         * We usually do not log the stack trace since this method should be invoked only for exceptions
         * like NoSuchAuthorityCodeException or MissingFactoryResourceException, for which the message
         * is descriptive enough. But we make a special case for NoninvertibleTransformException since
         * its cause may have deeper root.
         */
        if (exception instanceof NoninvertibleTransformException) {
            record.setThrown(exception);
        }
        Logging.log(CoordinateOperationFinder.class, "createOperations", record);
    }
}
