Merge branch 'geoapi-4.0' into geoapi-3.1: last minute API changes before 1.0 release.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
index 12169c1..9caedb6 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
@@ -849,7 +849,7 @@
             if (getCoordinateReferenceSystem(envelope) != null && !envelope.isAllNaN()) {
                 try {
                     final DefaultGeographicBoundingBox db = ReferencingServices.getInstance().setBounds(envelope, null, null);
-                    db.transition(DefaultGeographicBoundingBox.State.EDITABLE);
+                    db.transitionTo(DefaultGeographicBoundingBox.State.EDITABLE);
                     bbox = db;
                 } catch (TransformException e) {
                     bbox = NilReason.INAPPLICABLE.createNilObject(GeographicBoundingBox.class);
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFunction.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFunction.java
index dcfccfd..67a580f 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ComparisonFunction.java
@@ -164,11 +164,9 @@
                  * All values in the collection may be compared to the other value until match condition is met.
                  * Null elements in the collection are ignored.
                  */
-                boolean found  = false;
-                boolean hasOne = false;
+                boolean match = false;
                 for (final Object element : collection) {
                     if (element != null) {
-                        found = true;
                         final boolean pass;
                         if (collectionFirst) {
                             pass = evaluate(element, right);
@@ -176,19 +174,26 @@
                             pass = evaluate(left, element);
                         }
                         switch (matchAction) {
-                            default:  return false;                            // Unknown enumeration.
-                            case ALL: if (!pass) return false; else break;
-                            case ANY: if ( pass) return true;  else break;
+                            default: return false;              // Unknown enumeration.
+                            case ALL: {
+                                if (!pass) return false;
+                                match = true;                   // Remember that we have at least 1 value.
+                                break;
+                            }
+                            case ANY: {
+                                if (pass) return true;
+                                break;                          // `match` still false since no match.
+                            }
                             case ONE: {
                                 if (pass) {
-                                    if (hasOne) return false;
-                                    hasOne = true;
+                                    if (match) return false;    // If a value has been found previously.
+                                    match = true;               // Remember that we have exactly one value.
                                 }
                             }
                         }
                     }
                 }
-                return found;
+                return match;
             }
         }
         return false;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
index c93558b..334fcfd 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/TransformationAccuracy.java
@@ -79,7 +79,7 @@
                     new DefaultAbsoluteExternalPositionalAccuracy(result);
             element.setNamesOfMeasure(Collections.singleton(TRANSFORMATION_ACCURACY));
             element.setEvaluationMethodType(EvaluationMethodType.DIRECT_EXTERNAL);
