/*
 * 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 javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.measure.IncommensurableException;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.Datum;
import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.Utilities;


/**
 * A parameterized mathematical operation that converts coordinates to another CRS without any change of
 * {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum}.
 * The best-known example of a coordinate conversion is a map projection.
 * The parameters describing coordinate conversions are defined rather than empirically derived.
 *
 * <p>This coordinate operation contains an {@linkplain DefaultOperationMethod operation method}, usually
 * with associated {@linkplain org.apache.sis.parameter.DefaultParameterValueGroup parameter values}.
 * In the SIS implementation, the parameter values can be either inferred from the
 * {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform math transform}
 * or explicitly provided at construction time in a <cite>defining conversion</cite> (see below).</p>
 *
 * <div class="section">Defining conversions</div>
 * {@code OperationMethod} instances are generally created for a pair of existing {@linkplain #getSourceCRS() source}
 * and {@linkplain #getTargetCRS() target CRS}. But {@code Conversion} instances without those information may exist
 * temporarily while creating a {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS derived} or
 * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS projected CRS}.
 * Those <cite>defining conversions</cite> have no source and target CRS since those elements are provided by the
 * derived or projected CRS themselves. This class provides a {@linkplain #DefaultConversion(Map, OperationMethod,
 * MathTransform, ParameterValueGroup) constructor} for such defining conversions.
 *
 * <p>After the source and target CRS become known, we can invoke the {@link #specialize specialize(…)} method for
 * {@linkplain DefaultMathTransformFactory#createParameterizedTransform creating a math transform from the parameters},
 * instantiate a new {@code Conversion} of a more specific type
 * ({@link org.opengis.referencing.operation.ConicProjection},
 *  {@link org.opengis.referencing.operation.CylindricalProjection} or
 *  {@link org.opengis.referencing.operation.PlanarProjection}) if possible,
 * and assign the source and target CRS to it.</p>
 *
 * <div class="section">Immutability and thread safety</div>
 * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
 * given to the constructor are also immutable. This means that unless otherwise noted in the javadoc,
 * {@code Conversion} instances created using only SIS factories and static constants can be shared
 * by many objects and passed between threads without synchronization.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.7
 *
 * @see DefaultTransformation
 *
 * @since 0.6
 * @module
 */
@XmlType(name = "ConversionType")
@XmlRootElement(name = "Conversion")
public class DefaultConversion extends AbstractSingleOperation implements Conversion {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -2148164324805562793L;

