You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2019/11/15 15:45:03 UTC

[sis] 01/04: Merge branch 'geoapi-4.0' into refactor/sql-store

This is an automated email from the ASF dual-hosted git repository.

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 15e88bbbdcc3d54977828d798f41e0e6c415065a
Merge: 71a39a3 adafeb6
Author: Alexis Manin <am...@apache.org>
AuthorDate: Thu Nov 14 15:19:41 2019 +0100

    Merge branch 'geoapi-4.0' into refactor/sql-store

 NOTICE                                             |  13 +-
 README                                             |  30 +-
 application/pom.xml                                |  17 +-
 application/sis-console/pom.xml                    |   9 +
 application/sis-console/src/main/artifact/README   |   6 +-
 application/sis-console/src/main/artifact/bin/sis  |   5 +-
 .../sis-console/src/main/artifact/lib/README       |   1 +
 .../java/org/apache/sis/console/AboutCommand.java  |   2 +-
 .../main/java/org/apache/sis/console/Command.java  |   8 +-
 .../apache/sis/console/ResourcesDownloader.java    |   2 +-
 .../org/apache/sis/console/TransformCommand.java   |   3 +-
 .../java/org/apache/sis/console/package-info.java  |   4 +-
 application/sis-javafx/doc/readme.txt              |  19 +
 application/sis-javafx/pom.xml                     |  45 +-
 .../apache/sis/gui/{Main.java => DataViewer.java}  |  89 +-
 .../org/apache/sis/gui/dataset/ExpandableList.java | 425 +++++++++
 .../apache/sis/gui/dataset/ExpandedFeature.java    | 214 +++++
 .../org/apache/sis/gui/dataset/FeatureList.java    | 340 ++++++++
 .../org/apache/sis/gui/dataset/FeatureLoader.java  | 346 ++++++++
 .../org/apache/sis/gui/dataset/FeatureTable.java   | 479 +++++++---
 .../apache/sis/gui/dataset/ResourceExplorer.java   | 135 +++
 .../org/apache/sis/gui/dataset/ResourceTree.java   | 783 +++++++++++++----
 .../org/apache/sis/gui/dataset}/package-info.java  |  19 +-
 .../sis/gui/metadata/IdentificationInfo.java       | 346 ++++++++
 .../org/apache/sis/gui/metadata/MetadataNode.java  | 228 -----
 .../apache/sis/gui/metadata/MetadataOverview.java  | 430 ---------
 .../apache/sis/gui/metadata/MetadataSummary.java   | 339 ++++++++
 .../org/apache/sis/gui/metadata/MetadataTree.java  | 332 +++++++
 .../sis/gui/metadata/RepresentationInfo.java       | 123 +++
 .../org/apache/sis/gui/metadata/ResourceView.java  | 399 ---------
 .../java/org/apache/sis/gui/metadata/Section.java  | 289 ++++++
 .../org/apache/sis/gui/metadata}/package-info.java |  16 +-
 .../java/org/apache/sis/gui}/package-info.java     |  14 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java | 459 ++++++++++
 .../org/apache/sis/gui/referencing/CRSButton.java  |  79 --
 .../org/apache/sis/gui/referencing/CRSChooser.java | 249 ++++--
 .../org/apache/sis/gui/referencing/CRSTable.java   | 349 --------
 .../java/org/apache/sis/gui/referencing/Code.java  |  94 +-
 .../org/apache/sis/gui/referencing/CodeFilter.java | 110 +++
 .../org/apache/sis/gui/referencing/WKTPane.java    | 188 +++-
 .../apache/sis/gui/referencing}/package-info.java  |  13 +-
 .../apache/sis/internal/gui/BackgroundThreads.java |  94 ++
 .../apache/sis/internal/gui/ExceptionReporter.java | 198 +++++
 .../org/apache/sis/internal/gui/FXUtilities.java   |  91 --
 .../org/apache/sis/internal/gui/FontGlyphs.java    | 143 ---
 .../sis/internal/gui/IdentityValueFactory.java     |  74 ++
 .../org/apache/sis/internal/gui/RecentChoices.java |  95 ++
 .../apache/sis/internal/gui/ResourceLoader.java    | 262 ++++++
 .../org/apache/sis/internal/gui/Resources.java     | 204 ++++-
 .../apache/sis/internal/gui/Resources.properties   |  42 +-
 .../sis/internal/gui/Resources_fr.properties       |  42 +-
 .../java/org/apache/sis/internal/gui/Styles.java   |  98 +++
 .../org/apache/sis/internal/gui/package-info.java  |   5 +-
 .../org/apache/sis/gui/referencing/CRSChooser.fxml |  30 -
 .../org/apache/sis/gui/referencing/proj_conic.png  | Bin 591 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_geo.png    | Bin 834 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_square.png | Bin 519 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_stereo.png | Bin 959 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_utm.png    | Bin 681 -> 0 bytes
 .../org/apache/sis/services/LocationServlet.java   |  13 +-
 core/pom.xml                                       |   1 +
 .../src/main/ant/prepare-release.xml               |  26 +-
 .../org/apache/sis/internal/doclet/Doclet.java     |  45 +-
 .../org/apache/sis/internal/doclet/Include.java    |   2 +-
 .../org/apache/sis/internal/doclet/Taglet.java     |  23 +-
 .../apache/sis/internal/unopkg/package-info.java   |   4 +-
 {storage/sis-xmlstore => core/sis-cql}/pom.xml     |  75 +-
 .../main/antlr4/org/apache/sis/internal/cql/CQL.g4 | 280 ++++++
 .../src/main/java/org/apache/sis/cql/CQL.java      | 752 ++++++++++++++++
 .../main/java/org/apache/sis/cql/CQLException.java |  37 +-
 .../org/apache/sis/cql/FilterToCQLVisitor.java     | 660 ++++++++++++++
 .../java/org/apache/sis/internal/cql/AntlrCQL.java |  98 +++
 .../test/java/org/apache/sis/cql/CQLTestCase.java  |  60 ++
 .../test/java/org/apache/sis/cql/CQLTestSuite.java |  33 +-
 .../org/apache/sis/cql/ExpressionReadingTest.java  | 613 +++++++++++++
 .../org/apache/sis/cql/ExpressionWritingTest.java  | 339 ++++++++
 .../java/org/apache/sis/cql/FilterReadingTest.java | 808 +++++++++++++++++
 .../java/org/apache/sis/cql/FilterWritingTest.java | 401 +++++++++
 .../java/org/apache/sis/coverage/Category.java     |   8 +-
 .../java/org/apache/sis/coverage/CategoryList.java |   8 +-
 .../coverage/IllegalSampleDimensionException.java  |  62 ++
 .../org/apache/sis/coverage/SampleDimension.java   |  13 +-
 .../org/apache/sis/coverage/SampleRangeFormat.java | 148 ++--
 .../main/java/org/apache/sis/coverage/ToNaN.java   |   6 +-
 .../org/apache/sis/coverage/grid/GridCoverage.java |   2 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |  26 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   2 +-
 .../apache/sis/coverage/grid/ImageRenderer.java    |   2 +-
 .../java/org/apache/sis/coverage/package-info.java |   2 +-
 .../apache/sis/feature/AbstractAssociation.java    |   4 +-
 .../org/apache/sis/feature/AbstractAttribute.java  |  11 +-
 .../org/apache/sis/feature/AbstractFeature.java    |  16 +-
 .../apache/sis/feature/AbstractIdentifiedType.java |   4 +-
 .../apache/sis/feature/CharacteristicTypeMap.java  |   2 +-
 .../apache/sis/feature/DefaultAssociationRole.java |   2 +-
 .../apache/sis/feature/DefaultAttributeType.java   |   8 +-
 .../org/apache/sis/feature/DefaultFeatureType.java |  10 +-
 .../org/apache/sis/feature/EnvelopeOperation.java  |   2 +-
 .../java/org/apache/sis/feature/FeatureFormat.java |   6 +-
 .../org/apache/sis/feature/FeatureOperations.java  |  10 +-
 .../main/java/org/apache/sis/feature/Features.java |  35 +
 .../apache/sis/feature/MultiValuedAssociation.java |   2 +-
 .../apache/sis/feature/MultiValuedAttribute.java   |   2 +-
 .../apache/sis/feature/SingletonAssociation.java   |   4 +-
 .../org/apache/sis/feature/SingletonAttribute.java |   4 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |   9 -
 .../apache/sis/feature/builder/TypeBuilder.java    |   2 +-
 .../java/org/apache/sis/feature/package-info.java  |   6 +-
 .../org/apache/sis/filter/AbstractFunction.java    | 141 ---
 .../org/apache/sis/filter/ArithmeticFunction.java  |  61 +-
 .../java/org/apache/sis/filter/BinaryFunction.java |  18 +-
 .../java/org/apache/sis/filter/Capabilities.java   | 437 ++++++++++
 .../org/apache/sis/filter/ComparisonFunction.java  | 503 ++++++++---
 .../apache/sis/filter/DefaultFilterFactory.java    | 317 ++++---
 .../java/org/apache/sis/filter/DefaultLike.java    | 101 +++
 .../org/apache/sis/filter/DefaultObjectId.java     |   4 +-
 .../java/org/apache/sis/filter/DefaultSortBy.java  |   4 +-
 .../org/apache/sis/filter/FilterByIdentifier.java  |   6 +-
 .../sis/filter/InvalidExpressionException.java     |  92 ++
 .../java/org/apache/sis/filter/LeafExpression.java |  59 +-
 .../org/apache/sis/filter/LogicalFunction.java     |  12 +-
 .../java/org/apache/sis/filter/NamedFunction.java  | 210 +++++
 .../src/main/java/org/apache/sis/filter/Node.java  |  20 +-
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  76 +-
 .../main/java/org/apache/sis/filter/ST_Buffer.java |  99 +++
 .../java/org/apache/sis/filter/ST_Centroid.java    |  96 ++
 .../java/org/apache/sis/filter/ST_Simplify.java    | 112 +++
 .../sis/filter/ST_SimplifyPreserveTopology.java    | 112 +++
 .../java/org/apache/sis/filter/ST_Transform.java   | 217 +++--
 .../org/apache/sis/filter/SpatialFunction.java     | 968 +++++++++++++++++++++
 .../org/apache/sis/filter/TemporalFunction.java    | 722 +++++++++++++++
 .../java/org/apache/sis/filter/UnaryFunction.java  |  12 +-
 .../java/org/apache/sis/filter/package-info.java   |  10 +-
 .../java/org/apache/sis/image/PixelIterator.java   |   7 +
 .../apache/sis/image/WritablePixelIterator.java    |  11 +-
 .../sis/internal/coverage/GridCoverage2D.java      | 117 +++
 .../sis/internal/feature/AttributeConvention.java  |   2 +-
 .../java/org/apache/sis/internal/feature/ESRI.java |  30 +-
 .../sis/internal/feature/FeatureExpression.java    |  67 +-
 .../sis/internal/feature/FunctionRegister.java     |  42 +-
 .../apache/sis/internal/feature/Geometries.java    | 226 ++++-
 .../java/org/apache/sis/internal/feature/JTS.java  | 102 ++-
 .../org/apache/sis/internal/feature/Java2D.java    |  25 +-
 .../org/apache/sis/internal/feature/Resources.java |  15 +
 .../sis/internal/feature/Resources.properties      |   3 +
 .../sis/internal/feature/Resources_fr.properties   |   3 +
 .../org/apache/sis/internal/feature/jts/JTS.java   |  59 +-
 ...rg.apache.sis.internal.feature.FunctionRegister |   1 -
 .../apache/sis/coverage/SampleRangeFormatTest.java | 137 +++
 .../apache/sis/filter/ArithmeticFunctionTest.java  |   4 +-
 .../org/apache/sis/filter/BetweenFunctionTest.java |  90 ++
 .../org/apache/sis/filter/CapabilitiesTest.java}   |  42 +-
 .../apache/sis/filter/ComparisonFunctionTest.java  | 151 ++++
 .../org/apache/sis/filter/DefaultObjectIdTest.java |   4 +-
 .../apache/sis/filter/FilterByIdentifierTest.java  |   4 +-
 .../org/apache/sis/filter/LeafExpressionTest.java  |   4 +-
 .../org/apache/sis/filter/LikeFunctionTest.java    |  42 +-
 .../org/apache/sis/filter/LogicalFunctionTest.java |   4 +-
 .../java/org/apache/sis/filter/PeriodLiteral.java  | 115 +++
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 327 +++++--
 .../org/apache/sis/filter/SpatialFunctionTest.java | 306 +++++++
 .../apache/sis/filter/TemporalFunctionTest.java    | 341 ++++++++
 .../org/apache/sis/filter/UnaryFunctionTest.java   |   4 +-
 .../sis/internal/coverage/GridCoverage2DTest.java  | 126 +++
 .../apache/sis/test/suite/FeatureTestSuite.java    |  12 +-
 core/sis-metadata/pom.xml                          |  13 +-
 .../java/org/apache/sis/internal/jaxb/Context.java |  21 +-
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |   8 +-
 .../sis/internal/jaxb/ModifiableIdentifierMap.java |   2 +-
 .../sis/internal/jaxb/PrimitiveTypeProperties.java |   6 +-
 .../apache/sis/internal/jaxb/gco/GO_DateTime.java  |   2 +-
 .../apache/sis/internal/jaxb/gco/GO_Decimal.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gco/GO_Real.java  |   2 +-
 .../jaxb/gco/InternationalStringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/PropertyType.java |  12 +-
 .../sis/internal/jaxb/gco/StringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/package-info.java |   7 +-
 .../sis/internal/jaxb/geometry/package-info.java   |   2 +-
 .../sis/internal/jaxb/gmi/LE_ProcessStep.java      |   2 +-
 .../apache/sis/internal/jaxb/gmi/LE_Source.java    |   2 +-
 .../org/apache/sis/internal/jaxb/gmi/MI_Band.java  |   2 +-
 .../internal/jaxb/gmi/MI_CoverageDescription.java  |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georectified.java     |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georeferenceable.java |   2 +-
 .../sis/internal/jaxb/gmi/MI_ImageDescription.java |   2 +-
 .../apache/sis/internal/jaxb/gmi/MI_Metadata.java  |   2 +-
 .../apache/sis/internal/jaxb/gml/GMLAdapter.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gml/Measure.java  |   2 +-
 .../jaxb/lan/LocalisedCharacterString.java         |  10 +-
 .../sis/internal/jaxb/metadata/CI_Address.java     |   2 +-
 .../sis/internal/jaxb/metadata/CI_Citation.java    |   2 +-
 .../sis/internal/jaxb/metadata/CI_Contact.java     |   2 +-
 .../apache/sis/internal/jaxb/metadata/CI_Date.java |   2 +-
 .../internal/jaxb/metadata/CI_OnlineResource.java  |   2 +-
 .../sis/internal/jaxb/metadata/CI_Party.java       |   2 +-
 .../internal/jaxb/metadata/CI_Responsibility.java  |   2 +-
 .../jaxb/metadata/CI_ResponsibleParty.java         |   2 +-
 .../sis/internal/jaxb/metadata/CI_Series.java      |   2 +-
 .../sis/internal/jaxb/metadata/CI_Telephone.java   |   2 +-
 .../sis/internal/jaxb/metadata/DQ_DataQuality.java |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Element.java     |   2 +-
 .../jaxb/metadata/DQ_PositionalAccuracy.java       |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Result.java      |   2 +-
 .../sis/internal/jaxb/metadata/EX_Extent.java      |   2 +-
 .../jaxb/metadata/EX_GeographicExtent.java         |   2 +-
 .../internal/jaxb/metadata/EX_TemporalExtent.java  |   2 +-
 .../internal/jaxb/metadata/EX_VerticalExtent.java  |   2 +-
 .../sis/internal/jaxb/metadata/LE_Algorithm.java   |   2 +-
 .../jaxb/metadata/LE_NominalResolution.java        |   2 +-
 .../jaxb/metadata/LE_ProcessStepReport.java        |   2 +-
 .../sis/internal/jaxb/metadata/LE_Processing.java  |   2 +-
 .../sis/internal/jaxb/metadata/LI_Lineage.java     |   2 +-
 .../sis/internal/jaxb/metadata/LI_ProcessStep.java |   2 +-
 .../sis/internal/jaxb/metadata/LI_Source.java      |   2 +-
 .../jaxb/metadata/MD_AggregateInformation.java     |   2 +-
 .../metadata/MD_ApplicationSchemaInformation.java  |   2 +-
 .../jaxb/metadata/MD_AssociatedResource.java       |   2 +-
 .../internal/jaxb/metadata/MD_AttributeGroup.java  |   2 +-
 .../internal/jaxb/metadata/MD_BrowseGraphic.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Constraints.java |   2 +-
 .../jaxb/metadata/MD_ContentInformation.java       |   2 +-
 .../jaxb/metadata/MD_DataIdentification.java       |   2 +-
 .../jaxb/metadata/MD_DigitalTransferOptions.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Dimension.java   |   2 +-
 .../internal/jaxb/metadata/MD_Distribution.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Distributor.java |   2 +-
 .../metadata/MD_ExtendedElementInformation.java    |   2 +-
 .../internal/jaxb/metadata/MD_FeatureTypeInfo.java |   2 +-
 .../sis/internal/jaxb/metadata/MD_Format.java      |   2 +-
 .../jaxb/metadata/MD_GeometricObjects.java         |   2 +-
 .../internal/jaxb/metadata/MD_Identification.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Identifier.java  |   2 +-
 .../internal/jaxb/metadata/MD_KeywordClass.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Keywords.java    |   2 +-
 .../jaxb/metadata/MD_MaintenanceInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Medium.java      |   2 +-
 .../sis/internal/jaxb/metadata/MD_Metadata.java    |   2 +-
 .../metadata/MD_MetadataExtensionInformation.java  |   2 +-
 .../internal/jaxb/metadata/MD_MetadataScope.java   |   2 +-
 .../metadata/MD_PortrayalCatalogueReference.java   |   2 +-
 .../internal/jaxb/metadata/MD_RangeDimension.java  |   2 +-
 .../internal/jaxb/metadata/MD_Releasability.java   |   2 +-
 .../jaxb/metadata/MD_RepresentativeFraction.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Resolution.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Scope.java       |   2 +-
 .../jaxb/metadata/MD_ScopeDescription.java         |   2 +-
 .../jaxb/metadata/MD_SpatialRepresentation.java    |   2 +-
 .../jaxb/metadata/MD_StandardOrderProcess.java     |   2 +-
 .../sis/internal/jaxb/metadata/MD_Usage.java       |   2 +-
 .../jaxb/metadata/MI_AcquisitionInformation.java   |   2 +-
 .../jaxb/metadata/MI_EnvironmentalRecord.java      |   2 +-
 .../sis/internal/jaxb/metadata/MI_Event.java       |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_GCP.java  |   2 +-
 .../jaxb/metadata/MI_GeolocationInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Instrument.java  |   2 +-
 .../sis/internal/jaxb/metadata/MI_Objective.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Operation.java   |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_Plan.java |   2 +-
 .../sis/internal/jaxb/metadata/MI_Platform.java    |   2 +-
 .../internal/jaxb/metadata/MI_PlatformPass.java    |   2 +-
 .../jaxb/metadata/MI_RangeElementDescription.java  |   2 +-
 .../internal/jaxb/metadata/MI_RequestedDate.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Requirement.java |   2 +-
 .../sis/internal/jaxb/metadata/MX_DataFile.java    |   2 +-
 .../internal/jaxb/metadata/RS_ReferenceSystem.java |  22 +-
 .../internal/jaxb/metadata/SV_CoupledResource.java |   2 +-
 .../jaxb/metadata/SV_OperationChainMetadata.java   |   2 +-
 .../jaxb/metadata/SV_OperationMetadata.java        |   2 +-
 .../sis/internal/jaxb/metadata/SV_Parameter.java   |   2 +-
 .../sis/internal/jaxb/metadata/package-info.java   |   2 +-
 .../metadata/replace/ReferenceSystemMetadata.java  |  12 +-
 .../jaxb/metadata/replace/ServiceParameter.java    |   2 +-
 .../org/apache/sis/internal/jaxb/package-info.java |   2 +-
 .../apache/sis/internal/metadata/Identifiers.java  |  20 +-
 .../apache/sis/internal/metadata/Resources.java    |  27 +
 .../sis/internal/metadata/Resources.properties     |   2 +
 .../sis/internal/metadata/Resources_fr.properties  |   2 +
 .../sis/internal/metadata/ServicesForUtility.java  |  28 +
 .../internal/metadata/TransformationAccuracy.java  |   2 +-
 .../sis/internal/metadata/sql/Initializer.java     |  22 +-
 .../sis/internal/metadata/sql/ScriptRunner.java    |  63 +-
 .../sis/internal/metadata/sql/package-info.java    |   2 +-
 .../java/org/apache/sis/internal/xml/Schemas.java  |   2 +-
 .../org/apache/sis/metadata/AbstractMetadata.java  |  19 +-
 .../org/apache/sis/metadata/MetadataCopier.java    |  41 +-
 .../org/apache/sis/metadata/MetadataFormat.java    |   2 +-
 .../org/apache/sis/metadata/MetadataStandard.java  |  18 +-
 .../org/apache/sis/metadata/MetadataVisitor.java   |   2 +-
 .../apache/sis/metadata/ModifiableMetadata.java    | 142 +--
 .../org/apache/sis/metadata/PropertyAccessor.java  |   4 +-
 .../apache/sis/metadata/PropertyInformation.java   |   2 +-
 .../java/org/apache/sis/metadata/StateChanger.java |   6 +-
 .../org/apache/sis/metadata/TreeNodeChildren.java  |   9 +-
 .../apache/sis/metadata/ValueExistencePolicy.java  |   2 +-
 .../apache/sis/metadata/iso/DefaultIdentifier.java |  13 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |   4 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |   6 +-
 .../metadata/iso/acquisition/DefaultObjective.java |   2 +-
 .../sis/metadata/iso/acquisition/package-info.java |   4 +-
 .../sis/metadata/iso/citation/Citations.java       |  98 +--
 .../sis/metadata/iso/citation/DefaultCitation.java |   6 +-
 .../metadata/iso/citation/DefaultTelephone.java    |   8 +-
 .../sis/metadata/iso/citation/package-info.java    |   6 +-
 .../iso/constraint/DefaultLegalConstraints.java    |   2 +-
 .../sis/metadata/iso/constraint/package-info.java  |   4 +-
 .../sis/metadata/iso/content/package-info.java     |   4 +-
 .../distribution/DefaultStandardOrderProcess.java  |   4 +-
 .../metadata/iso/distribution/package-info.java    |   4 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |   2 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |   7 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |   2 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |   4 +-
 .../apache/sis/metadata/iso/extent/Extents.java    |   8 +-
 .../sis/metadata/iso/extent/package-info.java      |   4 +-
 .../DefaultAggregateInformation.java               |   2 +-
 .../identification/DefaultAssociatedResource.java  |   2 +-
 .../DefaultRepresentativeFraction.java             |   4 +-
 .../iso/identification/DefaultResolution.java      |  12 +-
 .../metadata/iso/identification/package-info.java  |   4 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |   2 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |   2 +-
 .../sis/metadata/iso/lineage/package-info.java     |   4 +-
 .../iso/maintenance/DefaultScopeDescription.java   |  22 +-
 .../sis/metadata/iso/maintenance/package-info.java |   4 +-
 .../org/apache/sis/metadata/iso/package-info.java  |   6 +-
 .../metadata/iso/quality/DefaultDataQuality.java   |   2 +-
 .../iso/quality/DefaultQuantitativeResult.java     |   2 +-
 .../sis/metadata/iso/quality/package-info.java     |   4 +-
 .../metadata/iso/spatial/DefaultGeorectified.java  |   6 +-
 .../sis/metadata/iso/spatial/package-info.java     |   4 +-
 .../java/org/apache/sis/metadata/package-info.java |   8 +-
 .../apache/sis/metadata/sql/CachedStatement.java   |  33 +-
 .../org/apache/sis/metadata/sql/Dispatcher.java    |   2 +-
 .../sis/metadata/sql/IdentifierGenerator.java      |   2 +-
 .../apache/sis/metadata/sql/MetadataFallback.java  |  17 +-
 .../apache/sis/metadata/sql/MetadataSource.java    |  77 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  28 +-
 .../org/apache/sis/metadata/sql/package-info.java  |   2 +-
 .../org/apache/sis/util/iso/AbstractFactory.java   |   2 +-
 .../java/org/apache/sis/util/iso/AbstractName.java |   4 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |   2 +-
 .../apache/sis/util/iso/DefaultNameFactory.java    |   2 +-
 .../org/apache/sis/util/iso/DefaultNameSpace.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |   6 +-
 .../apache/sis/util/iso/DefaultRecordSchema.java   |   4 +-
 .../org/apache/sis/util/iso/DefaultRecordType.java |   6 +-
 .../org/apache/sis/util/iso/DefaultScopedName.java |   2 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |   4 +-
 .../org/apache/sis/util/iso/GlobalNameSpace.java   |   2 +-
 .../main/java/org/apache/sis/util/iso/Names.java   |  22 +-
 .../org/apache/sis/util/iso/RecordDefinition.java  |   4 +-
 .../main/java/org/apache/sis/util/iso/Types.java   |   2 +-
 .../java/org/apache/sis/util/iso/package-info.java |   5 +-
 .../java/org/apache/sis/xml/IdentifiedObject.java  |   2 +-
 .../java/org/apache/sis/xml/Implementation.java    |  32 +-
 .../java/org/apache/sis/xml/MarshalContext.java    |  10 +-
 .../java/org/apache/sis/xml/MarshallerPool.java    |  35 +-
 .../main/java/org/apache/sis/xml/Namespaces.java   |  24 +-
 .../main/java/org/apache/sis/xml/NilObject.java    |   2 +-
 .../main/java/org/apache/sis/xml/NilReason.java    |   4 +-
 .../apache/sis/xml/OGCNamespacePrefixMapper.java   |  79 --
 .../sis/xml/OGCNamespacePrefixMapper_Endorsed.java |  73 --
 .../src/main/java/org/apache/sis/xml/Pooled.java   |  16 +-
 .../java/org/apache/sis/xml/ReferenceResolver.java |   2 +-
 .../main/java/org/apache/sis/xml/Transformer.java  |   2 +-
 .../java/org/apache/sis/xml/ValueConverter.java    |   6 +-
 .../src/main/java/org/apache/sis/xml/XLink.java    |  20 +-
 .../src/main/java/org/apache/sis/xml/XML.java      |  42 +-
 .../main/java/org/apache/sis/xml/package-info.java |   4 +-
 .../sis/internal/jaxb/cat/EnumMarshallingTest.java |   2 +-
 .../apache/sis/metadata/MetadataCopierTest.java    |  48 +-
 .../apache/sis/metadata/MetadataStandardTest.java  |   4 +-
 .../sis/metadata/ModifiableMetadataTest.java       |  10 +-
 .../java/org/apache/sis/metadata/NameMapTest.java  |   2 +-
 .../apache/sis/metadata/TreeNodeChildrenTest.java  |   2 +-
 .../sis/metadata/iso/CustomMetadataTest.java       |   2 +-
 .../apache/sis/metadata/iso/MarshallingTest.java   |  24 +-
 .../metadata/iso/citation/DefaultCitationTest.java |  23 +-
 .../metadata/iso/citation/DefaultContactTest.java  |  20 +-
 .../metadata/iso/citation/HardCodedCitations.java  |   8 +-
 .../identification/DefaultBrowseGraphicTest.java   |  17 +-
 .../DefaultRepresentativeFractionTest.java         |   4 +-
 .../sis/metadata/xml/SchemaComplianceTest.java     |  24 +-
 .../java/org/apache/sis/test/MetadataAssert.java   |   2 +-
 .../java/org/apache/sis/test/sql/TestDatabase.java |  13 +-
 .../apache/sis/test/suite/MetadataTestSuite.java   |   1 -
 .../org/apache/sis/test/xml/PackageVerifier.java   |  10 +-
 .../org/apache/sis/test/xml/SchemaCompliance.java  |   2 +-
 .../org/apache/sis/xml/MarshallerPoolTest.java     |   2 -
 .../sis/xml/OGCNamespacePrefixMapperTest.java      | 134 ---
 core/sis-referencing-by-identifiers/pom.xml        |   4 +
 .../referencing/gazetteer/FinalLocationType.java   |  20 +-
 .../gazetteer/GeohashReferenceSystem.java          |   2 +-
 .../sis/referencing/gazetteer/LocationFormat.java  |   2 +-
 .../gazetteer/MilitaryGridReferenceSystem.java     |  12 +-
 .../gazetteer/ModifiableLocationType.java          |   4 +-
 .../gazetteer/ReferencingByIdentifiers.java        |   2 +-
 .../sis/referencing/gazetteer/package-info.java    |   2 +-
 .../referencing/gazetteer/LocationTypeTest.java    |   2 +-
 core/sis-referencing/pom.xml                       |   9 +
 .../org/apache/sis/distance/DistanceUtils.java     | 102 ---
 .../org/apache/sis/geometry/AbstractEnvelope.java  |  33 +-
 .../org/apache/sis/geometry/ArrayEnvelope.java     |   4 +-
 .../org/apache/sis/geometry/DirectPosition2D.java  |   2 +-
 .../java/org/apache/sis/geometry/Envelope2D.java   |  27 +-
 .../java/org/apache/sis/geometry/Envelopes.java    |  10 +-
 .../apache/sis/geometry/GeneralDirectPosition.java |  20 +-
 .../org/apache/sis/geometry/GeneralEnvelope.java   |  33 +-
 .../org/apache/sis/geometry/ImmutableEnvelope.java |   2 +-
 .../java/org/apache/sis/geometry/package-info.java |   8 +-
 .../internal/jaxb/referencing/CC_Conversion.java   |   2 +-
 .../jaxb/referencing/CC_CoordinateOperation.java   |   2 +-
 .../referencing/CC_GeneralOperationParameter.java  |   2 +-
 .../jaxb/referencing/CC_GeneralParameterValue.java |   2 +-
 .../jaxb/referencing/CC_OperationMethod.java       |   2 +-
 .../jaxb/referencing/CC_OperationParameter.java    |   2 +-
 .../referencing/CC_OperationParameterGroup.java    |   2 +-
 .../internal/jaxb/referencing/CD_Ellipsoid.java    |   2 +-
 .../jaxb/referencing/CD_EngineeringDatum.java      |   2 +-
 .../jaxb/referencing/CD_GeodeticDatum.java         |   2 +-
 .../internal/jaxb/referencing/CD_ImageDatum.java   |   2 +-
 .../jaxb/referencing/CD_ParametricDatum.java       |   2 +-
 .../jaxb/referencing/CD_PrimeMeridian.java         |   2 +-
 .../jaxb/referencing/CD_TemporalDatum.java         |   2 +-
 .../jaxb/referencing/CD_VerticalDatum.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_AffineCS.java |   2 +-
 .../internal/jaxb/referencing/CS_CartesianCS.java  |   2 +-
 .../jaxb/referencing/CS_CoordinateSystem.java      |   2 +-
 .../jaxb/referencing/CS_CoordinateSystemAxis.java  |   2 +-
 .../jaxb/referencing/CS_CylindricalCS.java         |   2 +-
 .../jaxb/referencing/CS_EllipsoidalCS.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_LinearCS.java |   2 +-
 .../internal/jaxb/referencing/CS_ParametricCS.java |   2 +-
 .../sis/internal/jaxb/referencing/CS_PolarCS.java  |   2 +-
 .../internal/jaxb/referencing/CS_SphericalCS.java  |   2 +-
 .../sis/internal/jaxb/referencing/CS_TimeCS.java   |   2 +-
 .../jaxb/referencing/CS_UserDefinedCS.java         |   2 +-
 .../internal/jaxb/referencing/CS_VerticalCS.java   |   2 +-
 .../apache/sis/internal/jaxb/referencing/Code.java |   4 +-
 .../internal/jaxb/referencing/RS_Identifier.java   |   4 +-
 .../sis/internal/jaxb/referencing/SC_CRS.java      |   2 +-
 .../internal/jaxb/referencing/SC_SingleCRS.java    |   4 +-
 .../internal/jaxb/referencing/SC_VerticalCRS.java  |   2 +-
 .../internal/jaxb/referencing/package-info.java    |   2 +-
 .../internal/referencing/DefinitionVerifier.java   |  10 +-
 .../sis/internal/referencing/DeprecatedCode.java   |   2 +-
 .../sis/internal/referencing/EPSGFactoryProxy.java |   7 +-
 .../apache/sis/internal/referencing/Formulas.java  |   5 +-
 .../referencing/GeodeticObjectBuilder.java         |   2 +-
 .../internal/referencing/PositionTransformer.java  |   2 +-
 .../referencing/PositionalAccuracyConstant.java    |   5 +-
 .../apache/sis/internal/referencing/Resources.java |   5 +
 .../sis/internal/referencing/Resources.properties  |   1 +
 .../internal/referencing/Resources_fr.properties   |   1 +
 .../internal/referencing/SignReversalComment.java  |   3 +
 .../sis/internal/referencing/WKTKeywords.java      |   2 +-
 .../referencing/j2d/ImmutableAffineTransform.java  |   2 +-
 .../referencing/j2d/IntervalRectangle.java         |   2 +-
 .../referencing/provider/AbstractLambert.java      |  22 +
 .../referencing/provider/AbstractMercator.java     |  22 +
 .../provider/AbstractStereographic.java            |  22 +
 .../referencing/provider/AlbersEqualArea.java      |  89 +-
 .../internal/referencing/provider/EPSGName.java    |   2 +-
 .../sis/internal/referencing/provider/ESRI.java    | 107 ++-
 .../referencing/provider/Equirectangular.java      |  64 ++
 .../provider/FranceGeocentricInterpolation.java    |  10 +
 .../referencing/provider/GeocentricAffine.java     |  63 +-
 .../GeocentricAffineBetweenGeographic.java         |  56 ++
 .../referencing/provider/Geographic2Dto3D.java     |   6 +
 .../provider/GeographicAndVerticalOffsets.java     |   6 +
 .../referencing/provider/GeographicOffsets.java    |  18 +
 .../provider/GeographicToGeocentric.java           |  12 +
 .../referencing/provider/LambertConformal1SP.java  |  37 +
 .../referencing/provider/LambertConformal2SP.java  |  75 +-
 .../provider/LambertConformalMichigan.java         |  10 +
 .../referencing/provider/LambertConformalWest.java |  11 +
 .../provider/LambertCylindricalEqualArea.java      |  48 +
 .../referencing/provider/MapProjection.java        | 149 ++--
 .../internal/referencing/provider/Mercator1SP.java |  37 +
 .../internal/referencing/provider/Mercator2SP.java |  29 +-
 .../referencing/provider/MercatorSpherical.java    |   2 +-
 .../referencing/provider/MillerCylindrical.java    |   2 +-
 .../internal/referencing/provider/Mollweide.java   |  24 +
 .../internal/referencing/provider/Molodensky.java  |  26 +-
 .../sis/internal/referencing/provider/NADCON.java  |  22 +-
 .../sis/internal/referencing/provider/NTv2.java    |  10 +
 .../referencing/provider/ObliqueMercator.java      |  93 +-
 .../provider/ObliqueMercatorCenter.java            |  20 +
 .../referencing/provider/ObliqueStereographic.java |  33 +
 .../referencing/provider/Orthographic.java         | 196 +++++
 .../referencing/provider/PolarStereographicA.java  |  37 +
 .../referencing/provider/PolarStereographicB.java  |  43 +-
 .../referencing/provider/PolarStereographicC.java  |  22 +
 .../provider/PolarStereographicSouth.java          |   4 +-
 .../internal/referencing/provider/Polyconic.java   |  44 +
 .../referencing/provider/RegionalMercator.java     |  37 +
 .../referencing/provider/SatelliteTracking.java    | 205 +++++
 .../internal/referencing/provider/Sinusoidal.java  |  24 +
 .../referencing/provider/TransverseMercator.java   |  37 +-
 .../provider/ZonedTransverseMercator.java          |  21 +
 .../referencing/provider/package-info.java         |   3 +-
 .../java/org/apache/sis/io/wkt/Convention.java     |  13 +-
 .../java/org/apache/sis/io/wkt/ElementKind.java    |   2 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   6 +-
 .../main/java/org/apache/sis/io/wkt/Formatter.java |   6 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   6 +-
 .../org/apache/sis/io/wkt/MathTransformParser.java |  23 +-
 .../main/java/org/apache/sis/io/wkt/Symbols.java   |  16 +-
 .../java/org/apache/sis/io/wkt/Transliterator.java |   6 +-
 .../sis/io/wkt/UnparsableObjectException.java      |   2 +-
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java |  49 +-
 .../java/org/apache/sis/io/wkt/package-info.java   |   8 +-
 .../sis/parameter/DefaultParameterDescriptor.java  |   4 +-
 .../parameter/DefaultParameterDescriptorGroup.java |   6 +-
 .../sis/parameter/DefaultParameterValue.java       |  18 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |   8 +-
 .../sis/parameter/MapProjectionParameters.java     |   8 +-
 .../org/apache/sis/parameter/ParameterBuilder.java |   8 +-
 .../org/apache/sis/parameter/Parameterized.java    |   4 +-
 .../java/org/apache/sis/parameter/Parameters.java  |  14 +-
 .../org/apache/sis/parameter/TensorParameters.java |  16 +-
 .../sis/parameter/UninitializedParameter.java      |   4 +-
 .../sis/parameter/UnmodifiableParameterValue.java  |   2 +-
 .../org/apache/sis/parameter/package-info.java     |   6 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |  90 +-
 .../sis/referencing/AbstractReferenceSystem.java   |   4 +-
 .../java/org/apache/sis/referencing/Builder.java   |  67 +-
 .../main/java/org/apache/sis/referencing/CRS.java  | 102 +--
 .../java/org/apache/sis/referencing/CommonCRS.java |  41 +-
 .../sis/referencing/GeodesicsOnEllipsoid.java      | 337 ++++---
 .../apache/sis/referencing/GeodeticCalculator.java | 368 +++++---
 ...odesicException.java => GeodeticException.java} |  44 +-
 .../apache/sis/referencing/IdentifiedObjects.java  | 228 +++--
 .../iso => referencing}/ImmutableIdentifier.java   |  46 +-
 .../apache/sis/referencing/NamedIdentifier.java    |   9 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |   4 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  24 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |   8 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |   6 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |   8 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  12 +-
 .../sis/referencing/crs/DefaultImageCRS.java       |   6 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |   6 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |   6 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |   6 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |   6 +-
 .../sis/referencing/crs/SC_GeographicCRS.java      |   2 +-
 .../apache/sis/referencing/crs/package-info.java   |   2 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |   8 +-
 .../apache/sis/referencing/cs/AxesConvention.java  |  15 +-
 .../org/apache/sis/referencing/cs/AxisFilter.java  |   6 +-
 .../sis/referencing/cs/CoordinateSystems.java      |  12 +-
 .../apache/sis/referencing/cs/DefaultAffineCS.java |   2 +-
 .../sis/referencing/cs/DefaultCartesianCS.java     |   6 +-
 .../sis/referencing/cs/DefaultCompoundCS.java      |   2 +-
 .../cs/DefaultCoordinateSystemAxis.java            |  14 +-
 .../sis/referencing/cs/DefaultCylindricalCS.java   |   6 +-
 .../sis/referencing/cs/DefaultEllipsoidalCS.java   |   6 +-
 .../apache/sis/referencing/cs/DefaultLinearCS.java |   6 +-
 .../sis/referencing/cs/DefaultParametricCS.java    |   6 +-
 .../apache/sis/referencing/cs/DefaultPolarCS.java  |   6 +-
 .../sis/referencing/cs/DefaultSphericalCS.java     |   6 +-
 .../apache/sis/referencing/cs/DefaultTimeCS.java   |   6 +-
 .../sis/referencing/cs/DefaultUserDefinedCS.java   |   6 +-
 .../sis/referencing/cs/DefaultVerticalCS.java      |   6 +-
 .../sis/referencing/cs/DirectionAlongMeridian.java |   4 +-
 .../sis/referencing/datum/AbstractDatum.java       |   6 +-
 .../sis/referencing/datum/BursaWolfParameters.java |  29 +-
 .../sis/referencing/datum/DatumShiftGrid.java      |  16 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    | 127 +--
 .../referencing/datum/DefaultEngineeringDatum.java |   6 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |  18 +-
 .../sis/referencing/datum/DefaultImageDatum.java   |   6 +-
 .../referencing/datum/DefaultParametricDatum.java  |   8 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |  12 +-
 .../referencing/datum/DefaultTemporalDatum.java    |   8 +-
 .../referencing/datum/DefaultVerticalDatum.java    |   8 +-
 .../org/apache/sis/referencing/datum/Sphere.java   |  30 +-
 .../sis/referencing/datum/TimeDependentBWP.java    |   2 +-
 .../apache/sis/referencing/datum/package-info.java |   5 +-
 .../factory/CommonAuthorityFactory.java            |   4 +-
 .../factory/ConcurrentAuthorityFactory.java        |  10 +-
 .../factory/GeodeticAuthorityFactory.java          | 145 +--
 .../referencing/factory/GeodeticObjectFactory.java |   6 +-
 .../factory/IdentifiedObjectFinder.java            |   4 +-
 .../referencing/factory/IdentifiedObjectSet.java   |   8 +-
 .../factory/MissingFactoryResourceException.java   |   2 +-
 .../factory/MultiAuthoritiesFactory.java           |  12 +-
 .../factory/UnavailableFactoryException.java       |   2 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    |   2 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |  75 +-
 .../sis/referencing/factory/sql/EPSGFactory.java   |   4 +-
 .../factory/sql/InstallationScriptProvider.java    |  10 +-
 .../sis/referencing/factory/sql/SQLTranslator.java |   2 +-
 .../sis/referencing/factory/sql/package-info.java  |   8 +-
 .../operation/AbstractCoordinateOperation.java     |  12 +-
 .../apache/sis/referencing/operation/CRSPair.java  |   2 +-
 .../operation/CoordinateOperationFinder.java       |   6 +-
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../operation/DefaultConcatenatedOperation.java    |   6 +-
 .../referencing/operation/DefaultConversion.java   |   8 +-
 .../operation/DefaultOperationMethod.java          |  10 +-
 .../operation/DefaultPassThroughOperation.java     |   4 +-
 .../operation/DefaultTransformation.java           |   6 +-
 .../operation/InverseOperationMethod.java          |   2 +-
 .../operation/builder/LinearTransformBuilder.java  |   2 +-
 .../operation/builder/LocalizationGridBuilder.java |   2 +-
 .../operation/builder/ResidualGrid.java            |   2 +-
 .../operation/matrix/GeneralMatrix.java            |   2 +-
 .../sis/referencing/operation/matrix/Matrices.java |  15 +-
 .../sis/referencing/operation/matrix/Matrix1.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix2.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix3.java  |  13 +-
 .../sis/referencing/operation/matrix/Matrix4.java  |  13 +-
 .../referencing/operation/matrix/MatrixSIS.java    |   9 +-
 .../sis/referencing/operation/matrix/Solver.java   |   4 +-
 .../referencing/operation/matrix/package-info.java |  10 +-
 .../sis/referencing/operation/package-info.java    |   6 +-
 .../operation/projection/AlbersEqualArea.java      |   7 +-
 .../operation/projection/ConformalProjection.java  |   6 +-
 .../operation/projection/CylindricalEqualArea.java |   2 +-
 .../operation/projection/Initializer.java          |  16 +-
 .../referencing/operation/projection/Inverter.java | 105 +++
 .../projection/LambertConicConformal.java          |   9 +-
 .../referencing/operation/projection/Mercator.java |  10 +-
 .../operation/projection/Mollweide.java            |   8 +-
 .../operation/projection/NormalizedProjection.java |  36 +-
 .../operation/projection/ObliqueMercator.java      |   6 +-
 .../operation/projection/ObliqueStereographic.java |   9 +-
 .../operation/projection/Orthographic.java         | 261 ++++++
 .../operation/projection/Polyconic.java            |   2 +-
 .../operation/projection/ProjectionException.java  |   2 +-
 .../operation/projection/SatelliteTracking.java    | 377 ++++++++
 .../operation/projection/Sinusoidal.java           |   7 +-
 .../operation/projection/TransverseMercator.java   |   2 +-
 .../operation/projection/ZonedGridSystem.java      |   2 +-
 .../operation/projection/package-info.java         |  26 +-
 .../transform/AbstractLinearTransform.java         |   6 +-
 .../operation/transform/AbstractMathTransform.java |  12 +-
 .../transform/AbstractMathTransform1D.java         |   6 +-
 .../transform/AbstractMathTransform2D.java         |   6 +-
 .../operation/transform/ConcatenatedTransform.java |   7 +-
 .../operation/transform/ContextualParameter.java   |   2 +-
 .../operation/transform/ContextualParameters.java  |  34 +-
 .../transform/CoordinateSystemTransform.java       |   2 +-
 .../operation/transform/DatumShiftTransform.java   |  35 +-
 .../transform/DefaultMathTransformFactory.java     |  12 +-
 .../transform/EllipsoidToCentricTransform.java     |   4 +-
 .../transform/ExponentialTransform1D.java          |   2 +-
 .../transform/InterpolatedGeocentricTransform.java |   4 +-
 .../transform/InterpolatedMolodenskyTransform.java |   2 +-
 .../operation/transform/InterpolatedTransform.java |  10 +-
 .../operation/transform/IterationStrategy.java     |  17 +-
 .../operation/transform/LinearInterpolator1D.java  |   2 +-
 .../operation/transform/LinearTransform.java       |  12 +-
 .../transform/LogarithmicTransform1D.java          |   2 +-
 .../operation/transform/MathTransformProvider.java |   4 +-
 .../operation/transform/MathTransforms.java        |   2 +-
 .../operation/transform/MolodenskyFormula.java     |   2 +-
 .../operation/transform/MolodenskyTransform.java   |   2 +-
 .../operation/transform/OperationMethodSet.java    |   4 +-
 .../operation/transform/PassThroughTransform.java  |  17 +-
 .../operation/transform/PowerTransform1D.java      |   2 +-
 .../transform/SpecializableTransform.java          |   2 +-
 .../operation/transform/TransferFunction.java      |   4 +-
 .../referencing/operation/transform/formulas.html  |  12 +-
 .../operation/transform/package-info.java          |   4 +-
 .../org/apache/sis/referencing/package-info.java   |   8 +-
 ...g.opengis.referencing.operation.OperationMethod |   2 +
 .../referencing/provider/Descriptions.properties   |   5 +
 .../apache/sis/distance/LatLonPointRadiusTest.java |  89 --
 .../apache/sis/geometry/CoordinateFormatTest.java  |   2 +-
 .../sis/internal/jaxb/referencing/CodeTest.java    |   2 +-
 .../internal/referencing/provider/NTv2Test.java    |   2 +-
 .../provider/ParameterNameTableGenerator.java      | 325 +++++++
 .../referencing/provider/ProvidersTest.java        |  16 +-
 .../apache/sis/io/wkt/MathTransformParserTest.java |  21 +-
 .../parameter/DefaultParameterDescriptorTest.java  |   2 +-
 .../sis/parameter/DefaultParameterValueTest.java   |   2 +-
 .../sis/parameter/ParameterValueGroupWrapper.java  |   3 +-
 .../referencing/AbstractIdentifiedObjectTest.java  |   1 -
 .../referencing/AbstractReferenceSystemTest.java   |   1 -
 .../org/apache/sis/referencing/BuilderTest.java    |   1 -
 .../java/org/apache/sis/referencing/CRSTest.java   |  16 +-
 .../apache/sis/referencing/ClenshawSummation.java  | 460 ++++++++++
 .../org/apache/sis/referencing/CommonCRSTest.java  |  14 +-
 .../sis/referencing/GeodesicsOnEllipsoidTest.java  |  97 ++-
 .../sis/referencing/GeodeticCalculatorTest.java    | 105 ++-
 .../ImmutableIdentifierTest.java                   |   2 +-
 .../referencing/crs/DefaultGeocentricCRSTest.java  |   2 +-
 .../apache/sis/referencing/cs/NormalizerTest.java  |   2 +-
 .../referencing/datum/DefaultEllipsoidTest.java    |  85 +-
 .../datum/DefaultTemporalDatumTest.java            |   2 +-
 .../referencing/factory/sql/EPSGInstallerTest.java |  13 +-
 .../factory/sql/epsg/DataScriptFormatter.java      |  10 +-
 .../epsg/{MethodDimensions.sql => DebugTools.sql}  |   8 +-
 .../sis/referencing/factory/sql/epsg/package.html  | 138 +--
 .../operation/DefaultOperationMethodTest.java      |   2 +-
 .../operation/matrix/MatrixTestCase.java           |   2 +-
 .../referencing/operation/matrix/SolverTest.java   |   2 +-
 .../projection/LambertConicConformalTest.java      |   2 +-
 .../operation/projection/OrthographicTest.java     | 162 ++++
 .../projection/SatelliteTrackingTest.java          | 407 +++++++++
 .../transform/DefaultMathTransformFactoryTest.java |   9 +-
 .../report/CoordinateReferenceSystems.java         | 487 ++++-------
 .../sis/referencing/report/package-info.java       |   2 +-
 .../sis/test/integration/ConsistencyTest.java      |   2 +-
 .../test/integration/CoordinateOperationTest.java  |  79 +-
 .../apache/sis/test/integration/MetadataTest.java  | 247 ++----
 .../sis/test/integration/MetadataVerticalTest.java | 214 +++++
 .../sis/test/suite/ReferencingTestSuite.java       |  10 +-
 .../org/apache/sis/test/widget/package-info.java   |   2 +-
 .../org/apache/sis/test/integration/Metadata.xml   |  63 +-
 .../sis/internal/converter/AngleConverter.java     |   4 +-
 .../sis/internal/converter/ArrayConverter.java     |   2 +-
 .../internal/converter/CharSequenceConverter.java  |   2 +-
 .../apache/sis/internal/converter/ClassPair.java   |   2 +-
 .../internal/converter/CollectionConverter.java    |   2 +-
 .../sis/internal/converter/ConverterRegistry.java  |  17 +-
 .../sis/internal/converter/DateConverter.java      |   6 +-
 .../sis/internal/converter/FallbackConverter.java  |   2 +-
 .../sis/internal/converter/IdentityConverter.java  |   2 +-
 .../sis/internal/converter/NumberConverter.java    |   4 +-
 .../sis/internal/converter/ObjectToString.java     |   2 +-
 .../sis/internal/converter/PathConverter.java      |   2 +-
 .../sis/internal/converter/StringConverter.java    |   6 +-
 .../sis/internal/converter/SystemConverter.java    |   7 +-
 .../sis/internal/converter/SystemRegistry.java     |   2 +-
 .../sis/internal/converter/package-info.java       |   2 +-
 .../java/org/apache/sis/internal/jdk9/JDK9.java    |  19 +-
 .../org/apache/sis/internal/jdk9/package-info.java |   2 +-
 .../apache/sis/internal/system/DaemonThread.java   |   4 +-
 .../sis/internal/system/DelayedExecutor.java       |   2 +-
 .../sis/internal/system/DelayedRunnable.java       |   8 +-
 .../org/apache/sis/internal/system/Modules.java    |  12 +-
 .../org/apache/sis/internal/system/Supervisor.java |   2 -
 .../org/apache/sis/internal/system/Threads.java    |   8 +-
 .../sis/internal/util/AutoMessageFormat.java       |   2 +-
 .../apache/sis/internal/util/CheckedArrayList.java |   2 +-
 .../apache/sis/internal/util/CollectionsExt.java   |  24 +-
 .../org/apache/sis/internal/util/Constants.java    |   2 +-
 .../apache/sis/internal/util/DefinitionURI.java    |   4 +-
 .../org/apache/sis/internal/util/DoubleDouble.java |  12 +-
 .../apache/sis/internal/util/MetadataServices.java |  25 +
 .../org/apache/sis/internal/util/Numerics.java     |   2 +-
 .../java/org/apache/sis/internal/util/Strings.java |  55 +-
 .../sis/internal/util/TemporalUtilities.java       |   2 -
 .../sis/internal/util/UnmodifiableArrayList.java   |   8 +-
 .../org/apache/sis/internal/util/package-info.java |   4 +-
 .../src/main/java/org/apache/sis/io/Appender.java  |   2 +-
 .../main/java/org/apache/sis/io/ClassFormat.java   |   4 +-
 .../java/org/apache/sis/io/CompoundFormat.java     |   6 +-
 .../main/java/org/apache/sis/io/DefaultFormat.java |   2 +-
 .../org/apache/sis/io/IdentifiedObjectFormat.java  |   2 +-
 .../main/java/org/apache/sis/io/LineAppender.java  |   2 +-
 .../main/java/org/apache/sis/io/TableAppender.java |   9 +-
 .../main/java/org/apache/sis/io/TabularFormat.java |   4 +-
 .../main/java/org/apache/sis/io/package-info.java  |   4 +-
 .../apache/sis/math/CompoundDirectPositions.java   |   2 +-
 .../java/org/apache/sis/math/DecimalFunctions.java |   6 +-
 .../java/org/apache/sis/math/MathFunctions.java    |   6 +-
 .../src/main/java/org/apache/sis/math/Plane.java   |   3 +-
 .../main/java/org/apache/sis/math/Statistics.java  |   5 +-
 .../src/main/java/org/apache/sis/math/Vector.java  |  10 +-
 .../org/apache/sis/measure/AbstractConverter.java  |   2 +-
 .../main/java/org/apache/sis/measure/Angle.java    |   6 +-
 .../java/org/apache/sis/measure/AngleFormat.java   |   1 +
 .../apache/sis/measure/ConcatenatedConverter.java  |   2 +-
 .../org/apache/sis/measure/ConventionalUnit.java   |   4 +-
 .../org/apache/sis/measure/ElevationAngle.java     |   2 +-
 .../sis/measure/FormattedCharacterIterator.java    |   4 +-
 .../org/apache/sis/measure/IdentityConverter.java  | 109 +++
 .../main/java/org/apache/sis/measure/Latitude.java |   2 +-
 .../org/apache/sis/measure/LinearConverter.java    |  49 +-
 .../java/org/apache/sis/measure/Longitude.java     |   2 +-
 .../org/apache/sis/measure/MeasurementRange.java   |   6 +-
 .../java/org/apache/sis/measure/NumberRange.java   |   8 +-
 .../main/java/org/apache/sis/measure/Range.java    |  12 +-
 .../java/org/apache/sis/measure/RangeFormat.java   |   4 +-
 .../apache/sis/measure/SexagesimalConverter.java   |   2 +-
 .../java/org/apache/sis/measure/SystemUnit.java    |   4 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  10 +-
 .../main/java/org/apache/sis/measure/Units.java    | 293 ++++---
 .../src/main/java/org/apache/sis/setup/About.java  |  21 +-
 .../java/org/apache/sis/setup/Configuration.java   | 142 +++
 .../main/java/org/apache/sis/setup/OptionKey.java  |  10 +-
 .../java/org/apache/sis/util/ArgumentChecks.java   |  27 +-
 .../main/java/org/apache/sis/util/ArraysExt.java   |   6 +-
 .../java/org/apache/sis/util/CharSequences.java    |  29 +-
 .../main/java/org/apache/sis/util/Characters.java  |   2 +-
 .../src/main/java/org/apache/sis/util/Classes.java |   2 +-
 .../java/org/apache/sis/util/ComparisonMode.java   |  28 +-
 .../java/org/apache/sis/util/Configuration.java    |   8 +-
 .../apache/sis/util/CorruptedObjectException.java  |   2 +-
 .../main/java/org/apache/sis/util/Disposable.java  |   2 +-
 .../org/apache/sis/util/LenientComparable.java     |   9 +-
 .../java/org/apache/sis/util/ObjectConverter.java  |   2 +-
 .../java/org/apache/sis/util/StringBuilders.java   |  35 +-
 .../main/java/org/apache/sis/util/Utilities.java   |  14 +-
 .../src/main/java/org/apache/sis/util/Version.java |   6 +-
 .../sis/util/collection/BackingStoreException.java |  24 +-
 .../java/org/apache/sis/util/collection/Cache.java |   6 +-
 .../apache/sis/util/collection/CacheEntries.java   |   2 +-
 .../apache/sis/util/collection/CodeListSet.java    |   4 +-
 .../sis/util/collection/DefaultTreeTable.java      |   2 +-
 .../org/apache/sis/util/collection/DerivedMap.java |   4 +-
 .../org/apache/sis/util/collection/DerivedSet.java |   4 +-
 .../org/apache/sis/util/collection/RangeSet.java   |   6 +-
 .../apache/sis/util/collection/TableColumn.java    |   2 +-
 .../apache/sis/util/collection/TreeNodeList.java   |   2 +-
 .../org/apache/sis/util/collection/TreeTable.java  |   9 +-
 .../sis/util/collection/TreeTableFormat.java       |   8 +-
 .../org/apache/sis/util/collection/TreeTables.java |   2 +-
 .../org/apache/sis/util/collection/WeakEntry.java  |  13 +-
 .../apache/sis/util/collection/WeakHashSet.java    |  11 +-
 .../sis/util/collection/WeakValueHashMap.java      |   9 +-
 .../sis/util/iso/AbstractInternationalString.java  |  10 +-
 .../sis/util/iso/DefaultInternationalString.java   |   6 +-
 .../sis/util/iso/ResourceInternationalString.java  |  12 +-
 .../sis/util/iso/SimpleInternationalString.java    |   6 +-
 .../org/apache/sis/util/logging/LoggerAdapter.java |   8 +-
 .../org/apache/sis/util/logging/LoggerFactory.java |   2 +-
 .../java/org/apache/sis/util/logging/Logging.java  |  53 +-
 .../apache/sis/util/logging/MonolineFormatter.java |  11 +-
 .../apache/sis/util/logging/PerformanceLevel.java  |   2 +-
 .../apache/sis/util/logging/WarningListener.java   |  78 --
 .../apache/sis/util/logging/WarningListeners.java  | 382 --------
 .../org/apache/sis/util/logging/package-info.java  |   6 +-
 .../java/org/apache/sis/util/resources/Errors.java |   2 +-
 .../sis/util/resources/IndexedResourceBundle.java  |  14 +-
 .../resources/ResourceInternationalString.java     |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  | 369 ++++----
 .../sis/util/resources/Vocabulary.properties       |   5 +-
 .../sis/util/resources/Vocabulary_fr.properties    |   5 +-
 .../apache/sis/util/resources/package-info.java    |   2 +-
 .../measure/FormattedCharacterIteratorTest.java    |   2 +-
 .../apache/sis/measure/LinearConverterTest.java    |  14 +-
 .../org/apache/sis/measure/QuantitiesTest.java     |  17 +
 .../org/apache/sis/test/ProjectDirectories.java    | 164 ++++
 .../test/java/org/apache/sis/test/TestCase.java    |   4 +
 .../org/apache/sis/test/TestConfiguration.java     |   9 +-
 .../test/java/org/apache/sis/test/TestSuite.java   |  35 +-
 .../java/org/apache/sis/test/package-info.java     |   4 +-
 .../apache/sis/test/suite/UtilityTestSuite.java    |   1 -
 .../sis/util/logging/EmptyWarningListeners.java    |  71 --
 .../sis/util/logging/WarningListenersTest.java     | 117 ---
 ide-project/NetBeans/build.xml                     |   1 +
 ide-project/NetBeans/nbproject/build-impl.xml      |  52 +-
 ide-project/NetBeans/nbproject/genfiles.properties |   6 +-
 ide-project/NetBeans/nbproject/project.properties  |  71 +-
 ide-project/NetBeans/nbproject/project.xml         |   5 +-
 pom.xml                                            |  84 +-
 profiles/sis-french-profile/pom.xml                |   5 +
 .../apache/sis/profile/france/package-info.java    |   2 +-
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   |   2 +-
 .../sis/internal/earth/netcdf/package-info.java    |   2 +-
 .../apache/sis/profile/japan/JapaneseProfile.java  |  25 +-
 src/main/config/logging.properties                 |   2 +-
 src/main/javadoc/overview.html                     |   4 +-
 src/main/javadoc/sis.css                           |  58 +-
 .../storage/earthobservation/LandsatReader.java    |  15 +-
 .../sis/storage/earthobservation/LandsatStore.java |  57 +-
 .../earthobservation/LandsatStoreProvider.java     |   2 +-
 .../earthobservation/LandsatReaderTest.java        |   7 +-
 .../sis/storage/earthobservation/LandsatTest.txt   |   2 +-
 .../org/apache/sis/storage/gdal/Proj4Factory.java  |   6 +-
 .../org/apache/sis/storage/gdal/package-info.java  |   4 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  52 +-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  |   2 +-
 .../sis/storage/geotiff/GridGeometryBuilder.java   |   2 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   8 +-
 .../org/apache/sis/internal/netcdf/Convention.java |  40 +-
 .../org/apache/sis/internal/netcdf/Decoder.java    |   7 +-
 .../sis/internal/netcdf/DiscreteSampling.java      |   7 +-
 .../apache/sis/internal/netcdf/NamedElement.java   |   4 +-
 .../java/org/apache/sis/internal/netcdf/Node.java  |   7 +-
 .../apache/sis/internal/netcdf/RasterResource.java |  79 +-
 .../org/apache/sis/internal/netcdf/Variable.java   |  14 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |  13 +-
 .../sis/internal/netcdf/impl/FeaturesInfo.java     |  10 +-
 .../sis/internal/netcdf/impl/VariableInfo.java     |  10 +-
 .../apache/sis/internal/netcdf/package-info.java   |   2 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  15 +-
 .../sis/internal/netcdf/ucar/FeaturesWrapper.java  |   5 +-
 .../sis/internal/netcdf/ucar/LogAdapter.java       |  11 +-
 .../sis/internal/netcdf/ucar/VariableWrapper.java  |   4 +-
 .../apache/sis/storage/netcdf/AttributeNames.java  |   3 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  |  34 +-
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |  40 +-
 .../sis/storage/netcdf/NetcdfStoreProvider.java    |  22 +-
 .../apache/sis/storage/netcdf/package-info.java    |   2 +-
 .../org/apache/sis/internal/netcdf/TestCase.java   |  11 +-
 .../internal/netcdf/impl/ChannelDecoderTest.java   |   3 +-
 .../storage/netcdf/NetcdfStoreProviderTest.java    |   9 +-
 .../apache/sis/internal/shapefile/AutoChecker.java |   4 +-
 .../internal/shapefile/ShapefileByteReader.java    |  64 +-
 .../internal/shapefile/ShapefileDescriptor.java    |   6 +-
 .../sis/storage/shapefile/InputFeatureStream.java  |   2 +-
 .../jdbc/AbstractTestBaseForInternalJDBC.java      |   2 +-
 .../sis/storage/shapefile/ShapeFileTest.java       |   4 +-
 .../apache/sis/internal/sql/feature/Analyzer.java  |   7 +-
 .../apache/sis/internal/sql/feature/Database.java  |   5 +-
 .../apache/sis/internal/sql/feature/Features.java  |   6 +-
 .../sis/internal/sql/feature/TableReference.java   |  11 +-
 .../java/org/apache/sis/storage/sql/SQLStore.java  |  41 +-
 .../apache/sis/storage/sql/SQLStoreProvider.java   |  11 +-
 .../org/apache/sis/storage/sql/package-info.java   |   2 +-
 storage/sis-storage/pom.xml                        |   5 +
 .../apache/sis/index/tree}/LatLonPointRadius.java  |  94 +-
 .../java/org/apache/sis/index/tree/QuadTree.java   |   8 +-
 .../org/apache/sis/index/tree/QuadTreeWriter.java  |   1 +
 .../sis/internal/storage/AbstractFeatureSet.java   |  22 +-
 .../sis/internal/storage/AbstractGridResource.java |  43 +-
 .../sis/internal/storage/AbstractResource.java     |  95 +-
 .../sis/internal/storage/AggregatedFeatureSet.java |  32 +-
 .../apache/sis/internal/storage/Capability.java    |  10 +-
 .../internal/storage/ConcatenatedFeatureSet.java   |  23 +-
 .../internal/storage/DocumentedStoreProvider.java  |   7 +-
 .../sis/internal/storage/JoinFeatureSet.java       |  11 +-
 .../sis/internal/storage/MemoryFeatureSet.java     |  11 +-
 .../sis/internal/storage/MetadataBuilder.java      |  30 +-
 .../sis/internal/storage/ResourceOnFileSystem.java |   2 +-
 .../org/apache/sis/internal/storage/Resources.java |  20 +
 .../sis/internal/storage/Resources.properties      |   4 +
 .../sis/internal/storage/Resources_fr.properties   |   4 +
 .../apache/sis/internal/storage/StoreMetadata.java |  15 +-
 .../apache/sis/internal/storage/URIDataStore.java  |  38 +-
 .../org/apache/sis/internal/storage/csv/Store.java |   6 +-
 .../sis/internal/storage/csv/StoreProvider.java    |  12 +-
 .../sis/internal/storage/csv/package-info.java     |   2 +-
 .../storage/folder/FolderStoreProvider.java        |   9 +-
 .../apache/sis/internal/storage/folder/Store.java  |  36 +-
 .../sis/internal/storage/io/ChannelData.java       |   2 +-
 .../sis/internal/storage/io/ChannelDataInput.java  |   4 +-
 .../sis/internal/storage/io/ChannelDataOutput.java |   4 +-
 .../sis/internal/storage/io/ChannelFactory.java    |  43 +-
 .../storage/io/ChannelImageInputStream.java        |   2 +-
 .../internal/storage/io/HyperRectangleReader.java  |  13 +-
 .../sis/internal/storage/io/IOUtilities.java       |   2 +-
 .../internal/storage/io/InputStreamAdapter.java    |   2 +-
 .../org/apache/sis/internal/storage/io/Region.java |  78 +-
 .../sis/internal/storage/io/package-info.java      |   2 +-
 .../apache/sis/internal/storage/package-info.java  |   2 +-
 .../sis/internal/storage/query/CoverageQuery.java  | 259 ++++++
 .../sis/internal/storage/query/CoverageSubset.java | 181 ++++
 .../sis/internal/storage/query/FeatureSubset.java  |  24 +-
 .../sis/internal/storage/query/SimpleQuery.java    | 167 ++--
 .../internal/storage/query/SortByComparator.java   |   4 +-
 .../sis/internal/storage/query/package-info.java   |   2 +-
 .../org/apache/sis/internal/storage/wkt/Store.java |   2 +-
 .../sis/internal/storage/wkt/StoreFormat.java      |  16 +-
 .../sis/internal/storage/xml/MimeTypeDetector.java |   2 +-
 .../org/apache/sis/internal/storage/xml/Store.java |  39 +-
 .../java/org/apache/sis/storage/Aggregate.java     |   4 +-
 .../main/java/org/apache/sis/storage/DataSet.java  |   2 +-
 .../java/org/apache/sis/storage/DataStore.java     | 135 +--
 .../org/apache/sis/storage/DataStoreException.java |   4 +-
 .../org/apache/sis/storage/DataStoreProvider.java  |  59 +-
 .../org/apache/sis/storage/DataStoreRegistry.java  |   6 +-
 .../java/org/apache/sis/storage/DataStores.java    |   2 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |   4 +-
 .../apache/sis/storage/GridCoverageResource.java   |  38 +-
 .../apache/sis/storage/IllegalNameException.java   |   2 +-
 ...NameException.java => NoSuchDataException.java} |  44 +-
 .../java/org/apache/sis/storage/ProbeResult.java   |   6 +-
 .../main/java/org/apache/sis/storage/Query.java    |   4 +-
 .../main/java/org/apache/sis/storage/Resource.java |  62 +-
 .../org/apache/sis/storage/StorageConnector.java   |  13 +-
 .../org/apache/sis/storage/WritableAggregate.java  |   2 +-
 .../sis/storage/WritableGridCoverageResource.java  |   4 +-
 .../org/apache/sis/storage/event/ChangeEvent.java  |  60 --
 .../apache/sis/storage/event/ChangeListener.java   |  54 --
 .../apache/sis/storage/event}/QuietLogRecord.java  |  14 +-
 .../org/apache/sis/storage/event/StoreEvent.java   |  91 ++
 .../apache/sis/storage/event/StoreListener.java    |  56 ++
 .../apache/sis/storage/event/StoreListeners.java   | 613 +++++++++++++
 .../org/apache/sis/storage/event/WarningEvent.java |  90 ++
 .../org/apache/sis/storage/event/package-info.java |  20 +-
 .../java/org/apache/sis/storage/package-info.java  |   2 +-
 .../internal/storage/AbstractGridResourceTest.java |   3 -
 .../java/org/apache/sis/storage/DataStoreMock.java |  45 +-
 .../sis/storage/event/StoreListenersTest.java      | 109 +++
 .../apache/sis/test/suite/StorageTestSuite.java    |   1 +
 storage/sis-xmlstore/pom.xml                       |   5 +
 .../storage/gpx/GroupAsPolylineOperation.java      |   3 +
 .../sis/internal/storage/gpx/StoreProvider.java    |  10 +-
 .../internal/storage/xml/stream/StaxDataStore.java |  31 +-
 .../internal/storage/xml/stream/StaxStreamIO.java  |   2 +-
 .../storage/xml/stream/StaxStreamReader.java       |  12 +-
 .../storage/xml/stream/StaxStreamWriter.java       |   4 +-
 991 files changed, 27940 insertions(+), 9684 deletions(-)

diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
index b8c90a3,8d27c54..3dbf6bf
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
@@@ -53,17 -33,15 +52,20 @@@ import org.opengis.filter.spatial.Withi
  import org.opengis.filter.temporal.*;
  import org.opengis.geometry.Envelope;
  import org.opengis.geometry.Geometry;
 +import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.util.FactoryException;
  import org.opengis.util.GenericName;
- 
- import org.apache.sis.geometry.GeneralEnvelope;
- import org.apache.sis.geometry.ImmutableEnvelope;
+ import org.apache.sis.internal.system.Modules;
+ import org.apache.sis.internal.system.SystemListener;
  import org.apache.sis.internal.feature.FunctionRegister;
+ import org.apache.sis.internal.feature.Resources;
  import org.apache.sis.referencing.CRS;
  import org.apache.sis.util.collection.BackingStoreException;
 -import org.opengis.util.FactoryException;
 +
++import org.apache.sis.geometry.GeneralEnvelope;
++import org.apache.sis.geometry.ImmutableEnvelope;
+ 
  
  /**
   * Default implementation of GeoAPI filter factory for creation of {@link Filter} and {@link Expression} instances.
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
index cc40a87,22783ba..1846bc2
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
@@@ -19,54 -19,17 +19,58 @@@
   * Filters features according their properties.
   * A <cite>filter expression</cite> is a construct used to constraint a feature set to a subset.
   *
 + * All operations in this package try to follow rules of both following standards:
 + * <ul>
 + *     <li><a href="https://www.iso.org/fr/standard/53698.html">ISO/IEC 13249-3:2011 - SQLMM</a></li>
 + *     <li><a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter Encoding 2.0 Encoding Standard</a></li>
 + * </ul>
 + *
 + * <div class="section">General considerations:</div>
 + * <div class="section">Coordinate reference system handling:</div>
 + * As stated by Filter encoding 2.0.2, section 7.8.4, heterogeneous coordinate reference systems must be handled by
 + * libraries, one way or another. The standard does not define any strategy. As Apache-SIS contains a powerful
 + * transform system, we'll try to handle differences in the following way:
 + * <ul>
 + *     <li>
 + *         If all evaluated geometries define a srid, but their not the same, we'll try to project them in a common
 + *         space. The strategy will be guided by {@link org.apache.sis.referencing.CRS#suggestCommonTarget(org.opengis.metadata.extent.GeographicBoundingBox, org.opengis.referencing.crs.CoordinateReferenceSystem...) Referencing utility method}.
 + *         If it cannot provide a common space, we will fail any ongoing operation.
 + *     </li>
 + *     <li>
 + *         Missing information:
 + *         <ul>
 + *              <li>If no geometry contains any srid, consider they're defined in the same space, and proceed</li>
 + *              <li>If one geometry define a CRS but the other do not, consider that an ambiguity resides: fail.</li>
 + *         </ul>
 + *     </li>
 + * </ul>
 + *
 + * <div class="section">Optimisations</div>
 + * For now, few to no optimisation is done in the operators. Most of important ones would require one of the two
 + * following things:
 + * <ul>
 + *     <li>
 + *         Context information: Filters does not know in advance the feature type they're operating upon, which is
 + *         vital to define some calculus parameters, as property value conversion strategy, spatial system changes, etc.
 + *         Such information would allow operators to prepare data at initialisation time.
 + *     </li>
 + *     <li>
 + *         User hints: some operations could be set faster at the cost of precision. To activate such things, it would
 + *         require user consent. Most naïve example is spatial reference system conversion, which could be de-activated
 + *         for systems with nearly equal parameters (see {@link org.apache.sis.util.Utilities#equalsApproximately(java.lang.Object, java.lang.Object)}.
 + *     </li>
 + * </ul>
-  * extra-information for
-  * the operator, as well as hints from the user to allow sac
++ *
++ * <div class="section">Thread-safety</div>
+  * <p>All filter and expression implementations provided by Apache SIS are thread-safe.
+  * They are not necessarily stateless however; for example a filter may remember which
+  * warnings have been reported in order to avoid to report the same warning twice.</p>
+  *
   * @author  Johann Sorel (Geomatys)
   * @author  Martin Desruisseaux (Geomatys)
-  * @version 1.0
+  * @version 1.1
   *
 - * @see <a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter Encoding 2.0 Encoding Standard</a>
 - *
 - * @since 1.1
 + * @since 1.0
   * @module
   */
  package org.apache.sis.filter;
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
index cca1b26,f32b4f9..47486eb
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
@@@ -16,19 -16,25 +16,33 @@@
   */
  package org.apache.sis.internal.feature;
  
 +import java.nio.ByteBuffer;
  import java.util.Iterator;
 +import java.util.stream.Stream;
 +