-            element.transition(DefaultAbsoluteExternalPositionalAccuracy.State.FINAL);
+            element.transitionTo(DefaultAbsoluteExternalPositionalAccuracy.State.FINAL);
 
             p = CACHE.putIfAbsent(accuracy, element);
             if (p == null) {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
index f9c3b78..516c144 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
@@ -104,7 +104,7 @@
     private static final byte STAGED = 1;
 
     /**
-     * A value for {@link #state} meaning that execution of {@code transition(…)} is in progress.
+     * A value for {@link #state} meaning that execution of {@code transitionTo(…)} is in progress.
      * Must be greater than all other values except {@link #COMPLETABLE} and {@link #FINAL}.
      */
     private static final byte FREEZING = 2;
@@ -117,7 +117,7 @@
     private static final byte COMPLETABLE = 3;
 
     /**
-     * A value for {@link #state} meaning that {@code transition(State.FINAL)} has been invoked.
+     * A value for {@link #state} meaning that {@code transitionTo(State.FINAL)} has been invoked.
      * Must be greater than all other values.
      */
     private static final byte FINAL = 4;
@@ -142,7 +142,7 @@
     /**
      * Whether the metadata is still editable or has been made final.
      * New {@link ModifiableMetadata} instances are initially {@link #EDITABLE}
-     * and can be made {@link #FINAL} after construction by a call to {@link ModifiableMetadata#transition(State)}.
+     * and can be made {@link #FINAL} after construction by a call to {@link ModifiableMetadata#transitionTo(State)}.
      *
      * <div class="note"><b>Note:</b>
      * more states may be added in future Apache SIS versions. On possible candidate is {@code STAGED}.
@@ -208,7 +208,7 @@
     /**
      * Tells whether this instance of metadata is editable.
      * This is initially {@link State#EDITABLE} for new {@code ModifiableMetadata} instances,
-     * but can be changed by a call to {@link #transition(State)}.
+     * but can be changed by a call to {@link #transitionTo(State)}.
      *
      * <p>{@link State#FINAL} implies that all properties are also final.
      * This recursivity does not necessarily apply to other states. For example {@link State#EDITABLE}
@@ -268,7 +268,7 @@
      *
      * @since 1.0
      */
-    public boolean transition(final State target) {
+    public boolean transitionTo(final State target) {
         if (target.code < state) {
             throw new UnmodifiableMetadataException(Resources.format(Resources.Keys.UnmodifiableMetadata));
         }
@@ -427,7 +427,7 @@
         if (source != target) {
             if (state == FREEZING) {
                 /*
-                 * transition(State.FINAL) is under progress. The source collection is already
+                 * transitionTo(State.FINAL) is under progress. The source collection is already
                  * an unmodifiable instance created by StateChanger.
                  */
                 assert (useSet != null) || collectionType(elementType).isInstance(source) : elementType;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
index c68d89d..f9305cf 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
@@ -30,7 +30,7 @@
 
 
 /**
- * Invokes {@link ModifiableMetadata#transition(ModifiableMetadata.State)} recursively on metadata elements.
+ * Invokes {@link ModifiableMetadata#transitionTo(ModifiableMetadata.State)} recursively on metadata elements.
  *
  * As of Apache SIS 1.0, this class is used only for {@link ModifiableMetadata.State#FINAL}.
  * But a future version may use this object for other states too.
@@ -122,7 +122,7 @@
      *
      * <ul>
      *   <li>If the specified object is an instance of {@code ModifiableMetadata}, then
-     *       {@link ModifiableMetadata#transition(ModifiableMetadata.State)} is invoked on that object.</li>
+     *       {@link ModifiableMetadata#transitionTo(ModifiableMetadata.State)} is invoked on that object.</li>
      *   <li>Otherwise, if the object is a {@linkplain Collection collection}, then the
      *       content is copied into a new collection of similar type, with values replaced
      *       by their unmodifiable variant.</li>
@@ -140,7 +140,7 @@
          *          It may have its own algorithm for changing its state.
          */
         if (object instanceof ModifiableMetadata) {
-            ((ModifiableMetadata) object).transition(target);
+            ((ModifiableMetadata) object).transitionTo(target);
             return object;
         }
         if (object instanceof DefaultRepresentativeFraction) {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
index 653e016..756b771 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
@@ -223,9 +223,9 @@
      * {@inheritDoc}
      */
     @Override
-    public boolean transition(final State target) {
+    public boolean transitionTo(final State target) {
         final Collection<Identifier> p = identifiers;
-        final boolean changed = super.transition(target);
+        final boolean changed = super.transitionTo(target);
         if (changed) {
             /*
              * The 'identifiers' collection will have been replaced by an unmodifiable collection if
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
index dd1156b..ea1c6ce 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
@@ -91,10 +91,10 @@
     public static final Extent WORLD;
     static {
         final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox(-180, 180, -90, 90);
-        box.transition(DefaultGeographicBoundingBox.State.FINAL);
+        box.transitionTo(DefaultGeographicBoundingBox.State.FINAL);
         final DefaultExtent world = new DefaultExtent(
                 Vocabulary.formatInternational(Vocabulary.Keys.World), box, null, null);
-        world.transition(DefaultExtent.State.FINAL);
+        world.transitionTo(DefaultExtent.State.FINAL);
         WORLD = world;
     }
 
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java
index e6cbf94..f6abb5a 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java
@@ -283,7 +283,7 @@
      * Makes this representative fraction unmodifiable. After invocation to this method,
      * any call to a setter method will throw an {@link UnmodifiableMetadataException}.
      *
-     * @see ModifiableMetadata#transition(ModifiableMetadata.State)
+     * @see ModifiableMetadata#transitionTo(ModifiableMetadata.State)
      *
      * @since 0.7
      */
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
index 11f2d8d..d00febf 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
@@ -239,7 +239,7 @@
                             }
                             cache = impl.newInstance();
                             if (cache instanceof ModifiableMetadata) {
-                                ((ModifiableMetadata) cache).transition(ModifiableMetadata.State.COMPLETABLE);
+                                ((ModifiableMetadata) cache).transitionTo(ModifiableMetadata.State.COMPLETABLE);
                             }
                             /*
                              * We do not use AtomicReference because it is okay if the cache is instantiated twice.
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
index 75f6bf8..be835d8 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
@@ -216,7 +216,7 @@
         if (copyFrom != null) {
             c.setCitedResponsibleParties(createCitation(copyFrom).getCitedResponsibleParties());
         }
-        c.transition(DefaultCitation.State.FINAL);
+        c.transitionTo(DefaultCitation.State.FINAL);
         return c;
     }
 
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
index 1bc1cd2..f40095b 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/ModifiableMetadataTest.java
@@ -85,7 +85,7 @@
      */
     @Test
     public void testStateEditable() {
-        assertFalse("transition", md.transition(ModifiableMetadata.State.EDITABLE));        // Shall be a no-op.
+        assertFalse("transitionTo", md.transitionTo(ModifiableMetadata.State.EDITABLE));        // Shall be a no-op.
         assertEquals("state", ModifiableMetadata.State.EDITABLE, md.state());
         assertEquals("identifier.state", ModifiableMetadata.State.EDITABLE, identifierState());
         /*
@@ -105,11 +105,11 @@
      */
     @Test
     public void testStateCompletable() {
-        assertTrue("transition", md.transition(ModifiableMetadata.State.COMPLETABLE));
+        assertTrue("transitionTo", md.transitionTo(ModifiableMetadata.State.COMPLETABLE));
         assertEquals("state", ModifiableMetadata.State.COMPLETABLE, md.state());
         assertEquals("identifier.state", ModifiableMetadata.State.COMPLETABLE, identifierState());
         try {
-            md.transition(ModifiableMetadata.State.EDITABLE);
+            md.transitionTo(ModifiableMetadata.State.EDITABLE);
             fail("Shall not be allowed to transition back to editable state.");
         } catch (UnmodifiableMetadataException e) {
             verifyUnmodifiableException(e);
@@ -147,11 +147,11 @@
      */
     @Test
     public void testStateFinal() {
-        assertTrue("transition", md.transition(ModifiableMetadata.State.FINAL));
+        assertTrue("transitionTo", md.transitionTo(ModifiableMetadata.State.FINAL));
         assertEquals("state", ModifiableMetadata.State.FINAL, md.state());
         assertEquals("identifier.state", ModifiableMetadata.State.FINAL, identifierState());
         try {
-            md.transition(ModifiableMetadata.State.EDITABLE);
+            md.transitionTo(ModifiableMetadata.State.EDITABLE);
             fail("Shall not be allowed to transition back to editable state.");
         } catch (UnmodifiableMetadataException e) {
             verifyUnmodifiableException(e);
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
index c861bdb..05238b8 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
@@ -134,13 +134,13 @@
     }
 
     /**
-     * Tests {@link DefaultCitation#transition(DefaultCitation.State)} to the final state.
+     * Tests {@link DefaultCitation#transitionTo(DefaultCitation.State)} to the final state.
      */
     @Test
     public void testTransitionToFinal() {
         final DefaultCitation original = create();
         final DefaultCitation clone = create();
-        clone.transition(DefaultCitation.State.FINAL);
+        clone.transitionTo(DefaultCitation.State.FINAL);
         assertEquals("original.state", DefaultCitation.State.EDITABLE, original.state());
         assertEquals("clone.state",    DefaultCitation.State.FINAL,    clone.state());
         assertEquals(original, clone);
@@ -201,7 +201,7 @@
      * Verifies that {@code actual} is an unmodifiable copy of {@code expected}.
      */
     private static <T> void assertCopy(final Collection<T> expected, final Collection<T> actual) {
-        assertNotSame("ModifiableMetadata.transition(FINAL) shall have copied the collection.", expected, actual);
+        assertNotSame("ModifiableMetadata.transitionTo(FINAL) shall have copied the collection.", expected, actual);
         assertEquals("The copied collection shall have the same content than the original.", expected, actual);
         try {
             actual.add(null);
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
index db17faf..f23a5eb 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
@@ -51,7 +51,7 @@
         c.getAlternateTitles().add(new SimpleInternationalString("ISO 19111"));
         c.getIdentifiers().add(new DefaultIdentifier("ISO", "19111", null));
         c.getPresentationForms().add(PresentationForm.DOCUMENT_DIGITAL);
-        c.transition(DefaultCitation.State.FINAL);
+        c.transitionTo(DefaultCitation.State.FINAL);
         ISO_19111 = c;
     }
 
@@ -62,7 +62,7 @@
     static {
         final DefaultCitation c = new DefaultCitation("ISO 19115");
         c.getPresentationForms().add(PresentationForm.DOCUMENT_DIGITAL);
-        c.transition(DefaultCitation.State.FINAL);
+        c.transitionTo(DefaultCitation.State.FINAL);
         ISO_19115 = c;
     }
 
@@ -101,7 +101,7 @@
         c.getPresentationForms().add(PresentationForm.TABLE_DIGITAL);
         c.getIdentifiers().add(new DefaultIdentifier(Constants.EPSG));
         c.getCitedResponsibleParties().add(p);
-        c.transition(DefaultCitation.State.FINAL);
+        c.transitionTo(DefaultCitation.State.FINAL);
         EPSG = c;
     }
 
@@ -111,7 +111,7 @@
     public static final DefaultCitation SIS;
     static {
         final DefaultCitation c = new DefaultCitation(Constants.SIS);
-        c.transition(DefaultCitation.State.FINAL);
+        c.transitionTo(DefaultCitation.State.FINAL);
         SIS = c;
     }
 
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFractionTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFractionTest.java
index 700f075..2eaefbc 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFractionTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFractionTest.java
@@ -111,7 +111,7 @@
 
     /**
      * Tests indirectly {@link DefaultRepresentativeFraction#freeze()}.
-     * This method verifies that a call to {@code DefaultResolution.transition(FINAL)}
+     * This method verifies that a call to {@code DefaultResolution.transitionTo(FINAL)}
      * implies a call to {@link DefaultRepresentativeFraction#freeze()}.
      *
      * @since 0.7
@@ -120,7 +120,7 @@
     public void testFreeze() {
         final DefaultRepresentativeFraction fraction = new DefaultRepresentativeFraction(1000);
         final DefaultResolution resolution = new DefaultResolution(fraction);
-        resolution.transition(DefaultResolution.State.FINAL);
+        resolution.transitionTo(DefaultResolution.State.FINAL);
         assertSame(fraction, resolution.getEquivalentScale());
         try {
             fraction.setDenominator(10);
diff --git a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
index 5ca0cd2..47be601 100644
--- a/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
+++ b/core/sis-referencing-by-identifiers/src/main/java/org/apache/sis/referencing/gazetteer/FinalLocationType.java
@@ -206,7 +206,7 @@
     private static <T> T unmodifiable(final Class<T> type, T metadata) {
         if (metadata instanceof ModifiableMetadata) {
             metadata = MetadataCopier.forModifiable(((ModifiableMetadata) metadata).getStandard()).copy(type, metadata);
-            ((ModifiableMetadata) metadata).transition(ModifiableMetadata.State.FINAL);
+            ((ModifiableMetadata) metadata).transitionTo(ModifiableMetadata.State.FINAL);
         }
         return metadata;
     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
index d3a1b04..a510fae 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
@@ -112,7 +112,7 @@
         setMeasureDescription(measureDescription);
         setEvaluationMethodDescription(evaluationMethodDescription);
         setEvaluationMethodType(EvaluationMethodType.DIRECT_INTERNAL);
-        transition(State.FINAL);
+        transitionTo(State.FINAL);
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/ImmutableIdentifier.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/ImmutableIdentifier.java
index f79eac6..f8c137b 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/ImmutableIdentifier.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/ImmutableIdentifier.java
@@ -51,8 +51,8 @@
  * <div class="section">Immutability and thread safety</div>
  * This class is immutable and thus inherently thread-safe if the {@link Citation} and {@link InternationalString}
  * arguments given to the constructor are also immutable. It is caller's responsibility to ensure that those
- * conditions hold, for example by invoking {@link org.apache.sis.metadata.iso.citation.DefaultCitation#transition
- * DefaultCitation.transition(DefaultCitation.State.FINAL)} before passing the arguments to the constructor.
+ * conditions hold, for example by invoking {@link org.apache.sis.metadata.iso.citation.DefaultCitation#transitionTo
+ * DefaultCitation.transitionTo(DefaultCitation.State.FINAL)} before passing the arguments to the constructor.
  * Subclasses shall make sure that any overridden methods remain safe to call from multiple threads and do not change
  * any public {@code ImmutableIdentifier} state.
  *
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
index 6d3abc1..c196c5f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
@@ -79,8 +79,8 @@
  * <div class="section">Immutability and thread safety</div>
  * This class is immutable and thus inherently thread-safe if the {@link Citation} and {@link InternationalString}
  * arguments given to the constructor are also immutable. It is caller's responsibility to ensure that those
- * conditions hold, for example by invoking {@link org.apache.sis.metadata.iso.citation.DefaultCitation#transition
- * DefaultCitation.transition(DefaultCitation.State.FINAL)} before passing the arguments to the constructor.
+ * conditions hold, for example by invoking {@link org.apache.sis.metadata.iso.citation.DefaultCitation#transitionTo
+ * DefaultCitation.transitionTo(DefaultCitation.State.FINAL)} before passing the arguments to the constructor.
  * Subclasses shall make sure that any overridden methods remain safe to call from multiple threads and do not change
  * any public {@code NamedIdentifier} state.
  *
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index 12fd713..f4ff54c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -487,7 +487,7 @@
         } catch (SQLException exception) {
             unexpectedException("getAuthority", exception);
         } finally {
-            c.transition(DefaultCitation.State.FINAL);
+            c.transitionTo(DefaultCitation.State.FINAL);
         }
         return c;
     }
@@ -2078,7 +2078,7 @@
                 }
                 if (description != null || bbox != null) {
                     DefaultExtent extent = new DefaultExtent(description, bbox, null, null);
-                    extent.transition(DefaultExtent.State.FINAL);
+                    extent.transitionTo(DefaultExtent.State.FINAL);
                     returnValue = ensureSingleton(extent, returnValue, code);
                 }
             }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataTest.java b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataTest.java
index 458f7e5..bd82939 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataTest.java
@@ -68,7 +68,6 @@
 import static java.util.Collections.singletonMap;
 
 // Test dependencies
-
 import org.apache.sis.test.LoggingWatcher;
 import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.xml.DocumentComparator;
diff --git a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
index 386b4b7..0e50216 100644
--- a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
+++ b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
@@ -974,7 +974,7 @@
                     }
                 }
             }
-            result.transition(DefaultMetadata.State.FINAL);
+            result.transitionTo(DefaultMetadata.State.FINAL);
         }
         return result;
     }
diff --git a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java
index 37b8672..770b330 100644
--- a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java
+++ b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java
@@ -20,6 +20,7 @@
 import java.io.BufferedReader;
 import java.io.LineNumberReader;
 import java.io.IOException;
+import java.nio.file.StandardOpenOption;
 import java.net.URI;
 import java.util.Optional;
 import org.opengis.metadata.Metadata;
@@ -28,6 +29,7 @@
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.DataStoreClosedException;
 import org.apache.sis.storage.DataStoreReferencingException;
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.storage.StorageConnector;
@@ -114,18 +116,18 @@
 
     /**
      * Returns the parameters used to open this Landsat data store.
-     * If non-null, the parameters are described by {@link LandsatStoreProvider#getOpenParameters()} and contains at
-     * least a parameter named {@value org.apache.sis.storage.DataStoreProvider#LOCATION} with a {@link URI} value.
-     * This method may return {@code null} if the storage input can not be described by a URI
+     * The parameters are described by {@link LandsatStoreProvider#getOpenParameters()} and contains at least
+     * a parameter named {@value org.apache.sis.storage.DataStoreProvider#LOCATION} with a {@link URI} value.
+     * The return value may be empty if the storage input can not be described by a URI
      * (for example a Landsat file reading directly from a {@link java.nio.channels.ReadableByteChannel}).
      *
-     * @return parameters used for opening this data store, or {@code null} if not available.
+     * @return parameters used for opening this data store.
      *
      * @since 0.8
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
-        return URIDataStore.parameters(provider, location);
+    public Optional<ParameterValueGroup> getOpenParameters() {
+        return Optional.ofNullable(URIDataStore.parameters(provider, location));
     }
 
     /**
@@ -156,17 +158,20 @@
      */
     @Override
     public synchronized Metadata getMetadata() throws DataStoreException {
-        if (metadata == null && source != null) try {
+        if (metadata == null) {
+            if (source == null) {
+                throw new DataStoreClosedException(getLocale(), LandsatStoreProvider.NAME, StandardOpenOption.READ);
+            }
             try (BufferedReader reader = (source instanceof BufferedReader) ? (BufferedReader) source : new LineNumberReader(source)) {
                 source = null;      // Will be closed at the end of this try-finally block.
                 final LandsatReader parser = new LandsatReader(getDisplayName(), listeners);
                 parser.read(reader);
                 metadata = parser.getMetadata();
+            } catch (IOException e) {
+                throw new DataStoreException(e);
+            } catch (FactoryException e) {
+                throw new DataStoreReferencingException(e);
             }
-        } catch (IOException e) {
-            throw new DataStoreException(e);
-        } catch (FactoryException e) {
-            throw new DataStoreReferencingException(e);
         }
         return metadata;
     }
@@ -177,10 +182,10 @@
      * any listener specified for another kind of events will be ignored.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
index efbf468..ce1e8fb 100644
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
+++ b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
@@ -257,7 +257,7 @@
             if (release != null) {
                 final DefaultCitation df = new DefaultCitation(c);
                 df.setEdition(new SimpleInternationalString(release));
-                df.transition(DefaultCitation.State.FINAL);
+                df.transitionTo(DefaultCitation.State.FINAL);
                 c = df;
             }
             authority = c;
diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
index ecbc331..d8175b6 100644
--- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -154,16 +154,16 @@
 
     /**
      * Returns the parameters used to open this GeoTIFF data store.
-     * If non-null, the parameters are described by {@link GeoTiffStoreProvider#getOpenParameters()} and contains at
-     * least a parameter named {@value org.apache.sis.storage.DataStoreProvider#LOCATION} with a {@link URI} value.
-     * This method may return {@code null} if the storage input can not be described by a URI
+     * The parameters are described by {@link GeoTiffStoreProvider#getOpenParameters()} and contains at least
+     * a parameter named {@value org.apache.sis.storage.DataStoreProvider#LOCATION} with a {@link URI} value.
+     * The return value may be empty if the storage input can not be described by a URI
      * (for example a GeoTIFF file reading directly from a {@link java.nio.channels.ReadableByteChannel}).
      *
-     * @return parameters used for opening this data store, or {@code null} if not available.
+     * @return parameters used for opening this data store.
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
-        return URIDataStore.parameters(provider, location);
+    public Optional<ParameterValueGroup> getOpenParameters() {
+        return Optional.ofNullable(URIDataStore.parameters(provider, location));
     }
 
     /**
@@ -347,10 +347,10 @@
      * any listener specified for another kind of events will be ignored.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index dafd338..e320940 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -1075,7 +1075,7 @@
         decoder.setSearchPath(searchPath);
         final DefaultMetadata metadata = build(false);
         addCompleteMetadata(createURI(stringValue(METADATA_LINK)));
-        metadata.transition(DefaultMetadata.State.FINAL);
+        metadata.transitionTo(DefaultMetadata.State.FINAL);
         return metadata;
     }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
index 9eed48a..afaf805 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
@@ -129,13 +129,13 @@
      * This method may return {@code null} if the storage input can not be described by a URI
      * (for example a netCDF file reading directly from a {@link java.nio.channels.ReadableByteChannel}).
      *
-     * @return parameters used for opening this data store, or {@code null} if not available.
+     * @return parameters used for opening this data store.
      *
      * @since 0.8
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
-        return URIDataStore.parameters(provider, location);
+    public Optional<ParameterValueGroup> getOpenParameters() {
+        return Optional.ofNullable(URIDataStore.parameters(provider, location));
     }
 
     /**
@@ -221,10 +221,10 @@
      * any listener specified for another kind of events will be ignored.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 
diff --git 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
index 6ef63cf..b22b6d2 100644
--- 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
@@ -135,14 +135,14 @@
      * @return parameters used for opening this data store.
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
+    public Optional<ParameterValueGroup> getOpenParameters() {
         if (provider == null) {
-            return null;
+            return Optional.empty();
         }
         final ParameterValueGroup pg = provider.getOpenParameters().createValue();
         pg.parameter(SQLStoreProvider.LOCATION).setValue(source);
         pg.parameter(SQLStoreProvider.TABLES).setValue(tableNames);
-        return pg;
+        return Optional.of(pg);
     }
 
     /**
@@ -262,10 +262,10 @@
      * any listener specified for another kind of events will be ignored.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
index e4fbc2d..40f2f50 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
@@ -139,10 +139,10 @@
      * (at least the read-only ones) produce no change events.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
index 7f3c2cd..d024582 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
@@ -3046,7 +3046,7 @@
                 md.setMetadataStandards(c);
             }
             if (freeze) {
-                md.transition(DefaultMetadata.State.FINAL);
+                md.transitionTo(DefaultMetadata.State.FINAL);
             }
         }
         return md;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
index 7db0fbb..069e503 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.storage;
 
 import java.net.URI;
+import java.util.Optional;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.FileSystemNotFoundException;
@@ -103,11 +104,11 @@
     /**
      * Returns the parameters used to open this data store.
      *
-     * @return parameters used for opening this {@code DataStore}, or {@code null} if not available.
+     * @return parameters used for opening this {@code DataStore}.
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
-        return parameters(provider, location);
+    public Optional<ParameterValueGroup> getOpenParameters() {
+        return Optional.ofNullable(parameters(provider, location));
     }
 
     /**
@@ -273,10 +274,10 @@
      * (at least the read-only ones) produce no change events.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
index 86582c1..df63841 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
@@ -210,7 +210,7 @@
      * Returns the parameters used to open this data store.
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
+    public Optional<ParameterValueGroup> getOpenParameters() {
         final String format = StoreUtilities.getFormatName(componentProvider);
         final ParameterValueGroup pg = (provider != null ? provider.getOpenParameters() : FolderStoreProvider.PARAMETERS).createValue();
         pg.parameter(DataStoreProvider.LOCATION).setValue(location);
@@ -218,7 +218,7 @@
         if (timezone != null) pg.parameter("timezone").setValue(timezone);
         if (encoding != null) pg.parameter("encoding").setValue(encoding);
         if (format   != null) pg.parameter("format"  ).setValue(format);
-        return pg;
+        return Optional.of(pg);
     }
 
     /**
@@ -409,10 +409,10 @@
      * any listener specified for another kind of events will be ignored.
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
         // If an argument is null, we let the parent class throws (indirectly) NullArgumentException.
         if (listener == null || eventType == null || eventType.isAssignableFrom(WarningEvent.class)) {
-            super.addListener(listener, eventType);
+            super.addListener(eventType, listener);
         }
     }
 
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
index d8bdffd..475c50e 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
@@ -116,7 +116,7 @@
 
     /**
      * Creates a new instance for the given storage (typically file or database).
-     * The {@code provider} argument is an optional information.
+     * The {@code provider} argument is an optional but recommended information.
      * The {@code connector} argument is mandatory.
      *
      * @param  provider   the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
@@ -170,6 +170,10 @@
      * The provider gives additional information on this {@code DataStore} such as a format description
      * and a list of parameters that can be used for opening data stores of the same class.
      *
+     * <p>The return value should never be null if this {@code DataStore} has been created by
+     * {@link DataStores#open(Object)} or by a {@link DataStoreProvider} {@code open(…)} method.
+     * However it may be null if this object has been instantiated by a direct call to its constructor.</p>
+     *
      * @return the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
      *
      * @see #provider
@@ -193,15 +197,15 @@
      *
      * <p>In some cases, for stores reading in-memory data or other inputs that can not fit with
      * {@code ParameterDescriptorGroup} requirements (for example an {@link java.io.InputStream}
-     * connected to unknown or no {@link java.net.URL}), this method may return null.</p>
+     * connected to unknown or no {@link java.net.URL}), this method may return an empty value.</p>
      *
-     * @return parameters used for opening this {@code DataStore}, or {@code null} if not available.
+     * @return parameters used for opening this {@code DataStore}.
      *
      * @see DataStoreProvider#getOpenParameters()
      *
      * @since 0.8
      */
-    public abstract ParameterValueGroup getOpenParameters();
+    public abstract Optional<ParameterValueGroup> getOpenParameters();
 
     /**
      * Sets the locale to use for formatting warnings and other messages.
@@ -346,7 +350,7 @@
      * contact information about the creator or distributor, data quality, update frequency, usage constraints,
      * file format and more.
      *
-     * @return information about resources in the data store, or {@code null} if none.
+     * @return information about resources in the data store. Should not be {@code null}.
      * @throws DataStoreException if an error occurred while reading the data.
      *
      * @see #getIdentifier()
@@ -435,7 +439,7 @@
      * on individual resources of this data store.</p>
      *
      * <p>If this data store may produce events of the given type, then the given listener is kept by strong reference;
-     * it will not be garbage collected unless {@linkplain #removeListener(StoreListener, Class) explicitly removed}
+     * it will not be garbage collected unless {@linkplain #removeListener(Class, StoreListener) explicitly removed}
      * or unless this {@code DataStore} is itself garbage collected. However if the given type of events can never
      * happen with this data store, then this method is not required to keep a reference to the given listener.</p>
      *
@@ -446,14 +450,14 @@
      * warnings in its own way, for example by showing warnings in a widget.
      *
      * @param  <T>        compile-time value of the {@code eventType} argument.
-     * @param  listener   listener to notify about events.
      * @param  eventType  type of {@link StoreEvent} to listen (can not be {@code null}).
+     * @param  listener   listener to notify about events.
      *
      * @since 1.0
      */
     @Override
-    public <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType) {
-        listeners.addListener(listener, eventType);
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
+        listeners.addListener(eventType, listener);
     }
 
     /**
@@ -463,8 +467,8 @@
      * children resources.
      *
      * <p>If the same listener has been registered many times for the same even type, then this method removes only
-     * the most recent registration. In other words if {@code addListener(ls, type)} has been invoked twice, then
-     * {@code removeListener(ls, type)} needs to be invoked twice in order to remove all instances of that listener.
+     * the most recent registration. In other words if {@code addListener(type, ls)} has been invoked twice, then
+     * {@code removeListener(type, ls)} needs to be invoked twice in order to remove all instances of that listener.
      * If the given listener is not found, then this method does nothing (no exception is thrown).</p>
      *
      * <div class="section">Warning events</div>
@@ -473,14 +477,14 @@
      * then this {@code DataStore} will send future warnings to the loggers.
      *
      * @param  <T>        compile-time value of the {@code eventType} argument.
-     * @param  listener   listener to stop notifying about events.
      * @param  eventType  type of {@link StoreEvent} which were listened (can not be {@code null}).
+     * @param  listener   listener to stop notifying about events.
      *
      * @since 1.0
      */
     @Override
-    public <T extends StoreEvent> void removeListener(StoreListener<? super T> listener, Class<T> eventType) {
-        listeners.removeListener(listener, eventType);
+    public <T extends StoreEvent> void removeListener(Class<T> eventType, StoreListener<? super T> listener) {
+        listeners.removeListener(eventType, listener);
     }
 
     /**
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
index fd206c5..d8091d3 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
@@ -199,7 +199,7 @@
      * <p>Implementers are responsible for declaring all parameters and whether they are mandatory or optional.
      * It is recommended to define at least a parameter named {@value #LOCATION}, completed by {@value #CREATE}
      * if the data store supports write operations.
-     * That parameter will be recognized by the default {@code DataStoreProvider} methods and used whenever a
+     * Those parameters will be recognized by the default {@code DataStoreProvider} methods and used whenever a
      * {@link StorageConnector} is required.</p>
      *
      * <div class="note"><b>Alternative:</b>
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
index 85a80f5..d5afc4a 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
@@ -145,7 +145,7 @@
      * on different resources in the same tree, for example a parent and its children.</p>
      *
      * <p>If this resource may produce events of the given type, then the given listener is kept by strong reference;
-     * it will not be garbage collected unless {@linkplain #removeListener(StoreListener, Class) explicitly removed}
+     * it will not be garbage collected unless {@linkplain #removeListener(Class, StoreListener) explicitly removed}
      * or unless this {@code Resource} is itself garbage collected. However if the given type of events can never
      * happen with this resource, then this method is not required to keep a reference to the given listener.</p>
      *
@@ -159,7 +159,7 @@
      * @param  listener   listener to notify about events.
      * @param  eventType  type of {@link StoreEvent} to listen (can not be {@code null}).
      */
-    <T extends StoreEvent> void addListener(StoreListener<? super T> listener, Class<T> eventType);
+    <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener);
 
     /**
      * Unregisters a listener previously added to this resource for the given type of events.
@@ -168,8 +168,8 @@
      * parent resources.
      *
      * <p>If the same listener has been registered many times for the same even type, then this method removes only
-     * the most recent registration. In other words if {@code addListener(ls, type)} has been invoked twice, then
-     * {@code removeListener(ls, type)} needs to be invoked twice in order to remove all instances of that listener.
+     * the most recent registration. In other words if {@code addListener(type, ls)} has been invoked twice, then
+     * {@code removeListener(type, ls)} needs to be invoked twice in order to remove all instances of that listener.
      * If the given listener is not found, then this method does nothing (no exception is thrown).</p>
      *
      * <div class="section">Warning events</div>
@@ -181,5 +181,5 @@
      * @param  listener   listener to stop notifying about events.
      * @param  eventType  type of {@link StoreEvent} which were listened (can not be {@code null}).
      */
-    <T extends StoreEvent> void removeListener(StoreListener<? super T> listener, Class<T> eventType);
+    <T extends StoreEvent> void removeListener(Class<T> eventType, StoreListener<? super T> listener);
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListener.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListener.java
index 7d49d22..9be960b 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListener.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListener.java
@@ -28,7 +28,7 @@
  *
  * <p>{@link Resource} implementations are responsible for instantiating the most specific
  * {@code StoreEvent} subclass for the type of events. Then, all {@code StoreListener}s that
- * {@linkplain Resource#addListener(StoreListener, Class) declared an interest} for
+ * {@linkplain Resource#addListener(Class, StoreListener) declared an interest} for
  * {@code StoreEvent}s of that kind are notified, including listeners in parent resources.
  * Each listener is notified only once per event even if the listener is registered twice.</p>
  *
@@ -38,7 +38,7 @@
  * @param  <T>  the type of events of interest to this listener.
  *
  * @see StoreEvent
- * @see Resource#addListener(StoreListener, Class)
+ * @see Resource#addListener(Class, StoreListener)
  *
  * @since 1.0
  * @module
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
index 2e18ac1..2eb6f12 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
@@ -531,13 +531,13 @@
      * warnings in its own way, for example by showing warnings in a widget.
      *
      * @param  <T>        compile-time value of the {@code eventType} argument.
-     * @param  listener   listener to notify about events.
      * @param  eventType  type of {@link StoreEvent} to listen (can not be {@code null}).
+     * @param  listener   listener to notify about events.
      *
-     * @see Resource#addListener(StoreListener, Class)
+     * @see Resource#addListener(Class, StoreListener)
      */
     @SuppressWarnings("unchecked")
-    public synchronized <T extends StoreEvent> void addListener(final StoreListener<? super T> listener, final Class<T> eventType) {
+    public synchronized <T extends StoreEvent> void addListener(final Class<T> eventType, final StoreListener<? super T> listener) {
         ArgumentChecks.ensureNonNull("listener",  listener);
         ArgumentChecks.ensureNonNull("eventType", eventType);
         ForType<T> ce = null;
@@ -561,8 +561,8 @@
      * parent manager.
      *
      * <p>If the same listener has been registered many times for the same even type, then this method removes only
-     * the most recent registration. In other words if {@code addListener(ls, type)} has been invoked twice, then
-     * {@code removeListener(ls, type)} needs to be invoked twice in order to remove all instances of that listener.
+     * the most recent registration. In other words if {@code addListener(type, ls)} has been invoked twice, then
+     * {@code removeListener(type, ls)} needs to be invoked twice in order to remove all instances of that listener.
      * If the given listener is not found, then this method does nothing (no exception is thrown).</p>
      *
      * <div class="section">Warning events</div>
@@ -571,13 +571,13 @@
      * to the loggers.
      *
      * @param  <T>        compile-time value of the {@code eventType} argument.
-     * @param  listener   listener to stop notifying about events.
      * @param  eventType  type of {@link StoreEvent} which were listened (can not be {@code null}).
+     * @param  listener   listener to stop notifying about events.
      *
-     * @see Resource#removeListener(StoreListener, Class)
+     * @see Resource#removeListener(Class, StoreListener)
      */
     @SuppressWarnings("unchecked")
-    public synchronized <T extends StoreEvent> void removeListener(StoreListener<? super T> listener, Class<T> eventType) {
+    public synchronized <T extends StoreEvent> void removeListener(Class<T> eventType, StoreListener<? super T> listener) {
         ArgumentChecks.ensureNonNull("listener",  listener);
         ArgumentChecks.ensureNonNull("eventType", eventType);
         for (ForType<?> e = listeners; e != null; e = e.next) {
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreMock.java b/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreMock.java
index cbbce51..d14b8c5 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreMock.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreMock.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Optional;
 import org.opengis.metadata.Metadata;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.storage.event.StoreListeners;
@@ -53,11 +54,11 @@
     }
 
     /**
-     * Returns {@code null} since there is no open parameters.
+     * Returns empty optional since there is no open parameters.
      */
     @Override
-    public ParameterValueGroup getOpenParameters() {
-        return null;
+    public Optional<ParameterValueGroup> getOpenParameters() {
+        return Optional.empty();
     }
 
     /**
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/storage/event/StoreListenersTest.java b/storage/sis-storage/src/test/java/org/apache/sis/storage/event/StoreListenersTest.java
index 9185879..7d1fc6d 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/event/StoreListenersTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/event/StoreListenersTest.java
@@ -66,18 +66,18 @@
     }
 
     /**
-     * Tests {@link StoreListeners#addListener(StoreListener, Class)} followed by
-     * {@link StoreListeners#removeListener(StoreListener, Class)}.
+     * Tests {@link StoreListeners#addListener(Class, StoreListener)} followed by
+     * {@link StoreListeners#removeListener(Class, StoreListener)}.
      */
     @Test
     public void testAddAndRemoveStoreListener() {
         final StoreListeners listeners = store.listeners();
         assertFalse("hasListeners()", listeners.hasListeners(WarningEvent.class));
-        listeners.addListener(this, WarningEvent.class);
+        listeners.addListener(WarningEvent.class, this);
         assertTrue("hasListeners()", listeners.hasListeners(WarningEvent.class));
-        listeners.removeListener(this, WarningEvent.class);
+        listeners.removeListener(WarningEvent.class, this);
         assertFalse("hasListeners()", listeners.hasListeners(WarningEvent.class));
-        listeners.removeListener(this, WarningEvent.class);         // Should be no-op.
+        listeners.removeListener(WarningEvent.class, this);         // Should be no-op.
     }
 
     /**
@@ -87,7 +87,7 @@
     @DependsOnMethod("testAddAndRemoveStoreListener")
     public void testWarning() {
         final LogRecord record = new LogRecord(Level.WARNING, "The message");
-        store.addListener(this, WarningEvent.class);
+        store.addListener(WarningEvent.class, this);
         store.listeners().warning(record);
         assertSame(record, warning);
     }
@@ -99,7 +99,7 @@
     @Test
     @DependsOnMethod("testWarning")
     public void testWarningWithAutoSource() {
-        store.addListener(this, WarningEvent.class);
+        store.addListener(WarningEvent.class, this);
         store.simulateWarning("The message");
         assertNotNull("Listener has not been notified.", warning);
         assertEquals(DataStoreMock.class.getName(), warning.getSourceClassName());