    /**
     * Creates a coordinate conversion from the given properties.
     * The properties given in argument follow the same rules than for the
     * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
     * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) super-class constructor}.
     * The following table is a reminder of main (not all) properties:
     *
     * <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.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#IDENTIFIERS_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
     *     <td>{@link #getIdentifiers()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td>
     *     <td>{@link org.opengis.metadata.extent.Extent}</td>
     *     <td>{@link #getDomainOfValidity()}</td>
     *   </tr>
     * </table>
     *
     * <div class="section">Relationship between datum</div>
     * By definition, coordinate <b>conversions</b> do not change the datum. Consequently the given {@code sourceCRS}
     * and {@code targetCRS} should use the same datum. If the datum is not the same, then the coordinate operation
     * should probably be a {@linkplain DefaultTransformation transformation} instead.
     * However Apache SIS does not enforce that condition, but we encourage users to follow it.
     * The reason why SIS is tolerant is because some gray areas may exist about whether an operation
     * should be considered as a conversion or a transformation.
     *
     * <div class="note"><b>Example:</b>
     * converting time instants from a {@linkplain org.apache.sis.referencing.crs.DefaultTemporalCRS temporal CRS} using
     * the <cite>January 1st, 1950</cite> epoch to another temporal CRS using the <cite>January 1st, 1970</cite> epoch
     * is a datum change, since the epoch is part of {@linkplain org.apache.sis.referencing.datum.DefaultTemporalDatum
     * temporal datum} definition. However such operation does not have all the accuracy issues of transformations
     * between geodetic datum (empirically determined, over-determined systems, stochastic nature of the parameters).
     * Consequently some users may consider sufficient to represent temporal epoch changes as conversions instead
     * than transformations.</div>
     *
     * Note that while Apache SIS accepts to construct {@code DefaultConversion} instances
     * with different source and target datum, it does not accept to use such instances for
     * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS derived CRS} construction.
     *
     * @param properties        the properties to be given to the identified object.
     * @param sourceCRS         the source CRS.
     * @param targetCRS         the target CRS, which shall use a datum {@linkplain Utilities#equalsIgnoreMetadata
     *                          equals (ignoring metadata)} to the source CRS datum.
     * @param interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
     * @param method            the coordinate operation method (mandatory in all cases).
     * @param transform         transform from positions in the source CRS to positions in the target CRS.
     */
    public DefaultConversion(final Map<String,?>             properties,
                             final CoordinateReferenceSystem sourceCRS,
                             final CoordinateReferenceSystem targetCRS,
                             final CoordinateReferenceSystem interpolationCRS,
                             final OperationMethod           method,
                             final MathTransform             transform)
    {
        super(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
        ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
        ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    }

    /**
     * Creates a defining conversion from the given transform and/or parameters.
     * This conversion has no source and target CRS since those elements are usually unknown
     * at <cite>defining conversion</cite> construction time.
     * The source and target CRS will become known later, at the
     * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS Derived CRS} or
     * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected CRS}
     * construction time.
     *
     * <p>The {@code properties} map given in argument follows the same rules than for the
     * {@linkplain #DefaultConversion(Map, CoordinateReferenceSystem, CoordinateReferenceSystem,
     * CoordinateReferenceSystem, OperationMethod, MathTransform) above constructor}.</p>
     *
     * <div class="section">Transform and parameters arguments</div>
     * At least one of the {@code transform} or {@code parameters} argument must be non-null.
     * If the caller supplies a {@code transform} argument, then it shall be a transform expecting
     * {@linkplain org.apache.sis.referencing.cs.AxesConvention#NORMALIZED normalized} input coordinates
     * and producing normalized output coordinates. See {@link org.apache.sis.referencing.cs.AxesConvention}
     * for more information about what Apache SIS means by "normalized".
     *
     * <p>If the caller can not yet supply a {@code MathTransform}, then (s)he shall supply the parameter values needed
     * for creating that transform, with the possible omission of {@code "semi_major"} and {@code "semi_minor"} values.
     * The semi-major and semi-minor parameter values will be set automatically when the
     * {@link #specialize specialize(…)} method will be invoked.</p>
     *
     * <p>If both the {@code transform} and {@code parameters} arguments are non-null, then the later should describe
     * the parameters used for creating the transform. Those parameters will be stored for information purpose and can
     * be given back by the {@link #getParameterValues()} method.</p>
     *
     * @param properties  the properties to be given to the identified object.
     * @param method      the operation method.
     * @param transform   transform from positions in the source CRS to positions in the target CRS, or {@code null}.
     * @param parameters  the {@code transform} parameter values, or {@code null}.
     *
     * @see DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, DefaultMathTransformFactory.Context)
     */
    public DefaultConversion(final Map<String,?>       properties,
                             final OperationMethod     method,
                             final MathTransform       transform,
                             final ParameterValueGroup parameters)
    {
        super(properties, method);
        if (transform != null) {
            this.transform = transform;
            checkDimensions(method, 0, transform, properties);
        } else if (parameters == null) {
            throw new IllegalArgumentException(Resources.forProperties(properties)
                    .getString(Resources.Keys.UnspecifiedParameterValues));
        }
        if (parameters != null) {
            this.parameters = Parameters.unmodifiable(parameters);
        }
        checkDimensions(properties);
    }

    /**
     * Constructs a new conversion with the same values than the specified one, together with the
     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
     * typically a defining conversion.
     *
     * @param definition  the defining conversion.
     * @param source      the new source CRS.
     * @param target      the new target CRS.
     * @param factory     the factory to use for creating a transform from the parameters or for performing axis changes.
     * @param actual      an array of length 1 where to store the actual operation method used by the math transform factory.
     */
    DefaultConversion(final Conversion definition,
                      final CoordinateReferenceSystem source,
                      final CoordinateReferenceSystem target,
                      final MathTransformFactory factory,
                      final OperationMethod[] actual) throws FactoryException
    {
        super(definition);
        int interpDim = ReferencingUtilities.getDimension(super.getInterpolationCRS());
        if (transform == null) {
            /*
             * If the user did not specified explicitly a MathTransform, we will need to create it from the parameters.
             * This case happen when creating a ProjectedCRS because the length of semi-major and semi-minor axes are
             * often missing at defining conversion creation time. Since this constructor know those semi-axis lengths
             * thanks to the 'sourceCRS' argument, we can complete the parameters.
             */
            if (parameters == null) {
                throw new IllegalArgumentException(Resources.format(Resources.Keys.UnspecifiedParameterValues));
            }
            if (factory instanceof DefaultMathTransformFactory) {
                /*
                 * Apache SIS specific API (not yet defined in GeoAPI, but could be proposed).
                 * Note that setTarget(…) intentionally uses only the CoordinateSystem instead than the full
                 * CoordinateReferenceSystem because the targetCRS is typically under construction when this
                 * method in invoked, and attempts to use it can cause NullPointerException.
                 */
                final DefaultMathTransformFactory.Context context;
                if (target instanceof GeneralDerivedCRS) {
                    context = ReferencingUtilities.createTransformContext(source, null, null);
                    context.setTarget(target.getCoordinateSystem());    // Using 'target' would be unsafe here.
                } else {
                    context = ReferencingUtilities.createTransformContext(source, target, null);
                }
                transform = ((DefaultMathTransformFactory) factory).createParameterizedTransform(parameters, context);
                parameters = Parameters.unmodifiable(context.getCompletedParameters());
            } else {
                /*
                 * Fallback for non-SIS implementation. Equivalent to the above code, except that we can
                 * not get the parameters completed with semi-major and semi-minor axis lengths. Most of
                 * the code should work anyway.
                 */
                transform = factory.createBaseToDerived(source, parameters, target.getCoordinateSystem());
            }
            actual[0] = factory.getLastMethodUsed();
        } else {
            /*
             * If the user specified explicitly a MathTransform, we may still need to swap or scale axes.
             * If this conversion is a defining conversion (which is usually the case when creating a new
             * ProjectedCRS), then DefaultMathTransformFactory has a specialized createBaseToDerived(…)
             * method for this job.
             */
            if (sourceCRS == null && targetCRS == null && factory instanceof DefaultMathTransformFactory) {
                final DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
                context.setSource(source.getCoordinateSystem());
                context.setTarget(target.getCoordinateSystem());    // See comment on the other setTarget(…) call.
                transform = ((DefaultMathTransformFactory) factory).swapAndScaleAxes(transform, context);
            } else {
                /*
                 * If we can not use our SIS factory implementation, or if this conversion is not a defining
                 * conversion (i.e. if this is the conversion of an existing ProjectedCRS, in which case the
                 * math transform may not be normalized), then we fallback on a simpler swapAndScaleAxes(…)
                 * method defined in this class. This is needed for AbstractCRS.forConvention(AxisConvention).
                 */
                transform = swapAndScaleAxes(transform, source, sourceCRS, interpDim, true,  factory);
                transform = swapAndScaleAxes(transform, targetCRS, target, interpDim, false, factory);
                interpDim = 0;  // Skip createPassThroughTransform(…) since it was handled by swapAndScaleAxes(…).
            }
        }
        if (interpDim != 0) {
            transform = factory.createPassThroughTransform(interpDim, transform, 0);
        }
        sourceCRS = source;
        targetCRS = target;
    }

    /**
     * Creates a new coordinate operation 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  operation  the coordinate operation to copy.
     *
     * @see #castOrCopy(Conversion)
     */
    protected DefaultConversion(final Conversion operation) {
        super(operation);
    }

    /**
     * Returns a SIS coordinate operation implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is an instance of
     *       {@link org.opengis.referencing.operation.Conversion},
     *       {@link org.opengis.referencing.operation.Projection},
     *       {@link org.opengis.referencing.operation.CylindricalProjection},
     *       {@link org.opengis.referencing.operation.ConicProjection} or
     *       {@link org.opengis.referencing.operation.PlanarProjection},
     *       then this method delegates to the {@code castOrCopy(…)} method of the corresponding SIS subclass.
     *       Note that if the given object implements more than one of the above-cited interfaces,
     *       then the {@code castOrCopy(…)} method to be used is unspecified.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code DefaultConversion}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultConversion} instance is created using the
     *       {@linkplain #DefaultConversion(Conversion) copy constructor}
     *       and returned. Note that this is a <cite>shallow</cite> copy operation, since the other
     *       properties contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @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 DefaultConversion castOrCopy(final Conversion object) {
        return SubTypes.forConversion(object);
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The default implementation returns {@code Conversion.class}.
     * Subclasses implementing a more specific GeoAPI interface shall override this method.
     *
     * @return the conversion interface implemented by this class.
     */
    @Override
    public Class<? extends Conversion> getInterface() {
        return Conversion.class;
    }

    /**
     * Returns a specialization of this conversion with a more specific type, source and target CRS.
     * This {@code specialize(…)} method is typically invoked on {@linkplain #DefaultConversion(Map,
     * OperationMethod, MathTransform, ParameterValueGroup) defining conversion} instances,
     * when more information become available about the conversion to create.
     *
     * <p>The given {@code baseType} argument can be one of the following values:</p>
     * <ul>
     *   <li><code>{@linkplain org.opengis.referencing.operation.Conversion}.class</code></li>
     *   <li><code>{@linkplain org.opengis.referencing.operation.Projection}.class</code></li>
     *   <li><code>{@linkplain org.opengis.referencing.operation.CylindricalProjection}.class</code></li>
     *   <li><code>{@linkplain org.opengis.referencing.operation.ConicProjection}.class</code></li>
     *   <li><code>{@linkplain org.opengis.referencing.operation.PlanarProjection}.class</code></li>
     * </ul>
     *
     * This {@code specialize(…)} method returns a conversion which implement at least the given {@code baseType}
     * interface, but may also implement a more specific GeoAPI interface if {@code specialize(…)} has been able
     * to infer the type from this operation {@linkplain #getMethod() method}.
     *
     * @param  <T>        compile-time type of the {@code baseType} argument.
     * @param  baseType   the base GeoAPI interface to be implemented by the conversion to return.
     * @param  sourceCRS  the source CRS.
     * @param  targetCRS  the target CRS.
     * @param  factory    the factory to use for creating a transform from the parameters or for performing axis changes.
     * @return the conversion of the given type between the given CRS.
     * @throws ClassCastException if a contradiction is found between the given {@code baseType},
     *         the defining {@linkplain DefaultConversion#getInterface() conversion type} and
     *         the {@linkplain DefaultOperationMethod#getOperationType() method operation type}.
     * @throws MismatchedDatumException if the given CRS do not use the same datum than the source and target CRS
     *         of this conversion.
     * @throws FactoryException if the creation of a {@link MathTransform} from the {@linkplain #getParameterValues()
     *         parameter values}, or a {@linkplain CoordinateSystems#swapAndScaleAxes change of axis order or units}
     *         failed.
     *
     * @see DefaultMathTransformFactory#createParameterizedTransform(ParameterValueGroup, DefaultMathTransformFactory.Context)
     */
    public <T extends Conversion> T specialize(final Class<T> baseType,
            final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS,
            final MathTransformFactory factory) throws FactoryException
    {
        ArgumentChecks.ensureNonNull("baseType",  baseType);
        ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
        ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
        ArgumentChecks.ensureNonNull("factory",   factory);
        /*
         * Conceptual consistency check: verify that the new CRS use the same datum than the previous ones,
         * since the purpose of this method is not to apply datum changes. Datum changes are the purpose of
         * a dedicated kind of operations, namely Transformation.
         */
        ensureCompatibleDatum("sourceCRS", super.getSourceCRS(), sourceCRS);
        if (!(targetCRS instanceof GeneralDerivedCRS)) {
            ensureCompatibleDatum("targetCRS", super.getTargetCRS(), targetCRS);
        } else {
            /*
             * Special case for derived and projected CRS: we can not check directly the datum of the target CRS
             * of a derived CRS, because this method is invoked indirectly by SIS AbstractDerivedCRS constructor
             * before its 'conversionFromBase' field is set. Since the Apache SIS implementations of derived CRS
             * map the datum to getConversionFromBase().getSourceCRS().getDatum(), invoking targetCRS.getDatum()
             * below may result in a NullPointerException. Instead we verify that 'this' conversion use the same
             * datum for source and target CRS, since DerivedCRS and ProjectedCRS are expected to have the same
             * datum than their source CRS.
             */
            if (super.getTargetCRS() != null) {
                ensureCompatibleDatum("targetCRS", sourceCRS, super.getTargetCRS());
            }
        }
        return SubTypes.create(baseType, this, sourceCRS, targetCRS, factory);
    }

    /**
     * Ensures that the {@code actual} CRS uses a datum which is equals, ignoring metadata,
     * to the datum of the {@code expected} CRS.
     *
     * @param  param     the parameter name, used only in case of error.
     * @param  expected  the CRS containing the expected datum, or {@code null}.
     * @param  actual    the CRS for which to check the datum, or {@code null}.
     * @throws MismatchedDatumException if the two CRS use different datum.
     */
    private static void ensureCompatibleDatum(final String param,
            final CoordinateReferenceSystem expected,
            final CoordinateReferenceSystem actual)
    {
        if ((expected instanceof SingleCRS) && (actual instanceof SingleCRS)) {
            final Datum datum = ((SingleCRS) expected).getDatum();
            if (datum != null && !Utilities.equalsIgnoreMetadata(datum, ((SingleCRS) actual).getDatum())) {
                throw new MismatchedDatumException(Resources.format(
                        Resources.Keys.IncompatibleDatum_2, datum.getName(), param));
            }
        }
    }

    /**
     * Concatenates to the given transform the operation needed for swapping and scaling the axes.
     * The two coordinate systems must implement the same GeoAPI coordinate system interface.
     * For example if {@code sourceCRS} uses a {@code CartesianCS}, then {@code targetCRS} must use
     * a {@code CartesianCS} too.
     *
     * @param  transform  the transform to which to concatenate axis changes.
     * @param  sourceCRS  the first CRS of the pair for which to check for axes changes.
     * @param  targetCRS  the second CRS of the pair for which to check for axes changes.
     * @param  interpDim  the number of dimensions of the interpolation CRS, or 0 if none.
     * @param  isSource   {@code true} for pre-concatenating the changes, or {@code false} for post-concatenating.
     * @param  factory    the factory to use for performing axis changes.
     */
    private static MathTransform swapAndScaleAxes(MathTransform transform,
            final CoordinateReferenceSystem sourceCRS,
            final CoordinateReferenceSystem targetCRS,
            final int interpDim, final boolean isSource,
            final MathTransformFactory factory) throws FactoryException
    {
        if (sourceCRS != null && targetCRS != null && sourceCRS != targetCRS) try {
            Matrix m = CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(),
                                                          targetCRS.getCoordinateSystem());
            if (!m.isIdentity()) {
                if (interpDim != 0) {
                    m = Matrices.createPassThrough(interpDim, m, 0);
                }
                final MathTransform s = factory.createAffineTransform(m);
                transform = factory.createConcatenatedTransform(isSource ? s : transform,
                                                                isSource ? transform : s);
            }
        } catch (IncommensurableException e) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2,
                    (isSource ? "sourceCRS" : "targetCRS"),
                    (isSource ?  sourceCRS  :  targetCRS).getName()), e);
        }
        return transform;
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               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.                                              ////////
    ////////                                                                                  ////////
    //////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Constructs 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 DefaultConversion() {
    }
}