+ import com.esri.core.geometry.Geometry;
+ import com.esri.core.geometry.Envelope2D;
+ import com.esri.core.geometry.MultiPath;
+ import com.esri.core.geometry.Polyline;
+ import com.esri.core.geometry.Polygon;
+ import com.esri.core.geometry.Point;
+ import com.esri.core.geometry.Point2D;
+ import com.esri.core.geometry.Point3D;
+ import com.esri.core.geometry.WktImportFlags;
+ import com.esri.core.geometry.WktExportFlags;
+ import com.esri.core.geometry.OperatorImportFromWkt;
+ import com.esri.core.geometry.OperatorExportToWkt;
+ import com.esri.core.geometry.OperatorCentroid2D;
++
  import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.util.Classes;
  
 +import com.esri.core.geometry.*;
 +
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Centralizes some usages of ESRI geometry API by Apache SIS.
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index 46881bf,f92634a..fa6856d
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@@ -17,27 -17,20 +17,33 @@@
  package org.apache.sis.internal.feature;
  
  import java.util.Iterator;
 +import java.util.Optional;
 +import java.util.function.Function;
  import java.util.logging.Level;
  import java.util.logging.LogRecord;
 +import java.util.stream.Stream;
 +
 +import org.opengis.geometry.DirectPosition;
 +import org.opengis.geometry.Envelope;
 +import org.opengis.geometry.Geometry;
 +import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.referencing.crs.SingleCRS;
 +import org.opengis.referencing.cs.CoordinateSystemAxis;
+ import org.opengis.util.FactoryException;
+ import org.opengis.referencing.operation.TransformException;
+ import org.opengis.referencing.operation.CoordinateOperation;
 -import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +
 +import org.apache.sis.geometry.GeneralEnvelope;
 +import org.apache.sis.internal.referencing.AxisDirections;
  import org.apache.sis.internal.system.Loggers;
 +import org.apache.sis.math.Vector;
 +import org.apache.sis.referencing.CRS;
 +import org.apache.sis.setup.GeometryLibrary;
 +import org.apache.sis.util.collection.BackingStoreException;
  import org.apache.sis.util.logging.Logging;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.UnsupportedImplementationException;
+ import org.apache.sis.util.Classes;
 -import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
 -import org.apache.sis.math.Vector;
  
  
  /**
@@@ -159,19 -166,35 +179,48 @@@ public abstract class Geometries<G> 
      }
  
      /**
 +     * Transforms an envelope to a polygon whose start point is lower corner, and points composing result are the
 +     * envelope corners in clockwise order.
 +     * @param env The envelope to convert.
 +     * @param wraparound How to resolve wrap-around ambiguities on the envelope.
 +     * @return If any geometric implementation is installed, return a polygon (or two polygons in case of
 +     * {@link WrapResolution#SPLIT split handling of wrap-around}.
 +     */
 +    public static Optional<Geometry> toGeometry(final Envelope env, WrapResolution wraparound) {
 +        return findStrategy(g -> g.tryConvertToGeometry(env, wraparound))
 +                .map(result -> new GeometryWrapper(result, env));
 +    }
 +
 +    /**
+      * If the given geometry is an implementation of this library, returns its coordinate reference system.
+      * Otherwise returns {@code null}. The default implementation returns {@code null} because only a few
+      * geometry implementations can store CRS information.
+      *
+      * @see #tryTransform(Object, CoordinateOperation, CoordinateReferenceSystem)
+      */
+     CoordinateReferenceSystem tryGetCoordinateReferenceSystem(Object point) throws FactoryException {
+         return null;
+     }
+ 
+     /**
+      * Gets the Coordinate Reference System (CRS) from the given geometry. If no CRS information is found or
+      * if the geometry implementation can not store this information, then this method returns {@code null}.
+      *
+      * @param  geometry the geometry from which to get the CRS, or {@code null}.
+      * @return the coordinate reference system, or {@code null}.
+      * @throws FactoryException if the CRS is defined by a SRID code and that code can not be used.
+      *
+      * @see #transform(Object, CoordinateReferenceSystem)
+      */
+     public static CoordinateReferenceSystem getCoordinateReferenceSystem(final Object geometry) throws FactoryException {
+         for (Geometries<?> g = implementation; g != null; g = g.fallback) {
+             CoordinateReferenceSystem crs = g.tryGetCoordinateReferenceSystem(geometry);
+             if (crs != null) return crs;
+         }
+         return null;
+     }
+ 
+     /**
       * If the given point is an implementation of this library, returns its coordinate.
       * Otherwise returns {@code null}.
       */
@@@ -351,8 -379,18 +425,8 @@@
          while (paths.hasNext()) {
              final Object first = paths.next();
              if (first != null) {
 -                for (Geometries<?> g = implementation; g != null; g = g.fallback) {
 -                    final Object merged = g.tryMergePolylines(first, paths);
 -                    if (merged != null) {
 -                        return merged;
 -                    }
 -                }
 -                /*
 -                 * Use the same exception type than `tryMergePolylines(…)` implementations.
 -                 * Also the same type than exception occurring elsewhere in the code of the
 -                 * caller (GroupAsPolylineOperation).
 -                 */
 -                throw new ClassCastException(unsupportedImplementation(first));
 +                return findStrategy(g -> g.tryMergePolylines(first, paths))
-                         .orElseThrow(() -> unsupported(2));
++                        .orElseThrow(() -> new ClassCastException(unsupportedImplementation(first)));
              }
          }
          return null;
@@@ -363,156 -534,16 +570,165 @@@
       *
       * @param  dimension  number of dimensions (2 or 3) requested for the geometry object.
       */
-     static UnsupportedOperationException unsupported(final int dimension) {
-         return new UnsupportedOperationException(Resources.format(Resources.Keys.UnsupportedGeometryObject_1, dimension));
+     static String unsupported(final int dimension) {
+         return Resources.format(Resources.Keys.UnsupportedGeometryObject_1, dimension);
+     }
+ 
+     /**
+      * Returns an error message for an unsupported geometry object implementation.
+      *
+      * @param  geometry  the unsupported object.
+      */
+     private static String unsupportedImplementation(final Object geometry) {
+         return Errors.format(Errors.Keys.UnsupportedType_1, Classes.getClass(geometry));
      }
 +
 +    private static <T> Optional<T> findStrategy(final Function<Geometries<?>, T> op) {
 +        for (Geometries<?> g = implementation; g != null; g = g.fallback) {
 +            final T result = op.apply(g);
 +            if (result != null) return Optional.of(result);
 +        }
 +
 +        return Optional.empty();
 +    }
 +
 +    /**
 +     * See {@link Geometries#toGeometry(Envelope, WrapResolution)}.
 +     */
 +    Object tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
 +        // Ensure that we can isolate an horizontal part in the given envelope.
 +        final int x;
 +        if (env.getDimension() == 2) {
 +            x = 0;
 +        } else {
 +            final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
 +            if (crs == null) throw new IllegalArgumentException("Envelope with more than 2 dimensions, but without CRS: cannot isolate horizontal part.");
 +            final SingleCRS hCrs = CRS.getHorizontalComponent(crs);
 +            if (hCrs == null) throw new IllegalArgumentException("Cannot find an horizontal part in given CRS");
 +            x = AxisDirections.indexOfColinear(crs.getCoordinateSystem(), hCrs.getCoordinateSystem());
 +        }
 +
 +        final int y = x+1;
 +
 +        final DirectPosition lc = env.getLowerCorner();
 +        final DirectPosition uc = env.getUpperCorner();
 +        double minX = lc.getOrdinate(x);
 +        double minY = lc.getOrdinate(y);
 +        double maxX = uc.getOrdinate(x);
 +        double maxY = uc.getOrdinate(y);
 +        double[] splittedLeft = null;
 +        // We start by short-circuiting simplest case for minor simplicity/performance reason.
 +        if (!WrapResolution.NONE.equals(resolution)) {
 +            // ensure the envelope is correctly defined, by forcing non-authorized wrapped axes to take entire crs span.
 +            final GeneralEnvelope fixedEnv = new GeneralEnvelope(env);
 +            fixedEnv.normalize();
 +            int wrapAxis = -1;
 +            for (int i = x ; i <= y && wrapAxis < x ; i++) {
 +                if (fixedEnv.getLower(i) > fixedEnv.getUpper(i)) wrapAxis = i;
 +            }
 +            if (wrapAxis >= x) {
 +                final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
 +                if (crs == null) throw new IllegalArgumentException("Cannot resolve wrap-around for an envelope without any system defined");
 +                final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(wrapAxis);
 +                final double wrapRange = axis.getMaximumValue() - axis.getMinimumValue();
 +                switch (resolution) {
 +                    case EXPAND:
 +                        // simpler and more performant than a call to GeneralEnvelope.simplify()
 +                        if (wrapAxis == x) {
 +                            minX = axis.getMinimumValue();
 +                            maxX = axis.getMaximumValue();
 +                        } else {
 +                            minY = axis.getMinimumValue();
 +                            maxY = axis.getMaximumValue();
 +                        }
 +                        break;
 +                    case SPLIT:
 +                        if (wrapAxis == x) {
 +                            splittedLeft = new double[]{axis.getMinimumValue(), minY, maxX, maxY};
 +                            maxX = axis.getMaximumValue();
 +                        }
 +                        else {
 +                            splittedLeft = new double[] {minX, axis.getMinimumValue(), maxX, maxY};
 +                            maxY = axis.getMaximumValue();
 +                        }
 +                        break;
 +                    case CONTIGUOUS:
 +                        if (wrapAxis == x) maxX += wrapRange;
 +                        else maxY += wrapRange;
 +                        break;
 +                    default:
 +                        throw new IllegalArgumentException("Unknown or unset wrap resolution: " + resolution);
 +                }
 +            }
 +        }
 +
 +        Vector[] points = clockwiseRing(minX, minY, maxX, maxY);
 +
 +        final G mainRect = createPolyline(2, points);
 +        if (splittedLeft != null) {
 +            minX = splittedLeft[0];
 +            minY = splittedLeft[1];
 +            maxX = splittedLeft[2];
 +            maxY = splittedLeft[3];
 +            Vector[] points2 = clockwiseRing(minX, minY, maxX, maxY);
 +            final G secondRect = createPolyline(2, points2);
 +            return createMultiPolygon(Stream.of(mainRect, secondRect));
 +        }
 +
 +        /* Geotk original method had an option to insert a median point on wrappped around axis, but we have not ported
 +         * it, because in an orthonormal space, I don't see any case where it could be useful. However, in case it
 +         * have to be added, we can do it here by amending created ring(s).
 +         */
 +        return toPolygon(mainRect);
 +    }
 +
 +    /**
 +     * Create a sequence of points describing a rectangle whose start point is the lower left one. The sequence of
 +     * points describe each corner, going in clockwise order and repeating starting point to properly close the ring.
 +     *
 +     * @param minX Lower coordinate of first axis.
 +     * @param minY Lower coordinate of second axis.
 +     * @param maxX Upper coordinate of first axis.
 +     * @param maxY Upper coordinate of second axis.
 +     *
 +     * @return A set of 5 points describing given rectangle.
 +     */
 +    private static Vector[] clockwiseRing(final double minX, final double minY, final double maxX, final double maxY) {
 +        return new Vector[]{
 +                Vector.create(new double[]{minX, minY}),
 +                Vector.create(new double[]{minX, maxY}),
 +                Vector.create(new double[]{maxX, maxY}),
 +                Vector.create(new double[]{maxX, minY}),
 +                Vector.create(new double[]{minX, minY})
 +        };
 +    }
 +
 +    /**
 +     * Extract all points from input geometry, and return them as a contiguous set of ordinates.
 +     * For rings, point order (clockwise/counter-clockwise) is implementation dependant.
 +     *
 +     * @param geometry The geometry to extract point from.
 +     */
 +    public static Optional<double[]> getOrdinates(Geometry geometry) {
 +        return findStrategy(g -> g.getPoints(geometry));
 +    }
 +
 +    public abstract double[] getPoints(Object geometry);
 +
 +    public abstract G createMultiPolygon(final Stream<?> polygonsOrLinearRings);
 +
 +    public static Object createMultiPolygon_(final Stream polygonsOrLinearRings) {
 +        return findStrategy(g -> g.createMultiPolygon(polygonsOrLinearRings));
 +    }
 +
 +    /**
 +     * Try and associate given coordinate reference system to the specified geometry. It should replace any previously
 +     * set referencing information.
 +     *
 +     * @param target The geometry to embed referencing information into.
 +     * @param toApply Referencing information to add.
 +     */
 +    public void setCRS(G target, CoordinateReferenceSystem toApply) {
 +        throw new UnsupportedOperationException("Not supported yet");
 +    }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
index ea6d1f9,b5ded9f..17f826c
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
@@@ -16,22 -16,20 +16,25 @@@
   */
  package org.apache.sis.internal.feature;
  
- import java.util.ArrayList;
+ import java.util.Map;
+ import java.util.List;
  import java.util.Arrays;
+ import java.util.ArrayList;
  import java.util.Iterator;
- import java.util.List;
 -import org.opengis.util.FactoryException;
 +import java.util.stream.Stream;
 +
+ import org.opengis.referencing.operation.TransformException;
+ import org.opengis.referencing.operation.CoordinateOperation;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.util.FactoryException;
 +
 +import org.apache.sis.geometry.GeneralEnvelope;
 +import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
 +import org.apache.sis.util.Classes;
 +import org.apache.sis.util.collection.BackingStoreException;
 +
  import org.locationtech.jts.geom.Coordinate;
 -import org.locationtech.jts.geom.Point;
 -import org.locationtech.jts.geom.Polygon;
 -import org.locationtech.jts.geom.LineString;
 -import org.locationtech.jts.geom.MultiLineString;
  import org.locationtech.jts.geom.Envelope;
  import org.locationtech.jts.geom.Geometry;
  import org.locationtech.jts.geom.GeometryFactory;
@@@ -310,45 -321,43 +364,85 @@@ add:    for (;;) 
          return toGeometry(lines);
      }
  
 +    @Override
 +    public double[] getPoints(Object geometry) {
 +        if (geometry instanceof GeometryWrapper) {
 +            geometry = ((GeometryWrapper) geometry).geometry;
 +        }
 +
 +        if (geometry instanceof Geometry) {
 +            Geometry geom = (Geometry) geometry;
 +            final int nbPts = geom.getNumPoints();
 +            final Coordinate[] coords = geom.getCoordinates();
 +            double[] ordinates = new double[nbPts * 2];
 +            for (int i = 0, j=0; i < nbPts ; i++) {
 +                final Coordinate coord = coords[i];
 +                ordinates[j++] = coord.x;
 +                ordinates[j++] = coord.y;
 +            }
 +            return ordinates;
 +        }
 +
 +        return null;
 +    }
 +
 +    @Override
 +    public MultiPolygon createMultiPolygon(Stream<?> polygonsOrLinearRings) {
 +        final Polygon[] polys = polygonsOrLinearRings
 +                .map(this::castToPolygon)
 +                .toArray(size -> new Polygon[size]);
 +        return factory.createMultiPolygon(polys);
 +    }
 +
 +    private Polygon castToPolygon(Object input) {
 +        if (input instanceof GeometryWrapper) input = ((GeometryWrapper) input).geometry;
 +
 +        if (input instanceof Geometry) return toPolygon((Geometry) input);
 +        else throw new IllegalArgumentException("Given argument cannot be cast to polygon");
 +    }
 +
 +    @Override
 +    public void setCRS(Geometry target, CoordinateReferenceSystem toApply) {
 +        org.apache.sis.internal.feature.jts.JTS.setCoordinateReferenceSystem(target, toApply);
 +    }
++
+     /**
+      * If the given geometry is a JTS geometry, computes its buffer. Otherwise returns {@code null}.
+      */
+     @Override
+     Object tryBuffer(final Object geometry, final double distance) {
+         if (geometry instanceof Geometry) {
+             final Geometry jts = (Geometry) geometry;
+             final Geometry buffer = jts.buffer(distance);
+             copyMetadata(jts, buffer);
+             return buffer;
+         }
+         return null;
+     }
+ 
+     /**
+      * Tries to transforms the given geometry to the specified Coordinate Reference System (CRS),
+      * or returns {@code null} if this method can not perform this operation on the given object.
+      * Exactly one of {@code operation} and {@code targetCRS} shall be non-null.
+      *
+      * @param  geometry   the geometry to transform.
+      * @param  operation  the coordinate operation to apply, or {@code null}.
+      * @param  targetCRS  the target coordinate reference system, or {@code null}.
+      * @return the transformed geometry, or the same geometry if it is already in target CRS.
+      *
+      * @see #tryGetCoordinateReferenceSystem(Object)
+      */
+     @Override
+     Geometry tryTransform(final Object geometry, final CoordinateOperation operation, final CoordinateReferenceSystem targetCRS)
+             throws FactoryException, TransformException
+     {
+         if (geometry instanceof Geometry) {
+             if (operation != null) {
+                 return org.apache.sis.internal.feature.jts.JTS.transform((Geometry) geometry, operation);
+             } else {
+                 return org.apache.sis.internal.feature.jts.JTS.transform((Geometry) geometry, targetCRS);
+             }
+         }
+         return null;
+     }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
index 50a492b,19a019a..5f1fcc5
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
@@@ -19,27 -19,19 +19,30 @@@ package org.apache.sis.internal.feature
  import java.awt.Shape;
  import java.awt.geom.Line2D;
  import java.awt.geom.Path2D;
 +import java.awt.geom.PathIterator;
  import java.awt.geom.Point2D;
  import java.awt.geom.Rectangle2D;
 +import java.util.Arrays;
 +import java.util.Iterator;
 +import java.util.Spliterator;
 +import java.util.function.Consumer;
 +import java.util.stream.DoubleStream;
 +import java.util.stream.Stream;
 +import java.util.stream.StreamSupport;
 +
+ import java.awt.geom.RectangularShape;
++
  import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.internal.feature.j2d.ShapeProperties;
  import org.apache.sis.internal.referencing.j2d.ShapeUtilities;
  import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.util.Classes;
  import org.apache.sis.util.Numbers;
+ import org.apache.sis.util.UnsupportedImplementationException;
  
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Centralizes usages of some (not all) Java2D geometry API by Apache SIS.
@@@ -285,86 -253,7 +304,86 @@@ add:    for (;;) 
       * Parses the given WKT.
       */
      @Override
 -    public Object parseWKT(final String wkt) {
 +    public Shape parseWKT(final String wkt) {
-         throw unsupported(2);
+         throw new UnsupportedImplementationException(unsupported("parseWKT"));
      }
 +
 +    @Override
 +    public Shape parseWKB(byte[] source) {
-         throw unsupported(2);
++        throw new UnsupportedImplementationException(unsupported("parseWKB"));
 +    }
 +
 +    /**
 +     * An abstraction over {@link PathIterator} to use it in a streaming context.
 +     */
 +    private static final class PathSpliterator implements Spliterator<Segment> {
 +
 +        private final PathIterator source;
 +
 +        private PathSpliterator(PathIterator source) {
 +            this.source = source;
 +        }
 +
 +        @Override
 +        public boolean tryAdvance(Consumer<? super Segment> action) {
 +            if (source.isDone()) return false;
 +            final double[] coords = new double[6];
 +            final int segmentType = source.currentSegment(coords);
 +            action.accept(new Segment(segmentType, coords));
 +            source.next();
 +            return true;
 +        }
 +
 +        @Override
 +        public Spliterator<Segment> trySplit() {
 +            return null;
 +        }
 +
 +        @Override
 +        public long estimateSize() {
 +            return Long.MAX_VALUE;
 +        }
 +
 +        @Override
 +        public int characteristics() {
 +            return Spliterator.NONNULL | Spliterator.ORDERED | Spliterator.IMMUTABLE;
 +        }
 +    }
 +
 +    /**
 +     * Describe a path segment as described by {@link PathIterator#currentSegment(double[]) AWT path iteration API}.
 +     * Basically, the awt abstraction is really poor, so we made a wrapper around it to describe segments.
 +     */
 +    private static class Segment {
 +        /**
 +         * This segment type ({@link PathIterator#SEG_CLOSE}, etc.).
 +         */
 +        final int type;
 +        /**
 +         * Brut points composing the segment, as returned by {@link PathIterator#currentSegment(double[])}.
 +         */
 +        private final double[] points;
 +
 +        Segment(int type, double[] points) {
 +            this.type = type;
 +            this.points = points;
 +        }
 +
 +        /**
 +         *
 +         * @return points composing this segment, as a contiguous set of ordinates. Points are all 2D, so every two
 +         * elements in backed stream describe a point. Can be empty in case of {@link PathIterator#SEG_CLOSE closing segment}.
 +         */
 +        DoubleStream ordinates() {
 +            switch (type) {
 +                case PathIterator.SEG_CLOSE: return DoubleStream.empty();
 +                case PathIterator.SEG_QUADTO: return Arrays.stream(points, 0, 4);
 +                case PathIterator.SEG_CUBICTO: return Arrays.stream(points);
 +                case PathIterator.SEG_LINETO:
 +                case PathIterator.SEG_MOVETO:
 +                        return Arrays.stream(points, 0, 2);
 +                default: throw new IllegalStateException("Unknown segment type: "+type);
 +            }
 +        }
 +    }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
index 39a9ffc,b766a06..ada49fb
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
@@@ -107,31 -101,33 +107,57 @@@ public final class JTS extends Static 
          return null;
      }
  
 +    public static Optional<CoordinateReferenceSystem> setCoordinateReferenceSystem(final Geometry target, final CoordinateReferenceSystem toSet) {
 +        ensureNonNull("Target geometry", target);
 +        final Object ud = target.getUserData();
 +        if (ud == null) {
 +            // By security, we reset SRID in case old CRS was defined this way.
 +            target.setSRID(0);
 +            target.setUserData(toSet);
 +            return Optional.empty();
 +        } else if (ud instanceof CoordinateReferenceSystem) {
 +            target.setUserData(toSet);
 +            return Optional.of((CoordinateReferenceSystem) ud);
 +        } else if (ud instanceof Map) {
 +            final Map asMap = (Map) ud;
 +            // In case user-data contains other useful data, we don't switch from map to CRS. We also reset SRID.
 +            final Object oldVal = asMap.put(CRS_KEY, toSet);
 +            // By security, we reset SRID in case old CRS was defined this way.
 +            if (oldVal == null) {
 +                target.setSRID(0);
 +            }
 +        }
 +
 +        throw new IllegalArgumentException("Cannot modify input geometry, because user-data does not comply with SIS convention (should be a map or null, but was "+ud.getClass().getCanonicalName()+").");
 +    }
 +
      /**
+      * Finds an operation between the given CRS valid in the given area of interest.
+      * This method does not verify the CRS of the given geometry.
+      *
+      * @param  sourceCRS       the CRS of source coordinates.
+      * @param  targetCRS       the CRS of target coordinates.
+      * @param  areaOfInterest  the area of interest.
+      * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}.
+      * @throws FactoryException if the operation can not be created.
+      */
+     private static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS,
+                                                      final CoordinateReferenceSystem targetCRS,
+                                                      final Geometry areaOfInterest)
+             throws FactoryException
+     {
+         DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox();
+         try {
+             final Envelope e = areaOfInterest.getEnvelopeInternal();
+             bbox.setBounds(new Envelope2D(sourceCRS, e.getMinX(), e.getMinY(), e.getWidth(), e.getHeight()));
+         } catch (TransformException ex) {
+             bbox = null;
+             Logging.ignorableException(Logging.getLogger(Loggers.GEOMETRY), JTS.class, "transform", ex);
+         }
+         return CRS.findOperation(sourceCRS, targetCRS, bbox);
+     }
+ 
+     /**
       * Transforms the given geometry to the specified Coordinate Reference System (CRS).
       * If the given CRS or the given geometry is null, the geometry is returned unchanged.
       * If the geometry has no Coordinate Reference System, a {@link TransformException} is thrown.
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index 8b2cda5,0ed8ba5..1350a92
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@@ -16,219 -16,239 +16,376 @@@
   */
  package org.apache.sis.filter;
  
 -import org.locationtech.jts.geom.Coordinate;
 -import org.locationtech.jts.geom.Envelope;
 -import org.locationtech.jts.geom.Geometry;
 -import org.locationtech.jts.geom.GeometryFactory;
 -import org.locationtech.jts.geom.LineString;
 -import org.locationtech.jts.geom.Point;
 -import org.locationtech.jts.geom.Polygon;
  import org.opengis.feature.Feature;
  import org.opengis.feature.FeatureType;
- import org.opengis.filter.FilterFactory2;
+ import org.opengis.filter.FilterFactory;
 +import org.opengis.filter.expression.Expression;
  import org.opengis.filter.expression.Function;
 +import org.opengis.filter.expression.Literal;
 +import org.opengis.filter.expression.PropertyName;
 +import org.opengis.geometry.Envelope;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.referencing.crs.ProjectedCRS;
 +
  import org.apache.sis.feature.builder.FeatureTypeBuilder;
 -import org.apache.sis.referencing.crs.HardCodedCRS;
 +import org.apache.sis.geometry.GeneralEnvelope;
  import org.apache.sis.referencing.CommonCRS;
++import org.apache.sis.referencing.crs.HardCodedCRS;
  import org.apache.sis.test.TestCase;
 +import org.apache.sis.util.NullArgumentException;
 +
- import org.junit.Assert;
  import org.junit.Test;
 +import org.locationtech.jts.geom.Coordinate;
++import org.locationtech.jts.geom.Geometry;
 +import org.locationtech.jts.geom.GeometryFactory;
 +import org.locationtech.jts.geom.LineString;
 +import org.locationtech.jts.geom.LinearRing;
 +import org.locationtech.jts.geom.Point;
++import org.locationtech.jts.geom.Polygon;
  
 -import static org.opengis.test.Assert.*;
 +import static org.apache.sis.internal.feature.GeometriesTestCase.expectFailFast;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
++import static org.opengis.test.Assert.assertEquals;
++import static org.opengis.test.Assert.assertInstanceOf;
+ 
  
  /**
+  * Tests {@link SQLMM} functions implementations.
+  * Current implementation tests Java Topology Suite (JTS) implementation only.
   *
-  * @author Johann Sorel (Geomatys)
+  * @author  Johann Sorel (Geomatys)
+  * @version 1.1
+  * @since   1.1
+  * @module
   */
- public class SQLMMTest extends TestCase {
+ public final strictfp class SQLMMTest extends TestCase {
 +
 +    private static final String P_NAME = "geom";
- 
++    
      /**
       * The factory to use for creating the objects to test.
       */
-     private final FilterFactory2 factory = new DefaultFilterFactory();
-     private final GeometryFactory gf = new GeometryFactory();
+     private final FilterFactory factory;
  
      /**
-      * Test SQL/MM ST_Transform function.
+      * The factory to use for creating Java Topology Suite (JTS) objects.
       */
-     @Test
-     public void ST_TransformTest() {
+     private final GeometryFactory geometryFactory;
  
-         CoordinateReferenceSystem inCrs = CommonCRS.WGS84.normalizedGeographic();
-         CoordinateReferenceSystem outCrs = CommonCRS.WGS84.geographic();
+     /**
+      * Creates a new test case.
+      */
+     public SQLMMTest() {
+         factory = new DefaultFilterFactory();
+         geometryFactory = new GeometryFactory();
+     }
  
-         //test invalid
+     /**
+      * Verifies that attempts to create a function of the given name fail if no argument is provided.
+      */
+     private void assertRequireArguments(final String functionName) {
          try {
-             factory.function("ST_Transform");
-             Assert.fail("Creation with no argument should fail");
+             factory.function(functionName);
+             fail("Creation with no argument should fail");
          } catch (IllegalArgumentException ex) {
-             //ok
+             final String message = ex.getMessage();
+             assertTrue(message, message.contains("parameters"));
          }
+     }
  
-         //create a test feature
-         final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
-         ftb.setName("test");
-         ftb.addAttribute(Point.class).setName("geom").setCRS(inCrs);
+     /**
+      * Wraps the given geometry in a feature object. The geometry will be stored in a property named {@code "geom"}.
+      *
+      * @param  geometry  the geometry to wrap in a feature.
+      * @param  crs       the coordinate reference system to assign to the geometry.
+      */
+     private static Feature wrapInFeature(final Geometry geometry, final CoordinateReferenceSystem crs) {
+         final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("test");
+         ftb.addAttribute(Point.class).setName("geom").setCRS(crs);
          final FeatureType type = ftb.build();
-         final Point geometry = gf.createPoint(new Coordinate(10, 30));
-         geometry.setUserData(inCrs);
+         geometry.setUserData(crs);
          final Feature feature = type.newInstance();
          feature.setPropertyValue("geom", geometry);
+         return feature;
+     }
  
-         { //test transform function using epsg code
-             final Function fct = factory.function("ST_Transform", factory.property("geom"), factory.literal("EPSG:4326"));
- 
-             //check result
-             final Object newGeom = fct.evaluate(feature);
-             assertTrue(newGeom instanceof Point);
-             final Point trs = (Point) newGeom;
-             Assert.assertEquals(outCrs, trs.getUserData());
-             Assert.assertEquals(30.0, trs.getX(), 0.0);
-             Assert.assertEquals(10.0, trs.getY(), 0.0);
-         }
+     /**
+      * Evaluates the given function and returns its result as an object of the given type.
+      *
+      * @param  expectedType  the expected type of the result.
+      * @param  feature       the feature to use as input value. May be {@code null}.
+      * @param  testing       the function to test.
+      * @return evaluation result.
+      */
+     private static <G extends Geometry> G evaluate(final Class<G> expectedType, final Feature feature, final Function testing) {
+         final Object result = testing.evaluate(feature);
+         assertInstanceOf("Expected JTS geometry.", expectedType, result);
+         return expectedType.cast(result);
+     }
  
-         { //test transform function using crs object
-             final Function fct = factory.function("ST_Transform", factory.property("geom"), factory.literal(outCrs));
+     /**
+      * Test SQL/MM {@link ST_Transform} function.
+      */
+     @Test
+     public void testTransform() {
+         /*
+          * Verify that creation of a function without arguments is not allowed.
+          */
+         assertRequireArguments("ST_Transform");
+         /*
+          * Create a feature to be used for testing purpose. For this test, the CRS transformation
+          * will be simply a change of axis order from (λ,φ) to (φ,λ).
+          */
+         final Point geometry = geometryFactory.createPoint(new Coordinate(10, 30));
+         final Feature feature = wrapInFeature(geometry, HardCodedCRS.WGS84);
+         /*
+          * Test transform function using the full CRS object, then using only EPSG code.
+          */
+         testTransform(feature, HardCodedCRS.WGS84_φλ, HardCodedCRS.WGS84_φλ);
+         testTransform(feature, "EPSG:4326", CommonCRS.WGS84.geographic());
+     }
  
-             //check result
-             final Object newGeom = fct.evaluate(feature);
-             assertTrue(newGeom instanceof Point);
-             final Point trs = (Point) newGeom;
-             Assert.assertEquals(outCrs, trs.getUserData());
-             Assert.assertEquals(30.0, trs.getX(), 0.0);
-             Assert.assertEquals(10.0, trs.getY(), 0.0);
-         }
+     /**
+      * Tests {@link ST_Transform} on the given feature. The feature must have a property named {@code "geom"}.
+      * The result is expected to be a geometry using WGS84 datum with (φ,λ) axis order.
+      *
+      * @param  feature       the feature to use for testing the function.
+      * @param  specifiedCRS  the argument to give to the {@code "ST_Transform"} function.
+      * @param  expectedCRS   the CRS expected as a result of the transform function.
+      */
+     private void testTransform(final Feature feature, final Object specifiedCRS, final CoordinateReferenceSystem expectedCRS) {
+         final Point result = evaluate(Point.class, feature, factory.function("ST_Transform",
+                 factory.property("geom"), factory.literal(specifiedCRS)));
+         assertEquals("userData", expectedCRS, result.getUserData());
+         assertEquals(30, result.getX(), STRICT);
+         assertEquals(10, result.getY(), STRICT);
      }
  
+     /**
+      * Test SQL/MM {@link ST_Centroid} function.
+      */
      @Test
-     public void ST_Envelope() {
-         try {
-             new ST_Envelope(new Expression[2]);
-             fail("ST_Envelope operator should accept a single parameter");
-         } catch (IllegalArgumentException e) {
-             // expected behavior
-         }
+     public void testCentroid() {
+         assertRequireArguments("ST_Centroid");
+         /*
+          * Creates a single linestring for testing the centroid function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[] {
+             new Coordinate(10, 20),
+             new Coordinate(30, 20)
+         });
+         geometry.setSRID(4326);
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         /*
+          * Execute the function and check the result.
+          */
+         final Point result = evaluate(Point.class, null, factory.function("ST_Centroid", factory.literal(geometry)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         assertEquals(20, result.getX(), STRICT);
+         assertEquals(20, result.getY(), STRICT);
+     }
  
-         try {
-             new ST_Envelope(null);
-             fail("ST_Envelope operator should accept a single parameter");
-         } catch (IllegalArgumentException e) {
-             // expected behavior
-         }
+     /**
+      * Test SQL/MM {@link ST_Buffer} function.
+      */
+     @Test
+     public void ST_BufferTest() {
+         assertRequireArguments("ST_Buffer");
+         /*
+          * Creates a single point for testing the buffer function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final Point geometry = geometryFactory.createPoint(new Coordinate(10, 20));
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final Polygon result = evaluate(Polygon.class, null, factory.function("ST_Buffer", factory.literal(geometry), factory.literal(1)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
 -        final Envelope env = result.getEnvelopeInternal();
++        final org.locationtech.jts.geom.Envelope env = result.getEnvelopeInternal();
+         assertEquals( 9, env.getMinX(), STRICT);
+         assertEquals(11, env.getMaxX(), STRICT);
+         assertEquals(19, env.getMinY(), STRICT);
+         assertEquals(21, env.getMaxY(), STRICT);
+     }
  
-         final LineString pt = gf.createLineString(new Coordinate[]{
-                 new Coordinate(12, 3.3),
-                 new Coordinate(13.1, 4.4),
-                 new Coordinate(12.02, 5.7)
-         });
-         ST_Envelope operator = new ST_Envelope(new Expression[]{factory.literal(pt)});
-         final GeneralEnvelope expectedEnv = new GeneralEnvelope(2);
-         expectedEnv.setEnvelope(12, 3.3, 13.1, 5.7);
-         Envelope evaluated = (Envelope) operator.evaluate(null);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
-         evaluated = (Envelope) operator.evaluate(null);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
+     /**
+      * Test SQL/MM {@link ST_Simplify} function.
+      */
+     @Test
+     public void ST_SimplifyTest() {
+         assertRequireArguments("ST_Simplify");
+         /*
+          * Creates a single line for testing the simplify function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final LineString result = evaluate(LineString.class, null, factory.function("ST_Simplify", factory.literal(geometry), factory.literal(10)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         Coordinate[] coordinates = result.getCoordinates();
+         assertEquals(2, coordinates.length);
+         assertEquals(10, coordinates[0].x, STRICT);
+         assertEquals(20, coordinates[0].y, STRICT);
+         assertEquals(20, coordinates[1].x, STRICT);
+         assertEquals(20, coordinates[1].y, STRICT);
+     }
  
-         // After testing literal data, we'll now try to extract data from a feature.
-         final Feature f = mock();
-         f.setPropertyValue(P_NAME, pt);
-         operator = new ST_Envelope(new Expression[]{factory.property(P_NAME)});
-         evaluated = (Envelope) operator.evaluate(f);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
+     /**
+      * Test SQL/MM {@link ST_SimplifyPreserveTopology} function.
+      */
+     @Test
+     public void ST_SimplifyPreserveTopologyTest() {
+         assertRequireArguments("ST_SimplifyPreserveTopology");
+         /*
+          * Creates a single line for testing the simplify function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final LineString result = evaluate(LineString.class, null, factory.function("ST_SimplifyPreserveTopology", factory.literal(geometry), factory.literal(10)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         Coordinate[] coordinates = result.getCoordinates();
+         assertEquals(2, coordinates.length);
+         assertEquals(10, coordinates[0].x, STRICT);
+         assertEquals(20, coordinates[0].y, STRICT);
+         assertEquals(20, coordinates[1].x, STRICT);
+         assertEquals(20, coordinates[1].y, STRICT);
      }
 +
 +    @Test
 +    public void ST_Intersects() {
 +        try {
 +            new ST_Intersects(null);
 +            fail("ST_Intersects operator should accept exactly 2 parameters");
 +        } catch (NullArgumentException e) {
 +            // expected behavior
 +        }
 +
 +        try {
 +            new ST_Intersects(new Expression[3]);
 +            fail("ST_Intersects operator should accept exactly 2 parameters");
 +        } catch (IllegalArgumentException e) {
 +            // expected behavior
 +        }
 +
 +        final Coordinate start = new Coordinate(0, 0.1);
 +        final Coordinate second = new Coordinate(1.2, 0.2);
-         final LinearRing ring = gf.createLinearRing(new Coordinate[]{
++        final LinearRing ring = geometryFactory.createLinearRing(new Coordinate[]{
 +                start, second, new Coordinate(0.7, 0.8), start
 +        });
 +
 +        final Literal lring = factory.literal(ring);
-         ST_Intersects st = intersects(factory.literal(gf.createPoint(new Coordinate(2, 4))), lring);
++        ST_Intersects st = intersects(factory.literal(geometryFactory.createPoint(new Coordinate(2, 4))), lring);
 +        // Ensure argument nullity does not modify behavior
 +        assertFalse("Unexpected intersection", st.evaluate(null));
 +        assertFalse("Unexpected intersection", st.evaluate(new Object()));
 +
 +        // Border should intersect
 +        final Feature f = mock();
-         final Point point = gf.createPoint(second);
++        final Point point = geometryFactory.createPoint(second);
 +        f.setPropertyValue(P_NAME, point);
 +        final PropertyName geomName = factory.property(P_NAME);
 +        st = intersects(geomName, lring);
 +        assertTrue("Border point should intersect triangle", st.evaluate(f));
 +        // Ensure inverting expression does not modify behavior.
 +        st = intersects(lring, geomName);
 +        assertTrue("Border point should intersect triangle", st.evaluate(f));
 +
 +        // Ensure CRS conversion works as expected (see package-info).
 +        // Missing
 +        point.setUserData(CommonCRS.defaultGeographic());
 +        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
 +        final Literal lPoint = factory.literal(point);
 +        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 +
 +        // Disjoint
 +        final ProjectedCRS nadUtm = CommonCRS.NAD27.universal(32, 37);
 +        final ProjectedCRS wgsUtm = CommonCRS.WGS84.universal(-2, 4);
 +
 +        point.setUserData(nadUtm);
 +        ring.setUserData(wgsUtm);
 +        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
 +        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 +
 +        // TODO: activate back after fixing CRS.suggestCommonTarget
 +        // utm domain contained in CRS:84
- //        ring.setUserData(CommonCRS.defaultGeographic());
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
++        ring.setUserData(CommonCRS.defaultGeographic());
++        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
 +
 +        // Common base CRS
- //        ring.setUserData(CommonCRS.WGS84.universal(0, 0));
- //        point.setUserData(CommonCRS.WGS84.universal(7, 8));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
++        ring.setUserData(CommonCRS.WGS84.universal(0, 0));
++        point.setUserData(CommonCRS.WGS84.universal(7, 8));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
 +    }
 +
 +    private static ST_Intersects intersects(final Expression left, Expression right) {
 +        return new ST_Intersects(new Expression[]{left, right});
 +    }
 +
++    @Test
++    public void ST_Envelope() {
++        try {
++            new ST_Envelope(new Expression[2]);
++            fail("ST_Envelope operator should accept a single parameter");
++        } catch (IllegalArgumentException e) {
++            // expected behavior
++        }
++
++        try {
++            new ST_Envelope(null);
++            fail("ST_Envelope operator should accept a single parameter");
++        } catch (IllegalArgumentException e) {
++            // expected behavior
++        }
++
++        final LineString pt = geometryFactory.createLineString(new Coordinate[]{
++                new Coordinate(12, 3.3),
++                new Coordinate(13.1, 4.4),
++                new Coordinate(12.02, 5.7)
++        });
++        ST_Envelope operator = new ST_Envelope(new Expression[]{factory.literal(pt)});
++        final GeneralEnvelope expectedEnv = new GeneralEnvelope(2);
++        expectedEnv.setEnvelope(12, 3.3, 13.1, 5.7);
++        Envelope evaluated = (Envelope) operator.evaluate(null);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++        evaluated = (Envelope) operator.evaluate(null);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++
++        // After testing literal data, we'll now try to extract data from a feature.
++        final Feature f = mock();
++        f.setPropertyValue(P_NAME, pt);
++        operator = new ST_Envelope(new Expression[]{factory.property(P_NAME)});
++        evaluated = (Envelope) operator.evaluate(f);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++    }
++
 +    /**
 +     *
-      * @return A feature with a single property of {@link Object any} type named after
++     * @return A feature with a single property of {@link Object any} type named after {@link #P_NAME this constant}.
 +     */
 +    private static Feature mock() {
 +        final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("mock");
 +        ftb.addAttribute(Object.class).setName(P_NAME);
 +        final FeatureType mockType = ftb.build();
 +        return mockType.newInstance();
 +    }
  }
diff --cc core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index a8912d4,b139c7a..fe67a0e
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@@ -16,38 -16,33 +16,39 @@@
   */
  package org.apache.sis.referencing;
  
 -import java.util.Map;
 -import java.util.List;
  import java.util.ArrayList;
  import java.util.Collections;
 +import java.util.List;
 +import java.util.Map;
+ import java.util.logging.Filter;
  import java.util.logging.LogRecord;
 -import org.opengis.util.FactoryException;
 +
  import org.opengis.geometry.Envelope;
 -import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.geometry.Geometry;
 +import org.opengis.metadata.citation.Citation;
 +import org.opengis.metadata.extent.BoundingPolygon;
 +import org.opengis.metadata.extent.Extent;
 +import org.opengis.metadata.extent.GeographicBoundingBox;
 +import org.opengis.metadata.extent.GeographicExtent;
  import org.opengis.referencing.IdentifiedObject;
 -import org.opengis.referencing.cs.CartesianCS;
 -import org.opengis.referencing.cs.EllipsoidalCS;
 -import org.opengis.referencing.cs.AxisDirection;
 -import org.opengis.referencing.cs.CoordinateSystem;
 -import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.referencing.crs.CRSAuthorityFactory;
  import org.opengis.referencing.crs.CRSFactory;
 -import org.opengis.referencing.crs.SingleCRS;
  import org.opengis.referencing.crs.CompoundCRS;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 -import org.opengis.referencing.crs.CRSAuthorityFactory;
 +import org.opengis.referencing.crs.EngineeringCRS;
 +import org.opengis.referencing.crs.GeneralDerivedCRS;
  import org.opengis.referencing.crs.GeodeticCRS;
  import org.opengis.referencing.crs.GeographicCRS;
 -import org.opengis.referencing.crs.GeneralDerivedCRS;
  import org.opengis.referencing.crs.ProjectedCRS;
 +import org.opengis.referencing.crs.SingleCRS;
  import org.opengis.referencing.crs.TemporalCRS;
  import org.opengis.referencing.crs.VerticalCRS;
 -import org.opengis.referencing.crs.EngineeringCRS;
 +import org.opengis.referencing.cs.AxisDirection;
 +import org.opengis.referencing.cs.CartesianCS;
 +import org.opengis.referencing.cs.CoordinateSystem;
 +import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.opengis.referencing.cs.EllipsoidalCS;
  import org.opengis.referencing.datum.Datum;
  import org.opengis.referencing.datum.GeodeticDatum;
  import org.opengis.referencing.operation.Conversion;
@@@ -77,23 -74,24 +78,22 @@@ import org.apache.sis.referencing.crs.D
  import org.apache.sis.referencing.crs.DefaultGeographicCRS;
  import org.apache.sis.referencing.crs.DefaultProjectedCRS;
  import org.apache.sis.referencing.crs.DefaultVerticalCRS;
 -import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 -import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
 +import org.apache.sis.referencing.cs.AxisFilter;
 +import org.apache.sis.referencing.cs.CoordinateSystems;
 +import org.apache.sis.referencing.cs.DefaultVerticalCS;
 +import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 +import org.apache.sis.referencing.factory.UnavailableFactoryException;
  import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
  import org.apache.sis.referencing.operation.CoordinateOperationContext;
 -import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
  import org.apache.sis.referencing.operation.DefaultConversion;
 -import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 -import org.apache.sis.referencing.factory.UnavailableFactoryException;
 -import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 -import org.apache.sis.metadata.iso.extent.Extents;
 +import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.logging.Logging;
  import org.apache.sis.util.ArgumentChecks;
 -import org.apache.sis.util.Utilities;
  import org.apache.sis.util.Static;
 +import org.apache.sis.util.Utilities;
- import org.apache.sis.util.logging.Logging;
- import org.apache.sis.util.logging.WarningListener;
- import org.apache.sis.util.resources.Errors;
  
  // Branch-dependent imports
 -import org.opengis.geometry.Geometry;
  
  
  /**
diff --cc pom.xml
index eb9792a,fb79bb9..4bf193f
--- a/pom.xml
+++ b/pom.xml
@@@ -529,22 -532,16 +538,27 @@@
             Dependencies to be inherited by all modules.
         =========================================================== -->
    <dependencies>
 +    <!-- 
 +      Unit test declaration. Embed aggregator dependency + retrocompatibility artifact ('vintage'). 
 +      The later won't be needed anymore once all JUnit tests have been upgraded to new JUnit version.
 +    -->
      <dependency>
 -      <groupId>junit</groupId>
 -      <artifactId>junit</artifactId>
 -      <scope>test</scope>
 -    </dependency>
 +			<groupId>org.junit.jupiter</groupId>
 +			<artifactId>junit-jupiter</artifactId>
 +			<version>${junit.jupiter.version}</version>
 +			<scope>test</scope>
 +		</dependency>
 +    <dependency>
 +			<groupId>org.junit.vintage</groupId>
 +			<artifactId>junit-vintage-engine</artifactId>
 +			<version>${junit.jupiter.version}</version>
 +			<scope>test</scope>
 +		</dependency>
+     <dependency>   <!-- To be removed after https://issues.apache.org/jira/browse/SIS-469 is done. -->
+       <groupId>jakarta.xml.bind</groupId>
+       <artifactId>jakarta.xml.bind-api</artifactId>
+       <scope>test</scope>
+     </dependency>
    </dependencies>
  
  
@@@ -563,9 -560,9 +577,10 @@@
      <maven.compiler.source>8</maven.compiler.source>
      <maven.compiler.target>8</maven.compiler.target>
      <sis.plugin.version>${project.version}</sis.plugin.version>
-     <sis.non-free.version>1.0-M1</sis.non-free.version>                 <!-- Used only if "non-free" profile is enabled. -->
-     <geoapi.version>4.0-M11</geoapi.version>
+     <sis.non-free.version>1.0</sis.non-free.version>                 <!-- Used only if "non-free" profile is enabled. -->
+     <geoapi.version>4.0-SNAPSHOT</geoapi.version>
+     <jaxb.version>2.3.2</jaxb.version>
 +		<junit.jupiter.version>5.5.2</junit.jupiter.version>
    </properties>
  
    <profiles>
@@@ -678,13 -675,9 +693,12 @@@
            <includes>
              <include>**/*TestSuite.java</include>
            </includes>
 -          <systemPropertyVariables>
 -            <derby.stream.error.file>${project.build.directory}/derby.log</derby.stream.error.file>
 -          </systemPropertyVariables>
 +          <systemProperties>
 +            <property>
 +              <name>derby.stream.error.file</name>
 +              <value>${project.build.directory}/derby.log</value>
 +            </property>
 +          </systemProperties>
-           <argLine>--add-modules java.xml.bind,java.xml.ws.annotation,javafx.graphics</argLine>
          </configuration>
        </plugin>
  
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
index 063a17f,bb973e8..861822f
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
@@@ -27,32 -28,21 +27,31 @@@ import java.util.function.Supplier
  import java.util.logging.Level;
  import java.util.logging.LogRecord;
  import javax.sql.DataSource;
 -import java.sql.SQLException;
 -import java.sql.DatabaseMetaData;
 -import java.sql.ResultSet;
 -import org.opengis.util.NameSpace;
 -import org.opengis.util.NameFactory;
 +
  import org.opengis.util.GenericName;
 +import org.opengis.util.NameFactory;
 +import org.opengis.util.NameSpace;
 +
 +import org.apache.sis.feature.builder.AssociationRoleBuilder;
 +import org.apache.sis.feature.builder.AttributeRole;
 +import org.apache.sis.feature.builder.AttributeTypeBuilder;
 +import org.apache.sis.feature.builder.FeatureTypeBuilder;
  import org.apache.sis.internal.metadata.sql.Dialect;
 +import org.apache.sis.internal.metadata.sql.Reflection;
  import org.apache.sis.internal.metadata.sql.SQLUtilities;
 +import org.apache.sis.internal.sql.feature.FeatureAdapter.PropertyMapper;
  import org.apache.sis.internal.system.DefaultFactories;
- import org.apache.sis.storage.DataStore;
 -import org.apache.sis.storage.sql.SQLStore;
 +import org.apache.sis.storage.DataStoreContentException;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.storage.InternalDataStoreException;
+ import org.apache.sis.storage.event.StoreListeners;
 +import org.apache.sis.storage.sql.SQLStore;
 +import org.apache.sis.util.collection.BackingStoreException;
 +import org.apache.sis.util.iso.Names;
- import org.apache.sis.util.logging.WarningListeners;
  import org.apache.sis.util.resources.ResourceInternationalString;
  
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Helper methods for creating {@code FeatureType}s from database structure.
@@@ -159,14 -141,11 +158,14 @@@ final class Analyzer 
       * @param  listeners  Value of {@code SQLStore.listeners}.
       * @param  locale     Value of {@code SQLStore.getLocale()}.
       */
-     Analyzer(final DataSource source, final Connection databaseConnection, final WarningListeners<DataStore> listeners,
 -    Analyzer(final DataSource source, final DatabaseMetaData metadata, final StoreListeners listeners,
++    Analyzer(final DataSource source, final Connection databaseConnection, final StoreListeners listeners,
               final Locale locale) throws SQLException
      {
 +        ensureNonNull("Database connection provider", source);
 +        ensureNonNull("Database connection", databaseConnection);
          this.source      = source;
 -        this.metadata    = metadata;
 +        this.connection  = databaseConnection;
 +        this.metadata    = databaseConnection.getMetaData();
          this.listeners   = listeners;
          this.locale      = locale;
          this.strings     = new HashMap<>();
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
index 0985cfb,66ba910..f908a74
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
@@@ -109,10 -108,10 +108,10 @@@ public final class Database 
       * @throws DataStoreException if a logical error occurred while analyzing the database structure.
       */
      public Database(final SQLStore store, final Connection connection, final DataSource source,
-             final GenericName[] tableNames, final WarningListeners<DataStore> listeners)
+             final GenericName[] tableNames, final StoreListeners listeners)
              throws SQLException, DataStoreException
      {
 -        final Analyzer analyzer = new Analyzer(source, connection.getMetaData(), listeners, store.getLocale());
 +        final Analyzer analyzer = new Analyzer(source, connection, listeners, store.getLocale());
          final String[] tableTypes = getTableTypes(analyzer.metadata);
          final Set<TableReference> declared = new LinkedHashSet<>();
          for (final GenericName tableName : tableNames) {
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
index 7e700a7,fd04b4b..dcd0269
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
@@@ -147,12 -135,10 +147,12 @@@ final class Features implements Spliter
      private final Class<?> keyComponentClass;
  
      /**
-      * Estimated number of rows, or {@literal <= 0} if unknown.
+      * Estimated number of remaining rows, or {@literal <= 0} if unknown.
       */
-     private final long estimatedSize;
+     private long estimatedSize;
  
 +    private final FeatureAdapter.ResultSetAdapter adapter;
 +
      /**
       * Creates a new iterator over the feature instances.
       *
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
index f4c20ca,7ca22ad..440988d
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
@@@ -35,10 -31,14 +35,12 @@@ import org.apache.sis.storage.Aggregate
  import org.apache.sis.storage.DataStore;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.storage.IllegalNameException;
 +import org.apache.sis.storage.Resource;
  import org.apache.sis.storage.StorageConnector;
- import org.apache.sis.storage.event.ChangeEvent;
- import org.apache.sis.storage.event.ChangeListener;
+ import org.apache.sis.storage.event.StoreEvent;
+ import org.apache.sis.storage.event.StoreListener;
+ import org.apache.sis.storage.event.WarningEvent;
 -import org.apache.sis.internal.sql.feature.Database;
 -import org.apache.sis.internal.sql.feature.Resources;
 -import org.apache.sis.internal.storage.MetadataBuilder;
+ import org.apache.sis.internal.util.Strings;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.Exceptions;
  
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
index 598a338,cb75e22..5d50a6c
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
@@@ -119,15 -123,20 +123,21 @@@ public class SimpleQuery extends Query 
       */
      @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
      public void setColumns(Column... columns) {
 -        if (columns != null) {
 +        if (columns == null || columns.length < 1) {
 +            this.columns = null;
 +        } else {
              columns = columns.clone();
-             for (int i = 0; i < columns.length; i++) {
-                 ArgumentChecks.ensureNonNullElement("columns", i, columns[i]);
+             final Map<Object,Integer> uniques = new LinkedHashMap<>(Containers.hashMapCapacity(columns.length));
+             for (int i=0; i<columns.length; i++) {
+                 final Column c = columns[i];
+                 ArgumentChecks.ensureNonNullElement("columns", i, c);
+                 final Object key = c.alias != null ? c.alias : c.expression;
+                 final Integer p = uniques.putIfAbsent(key, i);
+                 if (p != null) {
+                     throw new IllegalArgumentException(Resources.format(Resources.Keys.DuplicatedQueryProperty_3, key, p, i));
+                 }
              }
-             this.columns = columns;
          }
 -        this.columns = columns;
      }
  
      /**