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

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new e723adca3d Resolve a few compiler warnings.
e723adca3d is described below

commit e723adca3d03f6ec2fa40fcd99ec90304ab31da4
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Jul 11 11:41:24 2024 +0200

    Resolve a few compiler warnings.
---
 .../apache/sis/coverage/grid/GridCoverage2D.java   |   1 +
 .../sis/feature/builder/FeatureTypeBuilder.java    |   1 +
 .../main/org/apache/sis/image/ComputedImage.java   |   1 +
 .../apache/sis/metadata/ModifiableMetadata.java    | 102 ++++++++++-----------
 .../apache/sis/metadata/iso/DefaultMetadata.java   |   1 -
 .../sis/metadata/iso/acquisition/DefaultEvent.java |   1 -
 .../iso/acquisition/DefaultRequirement.java        |   1 -
 .../DefaultDigitalTransferOptions.java             |   1 -
 .../sis/metadata/iso/extent/DefaultExtent.java     |   2 -
 .../iso/identification/AbstractIdentification.java |  16 +++-
 .../identification/DefaultDataIdentification.java  |   5 +-
 .../metadata/iso/identification/DefaultUsage.java  |   2 -
 .../metadata/iso/lineage/DefaultProcessStep.java   |   1 -
 .../maintenance/DefaultMaintenanceInformation.java |   1 -
 .../org/apache/sis/util/iso/DefaultTypeName.java   |  15 ++-
 .../main/org/apache/sis/util/iso/Names.java        |  36 ++++----
 .../main/org/apache/sis/util/iso/TypeNames.java    |   8 --
 .../sis/parameter/DefaultParameterDescriptor.java  |   2 +-
 .../apache/sis/referencing/NamedIdentifier.java    |   1 +
 .../sis/referencing/factory/sql/EPSGFactory.java   |   4 +-
 .../operation/transform/InterpolatedTransform.java |   2 +-
 .../sis/referencing/privy/AffineTransform2D.java   |   4 +
 .../sis/referencing/ImmutableIdentifierTest.java   |   4 +-
 .../apache/sis/storage/landsat/LandsatStore.java   |   1 +
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |   1 +
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |   1 +
 .../org/apache/sis/io/stream/ChannelDataInput.java |   1 +
 .../apache/sis/storage/CanNotProbeException.java   |   1 +
 .../main/org/apache/sis/storage/DataStore.java     |   3 +
 .../src/org.apache.sis.util/main/module-info.java  |   3 +-
 .../main/org/apache/sis/pending/jdk/JDK19.java     |  21 +++++
 .../org/apache/sis/system/OptionalDependency.java  |   1 +
 .../test/org/apache/sis/util/LocalesTest.java      |  17 ++--
 .../apache/sis/gui/coverage/BandRangeTable.java    |   1 +
 .../apache/sis/gui/coverage/GridSliceSelector.java |   1 +
 .../main/org/apache/sis/gui/coverage/GridView.java |   1 +
 .../sis/gui/coverage/ImagePropertyExplorer.java    |   3 +-
 .../org/apache/sis/gui/dataset/FeatureTable.java   |   3 +
 .../main/org/apache/sis/gui/dataset/LogViewer.java |   1 +
 .../apache/sis/gui/dataset/ResourceExplorer.java   |   1 +
 .../org/apache/sis/gui/dataset/ResourceTree.java   |   8 +-
 .../org/apache/sis/gui/internal/LogHandler.java    |   2 +-
 .../apache/sis/gui/internal/io/FileAccessView.java |   1 +
 .../org/apache/sis/gui/map/GestureFollower.java    |   1 +
 .../main/org/apache/sis/gui/map/StatusBar.java     |   1 +
 .../apache/sis/gui/metadata/MetadataSummary.java   |   1 +
 .../sis/gui/metadata/StandardMetadataTree.java     |   1 +
 .../gui/referencing/RecentReferenceSystems.java    |   1 +
 48 files changed, 169 insertions(+), 120 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
index e7c53d1b96..ef9342082c 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
@@ -183,6 +183,7 @@ public class GridCoverage2D extends GridCoverage {
      *
      * @since 1.2
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public GridCoverage2D(final GridCoverage source, RenderedImage data) {
         super(source, source.getGridGeometry());
         this.data = data = unwrapIfSameSize(Objects.requireNonNull(data));
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/builder/FeatureTypeBuilder.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/builder/FeatureTypeBuilder.java
index 78bd67f66c..575b5d72ed 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/builder/FeatureTypeBuilder.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/builder/FeatureTypeBuilder.java
@@ -210,6 +210,7 @@ public class FeatureTypeBuilder extends TypeBuilder {
      *
      * @see #setAll(FeatureType)
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public FeatureTypeBuilder(final FeatureType template) {
         this(null, null, null);
         if (template != null) {
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ComputedImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ComputedImage.java
index 14d9327062..3e5fa5fa56 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ComputedImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ComputedImage.java
@@ -223,6 +223,7 @@ public abstract class ComputedImage extends PlanarImage 
implements Disposable {
      * @param  sampleModel  the sample model shared by all tiles in this image.
      * @param  sources      sources of this image (may be an empty array), or 
a null array if unknown.
      */
+    @SuppressWarnings("this-escape")        // `this` escaped as weak 
reference only.
     protected ComputedImage(final SampleModel sampleModel, RenderedImage... 
sources) {
         this.sampleModel = Objects.requireNonNull(sampleModel);
         /*
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/ModifiableMetadata.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/ModifiableMetadata.java
index c04139e60f..778b3a450c 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/ModifiableMetadata.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/ModifiableMetadata.java
@@ -26,7 +26,6 @@ import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Locale;
 import java.util.Currency;
-import java.util.NoSuchElementException;
 import java.lang.reflect.Modifier;
 import java.nio.charset.Charset;
 import jakarta.xml.bind.annotation.XmlTransient;
@@ -419,10 +418,10 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * @see #nonNullList(List, Class)
      */
     @SuppressWarnings("unchecked")
-    protected final <E> List<E> writeList(Collection<? extends E> source, 
List<E> target,
-            Class<E> elementType) throws UnmodifiableMetadataException
+    protected final <E> List<E> writeList(Collection<? extends E> source, 
List<E> target, Class<E> elementType)
+            throws UnmodifiableMetadataException
     {
-        return (List<E>) write(source, target, elementType, Boolean.FALSE);
+        return (List<E>) write(source, target, elementType, List.class);
     }
 
     /**
@@ -447,10 +446,10 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      *
      * @see #nonNullSet(Set, Class)
      */
-    protected final <E> Set<E> writeSet(Collection<? extends E> source, Set<E> 
target,
-            Class<E> elementType) throws UnmodifiableMetadataException
+    protected final <E> Set<E> writeSet(Collection<? extends E> source, Set<E> 
target, Class<E> elementType)
+            throws UnmodifiableMetadataException
     {
-        return (Set<E>) write(source, target, elementType, Boolean.TRUE);
+        return (Set<E>) write(source, target, elementType, Set.class);
     }
 
     /**
@@ -481,8 +480,8 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      *         or {@code null} if the source was null.
      * @throws UnmodifiableMetadataException if this metadata is unmodifiable.
      */
-    protected final <E> Collection<E> writeCollection(Collection<? extends E> 
source, Collection<E> target,
-            Class<E> elementType) throws UnmodifiableMetadataException
+    protected final <E> Collection<E> writeCollection(Collection<? extends E> 
source, Collection<E> target, Class<E> elementType)
+            throws UnmodifiableMetadataException
     {
         return write(source, target, elementType, null);
     }
@@ -491,12 +490,11 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * Writes the content of the {@code source} collection into the {@code 
target} list or set,
      * creating it if needed.
      *
-     * @param  useSet  {@link Boolean#TRUE} for creating a set, {@link 
Boolean#FALSE} for creating a list,
-     *                 or null for automatic choice.
+     * @param  collectionType  {@code Set.class}, {@code List.class} or null 
for automatic choice.
      */
     @SuppressWarnings("unchecked")
     private <E> Collection<E> write(final Collection<? extends E> source, 
Collection<E> target,
-            final Class<E> elementType, Boolean useSet) throws 
UnmodifiableMetadataException
+            final Class<E> elementType, Class<?> collectionType) throws 
UnmodifiableMetadataException
     {
         /*
          * It is not worth to copy the content if the current and the new 
instance are the
@@ -510,7 +508,7 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
                  * 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;
+                assert (collectionType != null) || 
collectionType(elementType).isInstance(source) : elementType;
                 return (Collection<E>) source;
             }
             checkWritePermission(valueIfDefined(target));
@@ -524,18 +522,20 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
                 if (target != null && state != COMPLETABLE) {
                     target.clear();
                 } else {
-                    if (useSet == null) {
-                        useSet = useSet(elementType);
+                    if (collectionType == null) {
+                        collectionType = collectionType(elementType);
                     }
-                    if (useSet) {
+                    if (collectionType == Set.class) {
                         target = createSet(elementType, source);
-                    } else {
+                    } else if (collectionType == List.class) {
                         target = createList(elementType, source);
+                    } else {
+                        throw new 
UnsupportedOperationException(Errors.format(Errors.Keys.UnsupportedType_1, 
collectionType));
                     }
                 }
                 target.addAll(source);
                 if (state == COMPLETABLE) {
-                    if (useSet) {
+                    if (collectionType == Set.class) {
                         target = CollectionsExt.unmodifiableOrCopy((Set<E>) 
target);
                     } else {
                         target = CollectionsExt.unmodifiableOrCopy((List<E>) 
target);
@@ -612,7 +612,7 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * @return a list containing the {@code source} elements,
      *         or {@code null} if the source was null or empty.
      */
-    protected final <E> List<E> copyList(final Collection<? extends E> source, 
final Class<E> elementType) {
+    protected static <E> List<E> copyList(final Collection<? extends E> 
source, final Class<E> elementType) {
         if (isNullOrEmpty(source)) {
             return null;
         }
@@ -632,7 +632,7 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * @return a set containing the {@code source} elements,
      *         or {@code null} if the source was null or empty.
      */
-    protected final <E> Set<E> copySet(final Collection<? extends E> source, 
final Class<E> elementType) {
+    protected static <E> Set<E> copySet(final Collection<? extends E> source, 
final Class<E> elementType) {
         if (isNullOrEmpty(source)) {
             return null;
         }
@@ -646,16 +646,13 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * or returns {@code null} if the source is {@code null} or empty.
      * This is a convenience method for copying fields in subclass copy 
constructors.
      *
-     * <p>The collection type is selected as described in the
-     * {@link #nonNullCollection(Collection, Class)}.</p>
-     *
      * @param  <E>          the type represented by the {@code Class} argument.
      * @param  source       the source collection, or {@code null}.
      * @param  elementType  the base type of elements to put in the collection.
      * @return a collection containing the {@code source} elements,
      *         or {@code null} if the source was null or empty.
      */
-    protected final <E> Collection<E> copyCollection(final Collection<? 
extends E> source, final Class<E> elementType) {
+    protected static <E> Collection<E> copyCollection(final Collection<? 
extends E> source, final Class<E> elementType) {
         if (isNullOrEmpty(source)) {
             return null;
         }
@@ -683,7 +680,7 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      *
      * @since 1.0
      */
-    protected final <K,V> Map<K,V> copyMap(final Map<? extends K, ? extends V> 
source, final Class<K> keyType) {
+    protected static <K,V> Map<K,V> copyMap(final Map<? extends K, ? extends 
V> source, final Class<K> keyType) {
         if (isNullOrEmpty(source)) {
             return null;
         }
@@ -696,16 +693,13 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * Creates a singleton list or set containing only the given value, if 
non-null.
      * This is a convenience method for initializing fields in subclass 
constructors.
      *
-     * <p>The collection type is selected as described in the
-     * {@link #nonNullCollection(Collection, Class)}.</p>
-     *
      * @param  <E>          the type represented by the {@code Class} argument.
      * @param  value        the singleton value to put in the returned 
collection, or {@code null}.
      * @param  elementType  the element type (used only if {@code value} is 
non-null).
      * @return a new modifiable collection containing the given value,
      *         or {@code null} if the given value was null.
      */
-    protected final <E> Collection<E> singleton(final E value, final Class<E> 
elementType) {
+    protected static <E> Collection<E> singleton(final E value, final Class<E> 
elementType) {
         if (value == null) {
             return null;
         }
@@ -799,18 +793,21 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
             return null;
         }
         final boolean isModifiable = (state < FREEZING);
-        if (useSet(elementType)) {
+        final Class<?> collectionType = collectionType(elementType);
+        if (collectionType == Set.class) {
             if (isModifiable) {
                 return createSet(elementType, current);         // `current` 
given as a matter of principle even if null.
             } else {
                 return Collections.emptySet();
             }
-        } else {
+        } else if (collectionType == List.class) {
             if (isModifiable) {
                 return createList(elementType, current);        // `current` 
given as a matter of principle even if null.
             } else {
                 return Collections.emptyList();
             }
+        } else {
+            throw new 
UnsupportedOperationException(Errors.format(Errors.Keys.UnsupportedType_1, 
collectionType));
         }
     }
 
@@ -906,46 +903,39 @@ public abstract class ModifiableMetadata extends 
AbstractMetadata {
      * Returns {@code true} if we should use a {@link Set} instead of a {@link 
List}
      * for elements of the given type.
      */
-    private <E> boolean useSet(final Class<E> elementType) {
-        final Class<?> type = collectionType(elementType);
-        if (Set .class == type) return true;
-        if (List.class == type) return false;
-        throw new 
NoSuchElementException(Errors.format(Errors.Keys.UnsupportedType_1, type));
+    private static boolean useSet(final Class<?> elementType) {
+        return CodeList.class.isAssignableFrom(elementType)
+                ||          Enum.class.isAssignableFrom(elementType)
+                ||       Charset.class.isAssignableFrom(elementType)
+                ||        String.class ==               elementType
+                ||        Locale.class ==               elementType
+                ||      Currency.class ==               elementType;
     }
 
     /**
      * Returns the type of collection to use for the given type. The current 
implementation can
      * return only two values: <code>{@linkplain Set}.class</code> if the 
property should not
-     * accept duplicated values, or <code>{@linkplain List}.class</code> 
otherwise. Future SIS
-     * versions may accept other types.
+     * accept duplicated values, or <code>{@linkplain List}.class</code> 
otherwise.
+     * Future SIS versions may accept other types.
      *
-     * <p>The default implementation returns <code>{@linkplain 
Set}.class</code> if the element type
-     * is assignable to {@link CodeList}, {@link Enum}, {@link String}, {@link 
Charset},
+     * <p>The default implementation returns <code>{@linkplain 
Set}.class</code> if the element
+     * type is assignable to {@link CodeList}, {@link Enum}, {@link String}, 
{@link Charset},
      * {@link Locale} or {@link Currency}, and <code>{@linkplain 
List}.class</code> otherwise.
      * Subclasses can override this method for choosing different kind of 
collections.
-     *
-     * <h4>Constraints</h4>
-     * Implementations should comply to the following constraints:
-     * <ul>
-     *   <li><em>This method may be invoked (indirectly) at construction 
time.</em>
-     *        Therefor, the implementation should not depend on the object 
state.</li>
-     *   <li><em>The {@link Set} type should be returned only when the set 
elements are immutable.</em>
-     *        This is needed for {@linkplain Object#hashCode() hash code} 
stability.</li>
-     * </ul>
+     * As a general rule, implementations should return the {@link Set} type
+     * only when the set elements are immutable.
+     * This is needed for {@linkplain Object#hashCode() hash code} 
stability.</p>
      *
      * @param  <E>          the type of elements in the collection to be 
created.
      * @param  elementType  the type of elements in the collection to be 
created.
      * @return {@code List.class} or {@code Set.class} depending on whether the
      *         property shall accept duplicated values or not.
+     *
+     * @deprecated This method will be removed because it can cause {@code 
this} to escape at construction time.
      */
+    @Deprecated(since="1.5", forRemoval=true)
     @SuppressWarnings({"rawtypes","unchecked"})
     protected <E> Class<? extends Collection<E>> collectionType(final Class<E> 
elementType) {
-        return (Class) (CodeList.class.isAssignableFrom(elementType)
-                ||          Enum.class.isAssignableFrom(elementType)
-                ||       Charset.class.isAssignableFrom(elementType)
-                ||        String.class ==               elementType
-                ||        Locale.class ==               elementType
-                ||      Currency.class ==               elementType
-                ? Set.class : List.class);
+        return (Class) (useSet(elementType) ? Set.class : List.class);
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
index 5ba20d67fb..3c129ac183 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
@@ -374,7 +374,6 @@ public class DefaultMetadata extends ISOMetadata implements 
Metadata {
      *
      * @since 1.5
      */
-    @SuppressWarnings("this-escape")
     public DefaultMetadata(final Responsibility contact,
                            final Temporal       dateStamp,
                            final Identification identificationInfo)
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
index 732bc85b94..13177edc30 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
@@ -131,7 +131,6 @@ public class DefaultEvent extends ISOMetadata implements 
Event {
      *
      * @see #castOrCopy(Event)
      */
-    @SuppressWarnings("this-escape")
     public DefaultEvent(final Event object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
index 355c09c9b7..d0ed5d144f 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
@@ -141,7 +141,6 @@ public class DefaultRequirement extends ISOMetadata 
implements Requirement {
      *
      * @see #castOrCopy(Requirement)
      */
-    @SuppressWarnings("this-escape")
     public DefaultRequirement(final Requirement object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDigitalTransferOptions.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDigitalTransferOptions.java
index 06708bb349..d660af725c 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDigitalTransferOptions.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDigitalTransferOptions.java
@@ -128,7 +128,6 @@ public class DefaultDigitalTransferOptions extends 
ISOMetadata implements Digita
      *
      * @see #castOrCopy(DigitalTransferOptions)
      */
-    @SuppressWarnings("this-escape")
     public DefaultDigitalTransferOptions(final DigitalTransferOptions object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultExtent.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultExtent.java
index d89ea059ba..54c8d8c8f6 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultExtent.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultExtent.java
@@ -144,7 +144,6 @@ public class DefaultExtent extends ISOMetadata implements 
Extent {
      * @param  verticalElements    a vertical component, or {@code null} if 
none.
      * @param  temporalElements    a temporal component, or {@code null} if 
none.
      */
-    @SuppressWarnings("this-escape")
     public DefaultExtent(final CharSequence     description,
                          final GeographicExtent geographicElements,
                          final VerticalExtent   verticalElements,
@@ -165,7 +164,6 @@ public class DefaultExtent extends ISOMetadata implements 
Extent {
      *
      * @see #castOrCopy(Extent)
      */
-    @SuppressWarnings("this-escape")
     public DefaultExtent(final Extent object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/AbstractIdentification.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/AbstractIdentification.java
index f6d67b7bc1..f7ebb85ecd 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/AbstractIdentification.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/AbstractIdentification.java
@@ -268,6 +268,21 @@ public class AbstractIdentification extends ISOMetadata 
implements Identificatio
         this.abstracts = Types.toInternationalString(abstracts);
     }
 
+    /**
+     * Creates an identification initialized to the specified values.
+     *
+     * @param citation       the citation data for the resource(s), or {@code 
null} if none.
+     * @param abstracts      a brief narrative summary of the content of the 
resource(s), or {@code null} if none.
+     * @param topicCategory  the main theme of the dataset, or {@code null} if 
none.
+     *
+     * @since 1.5
+     */
+    public AbstractIdentification(final Citation citation, final CharSequence 
abstracts, final TopicCategory topicCategory) {
+        this.citation = citation;
+        this.abstracts = Types.toInternationalString(abstracts);
+        topicCategories = singleton(topicCategory, TopicCategory.class);
+    }
+
     /**
      * Constructs a new instance initialized with the values from the 
specified metadata object.
      * This is a <em>shallow</em> copy constructor, because the other metadata 
contained in the
@@ -277,7 +292,6 @@ public class AbstractIdentification extends ISOMetadata 
implements Identificatio
      *
      * @see #castOrCopy(Identification)
      */
-    @SuppressWarnings("this-escape")
     public AbstractIdentification(final Identification object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
index 15b7bf2ff2..7eccb4056d 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
@@ -133,11 +133,10 @@ public class DefaultDataIdentification extends 
AbstractIdentification implements
                                      final Locale language,
                                      final TopicCategory topicCategory)
     {
-        super(citation, abstracts);
+        super(citation, abstracts, topicCategory);
         if (language != null) {
-            locales = writeMap(Collections.singletonMap(language, null), null, 
Locale.class);
+            locales = copyMap(Collections.singletonMap(language, null), 
Locale.class);
         }
-        super.setTopicCategories(singleton(topicCategory, 
TopicCategory.class));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
index 842b4ee063..40a57128ab 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
@@ -145,7 +145,6 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
      * @param specificUsage    brief description of the resource and/or 
resource series usage, or {@code null} if none.
      * @param userContactInfo  means of communicating with person(s) and 
organization(s), or {@code null} if none.
      */
-    @SuppressWarnings("this-escape")
     public DefaultUsage(final CharSequence specificUsage,
                         final Responsibility userContactInfo)
     {
@@ -162,7 +161,6 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
      *
      * @see #castOrCopy(Usage)
      */
-    @SuppressWarnings("this-escape")
     public DefaultUsage(final Usage object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
index d1b49d4ca5..5e80d2de7e 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
@@ -180,7 +180,6 @@ public class DefaultProcessStep extends ISOMetadata 
implements ProcessStep {
      *
      * @see #castOrCopy(ProcessStep)
      */
-    @SuppressWarnings("this-escape")
     public DefaultProcessStep(final ProcessStep object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
index 226e4e63e9..0435e8672e 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
@@ -152,7 +152,6 @@ public class DefaultMaintenanceInformation extends 
ISOMetadata implements Mainte
      *
      * @see #castOrCopy(MaintenanceInformation)
      */
-    @SuppressWarnings("this-escape")
     public DefaultMaintenanceInformation(final MaintenanceInformation object) {
         super(object);
         if (object != null) {
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultTypeName.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultTypeName.java
index 365d02d874..38350caa01 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultTypeName.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultTypeName.java
@@ -24,6 +24,7 @@ import jakarta.xml.bind.annotation.XmlRootElement;
 import org.opengis.util.TypeName;
 import org.opengis.util.NameSpace;
 import org.apache.sis.util.UnknownNameException;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -133,7 +134,7 @@ import org.apache.sis.util.UnknownNameException;
  * @author  Guilhem Legal (Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.5
  *
  * @see DefaultMemberName
  * @see DefaultNameFactory
@@ -197,16 +198,20 @@ public class DefaultTypeName extends DefaultLocalName 
implements TypeName {
      *
      * @see DefaultNameFactory#createTypeName(NameSpace, CharSequence)
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     protected DefaultTypeName(final NameSpace scope, final CharSequence name) 
throws UnknownNameException {
         super(scope, name);
+        ClassNotFoundException cause;
         try {
             javaType = TypeNames.toClass(TypeNames.namespace(scope), 
super.toString());
+            if (javaType != Void.TYPE) {
+                return;
+            }
+            cause = null;
         } catch (ClassNotFoundException e) {
-            throw new 
UnknownNameException(TypeNames.unknown(super.toFullyQualifiedName()), e);
-        }
-        if (javaType == Void.TYPE) {
-            throw new 
UnknownNameException(TypeNames.unknown(super.toFullyQualifiedName()));
+            cause = e;
         }
+        throw new 
UnknownNameException(Errors.format(Errors.Keys.UnknownType_1, 
super.toFullyQualifiedName()), cause);
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/Names.java 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/Names.java
index 80709bb95a..50ee62a5b4 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/Names.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/Names.java
@@ -27,9 +27,10 @@ import org.opengis.util.NameSpace;
 import org.opengis.util.NameFactory;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.OptionalCandidate;
 import org.apache.sis.util.UnknownNameException;
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -130,7 +131,7 @@ public final class Names extends Static {
      * @todo Bug in current implementation: the {@code separator} argument is 
ignored if {@code namespace} is null.
      */
     public static GenericName parseGenericName(final CharSequence namespace, 
final String separator, final CharSequence scopedName) {
-        ensureNonNull("localPart", scopedName);
+        ArgumentChecks.ensureNonNull("localPart", scopedName);
         final NameFactory factory = DefaultNameFactory.provider();
         return factory.parseGenericName(createNameSpace(factory, namespace, 
separator), scopedName);
     }
@@ -151,7 +152,7 @@ public final class Names extends Static {
      * @since 1.0
      */
     public static GenericName createGenericName(final CharSequence namespace, 
final String separator, final CharSequence... parsedNames) {
-        ensureNonNull("parsedNames", parsedNames);
+        ArgumentChecks.ensureNonNull("parsedNames", parsedNames);
         final NameFactory factory = DefaultNameFactory.provider();
         return factory.createGenericName(createNameSpace(factory, namespace, 
separator), parsedNames);
     }
@@ -220,7 +221,7 @@ public final class Names extends Static {
      * @see DefaultNameFactory#createLocalName(NameSpace, CharSequence)
      */
     public static LocalName createLocalName(final CharSequence namespace, 
final String separator, final CharSequence localPart) {
-        ensureNonNull("localPart", localPart);
+        ArgumentChecks.ensureNonNull("localPart", localPart);
         final NameFactory factory = DefaultNameFactory.provider();
         return factory.createLocalName(createNameSpace(factory, namespace, 
separator), localPart);
     }
@@ -249,7 +250,7 @@ public final class Names extends Static {
      * @see DefaultNameFactory#createTypeName(NameSpace, CharSequence)
      */
     public static TypeName createTypeName(final CharSequence namespace, final 
String separator, final CharSequence localPart) {
-        ensureNonNull("localPart", localPart);
+        ArgumentChecks.ensureNonNull("localPart", localPart);
         final NameFactory factory = DefaultNameFactory.provider();
         return factory.createTypeName(createNameSpace(factory, namespace, 
separator), localPart);
     }
@@ -268,7 +269,7 @@ public final class Names extends Static {
      * @since 1.3
      */
     public static TypeName createTypeName(final Class<?> valueClass) {
-        ensureNonNull("valueClass", valueClass);
+        ArgumentChecks.ensureNonNull("valueClass", valueClass);
         final var factory = DefaultNameFactory.provider();
         return factory.toTypeName(valueClass);    // SIS-specific method.
     }
@@ -306,8 +307,8 @@ public final class Names extends Static {
     public static MemberName createMemberName(final CharSequence namespace, 
final String separator,
             final CharSequence localPart, final Class<?> valueClass)
     {
-        ensureNonNull("localPart",  localPart);
-        ensureNonNull("valueClass", valueClass);
+        ArgumentChecks.ensureNonNull("localPart",  localPart);
+        ArgumentChecks.ensureNonNull("valueClass", valueClass);
         final var factory = DefaultNameFactory.provider();
         return factory.createMemberName(createNameSpace(factory, namespace, 
separator), localPart,
                factory.toTypeName(valueClass));     // SIS-specific method.
@@ -330,8 +331,8 @@ public final class Names extends Static {
     public static MemberName createMemberName(final CharSequence namespace, 
final String separator,
             final CharSequence localPart, final TypeName attributeType)
     {
-        ensureNonNull("localPart", localPart);
-        ensureNonNull("attributeType", attributeType);
+        ArgumentChecks.ensureNonNull("localPart", localPart);
+        ArgumentChecks.ensureNonNull("attributeType", attributeType);
         final NameFactory factory = DefaultNameFactory.provider();
         return factory.createMemberName(createNameSpace(factory, namespace, 
separator), localPart, attributeType);
     }
@@ -425,16 +426,17 @@ public final class Names extends Static {
         if (t instanceof Class<?>) {
             return (Class<?>) t;
         }
-        final Class<?> c;
+        ClassNotFoundException cause;
         try {
-            c = TypeNames.toClass(TypeNames.namespace(type.scope()), 
type.toString());
+            final Class<?> c = 
TypeNames.toClass(TypeNames.namespace(type.scope()), type.toString());
+            if (c != Void.TYPE) {
+                return c;
+            }
+            cause = null;
         } catch (ClassNotFoundException e) {
-            throw new UnknownNameException(TypeNames.unknown(type), e);
-        }
-        if (c == Void.TYPE) {
-            throw new UnknownNameException(TypeNames.unknown(type));
+            cause = e;
         }
-        return c;
+        throw new 
UnknownNameException(Errors.format(Errors.Keys.UnknownType_1, 
type.toFullyQualifiedName()), cause);
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/TypeNames.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/TypeNames.java
index 1248723b11..5834626455 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/TypeNames.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/TypeNames.java
@@ -195,12 +195,4 @@ search: if 
(CharSequence.class.isAssignableFrom(valueClass)) {
         }
         return null;
     }
-
-    /**
-     * Formats the error message for an unknown type.
-     * This is a helper method for callers of {@link #toClass(String, String)}.
-     */
-    static String unknown(final GenericName name) {
-        return Errors.format(Errors.Keys.UnknownType_1, 
name.toFullyQualifiedName());
-    }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterDescriptor.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterDescriptor.java
index 49c412f944..5f99053939 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterDescriptor.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterDescriptor.java
@@ -193,7 +193,7 @@ public class DefaultParameterDescriptor<T> extends 
AbstractParameterDescriptor i
      *                       from the code list or enumeration are valid.
      * @param defaultValue   the default value for the parameter, or {@code 
null} if none.
      */
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({"this-escape", "unchecked"})
     public DefaultParameterDescriptor(final Map<String,?> properties,
                                       final int           minimumOccurs,
                                       final int           maximumOccurs,
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/NamedIdentifier.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/NamedIdentifier.java
index a0fd578825..604c7c5e0d 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/NamedIdentifier.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/NamedIdentifier.java
@@ -225,6 +225,7 @@ public class NamedIdentifier extends ImmutableIdentifier 
implements GenericName
      *          identifier code or name, optionally from a controlled list or 
pattern defined by the authority.
      *          The code cannot be null.
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public NamedIdentifier(final Citation authority, final CharSequence code) {
         super(authority, Citations.toCodeSpace(authority), toString(code));
         if (code instanceof InternationalString) {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
index c64120e50a..244b0bf26b 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java
@@ -248,13 +248,15 @@ public class EPSGFactory extends 
ConcurrentAuthorityFactory<EPSGDataAccess> impl
      * @throws IllegalArgumentException if a property value is invalid.
      * @throws FactoryException if an error occurred while creating the EPSG 
factory.
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public EPSGFactory(Map<String,?> properties) throws FactoryException {
         super(EPSGDataAccess.class);
         if (properties == null) {
             properties = Map.of();
         }
-        DataSource ds  = (DataSource)                 
properties.get("dataSource");
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         Locale locale  = (Locale)                     properties.get("locale");
+        DataSource ds  = (DataSource)                 
properties.get("dataSource");
         schema         = (String)                     properties.get("schema");
         catalog        = (String)                     
properties.get("catalog");
         scriptProvider = (InstallationScriptProvider) 
properties.get("scriptProvider");
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
index 48b93f16e0..b2e3d12694 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java
@@ -127,7 +127,7 @@ public class InterpolatedTransform extends 
DatumShiftTransform {
      *
      * @see #createGeodeticTransformation(MathTransformFactory, DatumShiftGrid)
      */
-    @SuppressWarnings("fallthrough")
+    @SuppressWarnings({"this-escape", "fallthrough"})       // `this` appears 
in a cyclic graph.
     protected <T extends Quantity<T>> InterpolatedTransform(final 
DatumShiftGrid<T,T> grid) throws NoninvertibleMatrixException {
         /*
          * Create the contextual parameters using the descriptor of the 
provider that created the datum shift grid.
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/AffineTransform2D.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/AffineTransform2D.java
index f8bac5339e..f13dd18427 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/AffineTransform2D.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/AffineTransform2D.java
@@ -87,6 +87,7 @@ public class AffineTransform2D extends 
ImmutableAffineTransform
      *
      * @param transform  the affine transform to copy.
      */
+    @SuppressWarnings("this-escape")        // This class is internal API and 
should be used safely.
     public AffineTransform2D(final AffineTransform transform) {
         super(transform);
         freeze();
@@ -98,6 +99,7 @@ public class AffineTransform2D extends 
ImmutableAffineTransform
      *
      * @param elements  the matrix elements in an array of length 4 or 6.
      */
+    @SuppressWarnings("this-escape")        // This class is internal API and 
should be used safely.
     public AffineTransform2D(final double[] elements) {
         super(elements);
         freeze();
@@ -134,6 +136,7 @@ public class AffineTransform2D extends 
ImmutableAffineTransform
      * @param m02 the X coordinate translation.
      * @param m12 the Y coordinate translation.
      */
+    @SuppressWarnings("this-escape")        // This class is internal API and 
should be used safely.
     public AffineTransform2D(double m00, double m10, double m01, double m11, 
double m02, double m12) {
         super(pz(m00), pz(m10), pz(m01), pz(m11), pz(m02), pz(m12));
         matrix = new AffineMatrix(this);
@@ -151,6 +154,7 @@ public class AffineTransform2D extends 
ImmutableAffineTransform
      * @param m12 the Y coordinate translation.
      * @param modifiable  whether the transform should be modifiable.
      */
+    @SuppressWarnings("this-escape")        // This class is internal API and 
should be used safely.
     public AffineTransform2D(double m00, double m10, double m01, double m11, 
double m02, double m12, final boolean modifiable) {
         super(m00, m10, m01, m11, m02, m12);
         if (!modifiable) {
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/ImmutableIdentifierTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/ImmutableIdentifierTest.java
index 0876f0490b..00f91795f9 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/ImmutableIdentifierTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/ImmutableIdentifierTest.java
@@ -27,6 +27,7 @@ import org.apache.sis.metadata.simple.SimpleCitation;
 import org.apache.sis.xml.privy.LegacyNamespaces;
 import org.apache.sis.util.privy.Constants;
 import org.apache.sis.io.wkt.Convention;
+import org.apache.sis.pending.jdk.JDK19;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
@@ -86,8 +87,7 @@ public final class ImmutableIdentifierTest extends TestCase {
         assertEquals     ("There is a description", 
identifier.getDescription().toString(Locale.ENGLISH));
         assertEquals     ("Voici une description",  
identifier.getDescription().toString(Locale.FRENCH));
         assertEquals     ("Pareil",                 
identifier.getDescription().toString(Locale.CANADA_FRENCH));
-        assertEquals     ("Voici une description",  
identifier.getDescription().toString(new Locale("fr", "BE")));
-        // TODO: use Locale.of(…) with JDK19.
+        assertEquals     ("Voici une description",  
identifier.getDescription().toString(JDK19.localeOf("fr", "BE")));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
 
b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
index ef52392ad3..abbfd80d77 100644
--- 
a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
+++ 
b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
@@ -125,6 +125,7 @@ public class LandsatStore extends DataStore implements 
Aggregate {
      * @param  connector  information about the storage (URL, stream, reader 
instance, <i>etc</i>).
      * @throws DataStoreException if an error occurred while opening the 
Landsat file.
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public LandsatStore(final LandsatStoreProvider provider, final 
StorageConnector connector) throws DataStoreException {
         super(provider, connector);
         Path path = connector.getStorageAs(Path.class);
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
index 87b79728d4..dbcc25ae03 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -235,6 +235,7 @@ public class GeoTiffStore extends DataStore implements 
Aggregate {
      *
      * @since 1.1
      */
+    @SuppressWarnings("this-escape")        // `this` appears in a cyclic 
graph.
     public GeoTiffStore(final DataStore parent, final DataStoreProvider 
provider, final StorageConnector connector,
                         final boolean hidden) throws DataStoreException
     {
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
index bf9fd4b923..71e2efe3ba 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
@@ -105,6 +105,7 @@ public class NetcdfStore extends DataStore implements 
Aggregate {
      *
      * @since 0.8
      */
+    @SuppressWarnings("this-escape")        // The invoked method does not 
store `this` and is not overrideable.
     public NetcdfStore(final NetcdfStoreProvider provider, final 
StorageConnector connector) throws DataStoreException {
         super(provider, connector);
         location = connector.getStorageAs(URI.class);
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
index 0a9db7030a..b3c64cb9e7 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
@@ -111,6 +111,7 @@ public class ChannelDataInput extends ChannelData 
implements DataInput {
      * @param channel  the new channel to use. Stream position shall be the 
same as {@code other.channel} position.
      * @param buffer   the new buffer to use. Its content will be discarded 
(limit set to 0).
      */
+    @SuppressWarnings("this-escape")    // `moveBufferForward(int)` is safe.
     public ChannelDataInput(final ChannelDataInput other, final 
ReadableByteChannel channel, final ByteBuffer buffer) {
         super(other, buffer, false);
         this.channel = channel;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/CanNotProbeException.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/CanNotProbeException.java
index dd1321f779..07ce855b0a 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/CanNotProbeException.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/CanNotProbeException.java
@@ -59,6 +59,7 @@ public class CanNotProbeException extends DataStoreException {
      * @param connector  the stream, file or other kind of resource that the 
store provider tried to probe.
      * @param cause      the reason why the data store cannot be probed.
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public CanNotProbeException(final DataStoreProvider provider, final 
StorageConnector connector, final Throwable cause) {
         super(null, provider.getShortName(), connector.getStorageName(), 
connector.storage);
         this.provider = provider;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
index db8b5badba..61ba67ec4f 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
@@ -110,6 +110,7 @@ public abstract class DataStore implements Resource, 
Localized, AutoCloseable {
     /**
      * Creates a new instance with no provider and initially no listener.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     protected DataStore() {
         provider  = null;
         name      = null;
@@ -128,6 +129,7 @@ public abstract class DataStore implements Resource, 
Localized, AutoCloseable {
      *
      * @since 0.8
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph. 
Should not be accessible before completion.
     protected DataStore(final DataStoreProvider provider, final 
StorageConnector connector) throws DataStoreException {
         this.provider  = provider;
         this.name      = connector.getStorageName();
@@ -155,6 +157,7 @@ public abstract class DataStore implements Resource, 
Localized, AutoCloseable {
      *
      * @since 1.1
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph. 
Should not be accessible before completion.
     protected DataStore(final DataStore parent, final DataStoreProvider 
provider, final StorageConnector connector,
                         final boolean hidden) throws DataStoreException
     {
diff --git a/endorsed/src/org.apache.sis.util/main/module-info.java 
b/endorsed/src/org.apache.sis.util/main/module-info.java
index 833750ffaa..8f3a98257b 100644
--- a/endorsed/src/org.apache.sis.util/main/module-info.java
+++ b/endorsed/src/org.apache.sis.util/main/module-info.java
@@ -158,5 +158,6 @@ module org.apache.sis.util {
             org.apache.sis.storage.netcdf,
             org.apache.sis.storage.geotiff,
             org.apache.sis.console,
-            org.apache.sis.portrayal;
+            org.apache.sis.portrayal,
+            org.apache.sis.gui;                         // In the "optional" 
sub-project.
 }
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK19.java 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK19.java
index 12c8f7ba76..f492f4d064 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK19.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK19.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.pending.jdk;
 
+import java.util.Locale;
 import java.util.HashSet;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
@@ -60,4 +61,24 @@ public final class JDK19 {
     public static <K, V> LinkedHashMap<K,V> newLinkedHashMap(int n) {
         return new LinkedHashMap<>(hashMapCapacity(n));
     }
+
+    @SuppressWarnings("deprecation")
+    public static long threadId(Thread thread) {
+        return thread.getId();
+    }
+
+    @SuppressWarnings("deprecation")
+    public static Locale localeOf(String language) {
+        return new Locale(language);
+    }
+
+    @SuppressWarnings("deprecation")
+    public static Locale localeOf(String language, String country) {
+        return new Locale(language, country);
+    }
+
+    @SuppressWarnings("deprecation")
+    public static Locale localeOf(String language, String country, String 
variant) {
+        return new Locale(language, country, variant);
+    }
 }
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/OptionalDependency.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/OptionalDependency.java
index d4a532de10..7731def049 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/OptionalDependency.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/OptionalDependency.java
@@ -43,6 +43,7 @@ public abstract class OptionalDependency extends 
SystemListener {
      * @param module  a constant from the {@link Modules} class which identify 
the module that need the optional dependency.
      * @param dependency  the name of the optional module on which the 
specified {@code module} depends.
      */
+    @SuppressWarnings("this-escape")            // This class is internal API.
     protected OptionalDependency(final String module, final String dependency) 
{
         super(module);
         this.dependency = dependency;
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/LocalesTest.java 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/LocalesTest.java
index 7410f5f011..16ced5289f 100644
--- a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/LocalesTest.java
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/LocalesTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.util;
 
 import java.util.Locale;
 import java.util.IllformedLocaleException;
+import org.apache.sis.pending.jdk.JDK19;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
@@ -66,9 +67,8 @@ public final class LocalesTest extends TestCase {
      */
     @Test
     public void testUnique() {
-        // TODO: use Locale.of(…) with JDK19.
-        assertSame(Locale.ENGLISH, Locales.unique(new Locale("en")));
-        assertSame(Locale.FRENCH,  Locales.unique(new Locale("fr")));
+        assertSame(Locale.ENGLISH, Locales.unique(JDK19.localeOf("en")));
+        assertSame(Locale.FRENCH,  Locales.unique(JDK19.localeOf("fr")));
     }
 
     /**
@@ -86,11 +86,10 @@ public final class LocalesTest extends TestCase {
         assertSame(Locale.JAPAN,         Locales.parse("ja_JP"));
         assertSame(Locale.US,            Locales.parse("en; USA"));
 
-        // TODO: use Locale.of(…) with JDK19.
-        assertEquals(new Locale("de", "DE"),            
Locales.parse("de_DE"));
-        assertEquals(new Locale("",   "GB"),            Locales.parse("_GB"));
-        assertEquals(new Locale("en", "US", "WINDOWS"), 
Locales.parse("en_US_WINDOWS"));
-        assertEquals(new Locale("de", "",   "POSIX"),   
Locales.parse("de__POSIX"));
+        assertEquals(JDK19.localeOf("de", "DE"),            
Locales.parse("de_DE"));
+        assertEquals(JDK19.localeOf("",   "GB"),            
Locales.parse("_GB"));
+        assertEquals(JDK19.localeOf("en", "US", "WINDOWS"), 
Locales.parse("en_US_WINDOWS"));
+        assertEquals(JDK19.localeOf("de", "",   "POSIX"),   
Locales.parse("de__POSIX"));
     }
 
     /**
@@ -99,7 +98,7 @@ public final class LocalesTest extends TestCase {
     @Test
     public void testParseIETF() {
         assertEquals(Locale.JAPAN, Locales.parse("ja-JP"));
-        assertEquals(new Locale("en", "US", "POSIX"), 
Locales.parse("en-US-x-lvariant-POSIX"));
+        assertEquals(JDK19.localeOf("en", "US", "POSIX"), 
Locales.parse("en-US-x-lvariant-POSIX"));
     }
 
     /**
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
index 65a842f39f..527986d747 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
@@ -68,6 +68,7 @@ final class BandRangeTable implements 
Callback<TableColumn<SampleDimension,Numbe
      *
      * @param  vocabulary  resources for the locale in use.
      */
+    @SuppressWarnings("unchecked")     // Generic array construction.
     TableView<SampleDimension> create(final Vocabulary vocabulary) {
         final TableView<SampleDimension> table = new TableView<>();
         table.setPrefHeight(NUM_VISIBLE_ROW * Styles.ROW_HEIGHT);
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridSliceSelector.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridSliceSelector.java
index c004ca4c38..a8c2354969 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridSliceSelector.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridSliceSelector.java
@@ -171,6 +171,7 @@ public class GridSliceSelector extends Widget {
      *
      * @param  locale  the locale to use for axis labels, or {@code null} for 
a default locale.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public GridSliceSelector(final Locale locale) {
         this.locale = locale;
         view = new GridPane();
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridView.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridView.java
index fcf5f89b17..af231ae564 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridView.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/GridView.java
@@ -226,6 +226,7 @@ public class GridView extends Control {
      *
      * @param  controls  the controls of this grid view, or {@code null} if 
none.
      */
+    @SuppressWarnings("this-escape")        // `this` appears in a cyclic 
graph.
     GridView(final GridControls controls) {
         this.controls    = controls;
         bandProperty     = new BandProperty();
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/ImagePropertyExplorer.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/ImagePropertyExplorer.java
index 74d940bf15..051257a245 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/ImagePropertyExplorer.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/ImagePropertyExplorer.java
@@ -359,7 +359,8 @@ public class ImagePropertyExplorer extends Widget {
      *
      * @param  background  the image background color, or {@code null} if none.
      */
-    ImagePropertyExplorer(final Locale locale,  final 
ObjectProperty<Background> background) {
+    @SuppressWarnings({"this-escape", "unchecked"})         // Generic array 
construction.
+    ImagePropertyExplorer(final Locale locale, final 
ObjectProperty<Background> background) {
         final Vocabulary vocabulary = Vocabulary.forLocale(locale);
         final Resources  resources  = Resources.forLocale(locale);
 
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/FeatureTable.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/FeatureTable.java
index 29314d556f..45c88d7b57 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/FeatureTable.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/FeatureTable.java
@@ -107,6 +107,7 @@ public class FeatureTable extends TableView<Feature> {
      * @see #getFeatures()
      * @see #setFeatures(FeatureSet)
      */
+    @SuppressWarnings("this-escape")
     public final ObjectProperty<FeatureSet> featuresProperty = new 
SimpleObjectProperty<>(this, "features");
 
     /**
@@ -119,6 +120,7 @@ public class FeatureTable extends TableView<Feature> {
     /**
      * Creates an initially empty table.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public FeatureTable() {
         super(new FeatureList());
         textLocale = Locale.getDefault(Locale.Category.DISPLAY);
@@ -132,6 +134,7 @@ public class FeatureTable extends TableView<Feature> {
      *
      * @param  other  the other table from which to get the feature list.
      */
+    @SuppressWarnings("this-escape")                // `this` appears in a 
cyclic graph.
     public FeatureTable(final FeatureTable other) {
         super(other.getFeatureList());
         other.isSharingList = true;
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/LogViewer.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/LogViewer.java
index 91ea699335..5fdb1e8feb 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/LogViewer.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/LogViewer.java
@@ -226,6 +226,7 @@ public class LogViewer extends Widget {
     /**
      * Creates a new view of log records.
      */
+    @SuppressWarnings({"this-escape", "unchecked"})         // Generic array 
construction.
     LogViewer(final Vocabulary vocabulary) {
         source     = new SimpleObjectProperty<>(this, "source");
         systemLogs = new SimpleBooleanProperty (this, "systemLogs");
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
index 390fe5faeb..247357627a 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
@@ -168,6 +168,7 @@ public class ResourceExplorer extends Widget {
     /**
      * Creates a new panel for exploring resources.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public ResourceExplorer() {
         /*
          * Build the controls on the left side, which will initially contain 
only the resource explorer.
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceTree.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceTree.java
index e88175cd10..c35cb2c5c8 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceTree.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceTree.java
@@ -19,7 +19,8 @@ package org.apache.sis.gui.dataset;
 import java.io.File;
 import java.nio.file.Path;
 import java.nio.file.FileSystemNotFoundException;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.MalformedURLException;
 import java.util.Locale;
 import java.util.Queue;
@@ -117,6 +118,7 @@ public class ResourceTree extends TreeView<Resource> {
      * Creates a new tree of resources with initially no resource to show.
      * For showing a resource, invoke {@link #setResource(Resource)} after 
construction.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public ResourceTree() {
         locale = Locale.getDefault();
         pendingItems = new LinkedList<>();
@@ -301,9 +303,9 @@ public class ResourceTree extends TreeView<Resource> {
         } else {
             final String url = db.getUrl();
             if (url != null) try {
-                loadResource(new URL(url));
+                loadResource(new URI(url).toURL());
                 success = true;
-            } catch (MalformedURLException e) {
+            } catch (URISyntaxException | MalformedURLException e) {
                 /*
                  * Try to take only the filename, taken as the text after last 
'/' ignoring
                  * the very last character (this is the purpose of the `length 
- 2` part).
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/LogHandler.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/LogHandler.java
index 64c1451aa1..000a6704e1 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/LogHandler.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/LogHandler.java
@@ -276,7 +276,7 @@ public final class LogHandler extends Handler implements 
StoreListener<WarningEv
      */
     public static Long loadingStart(final Resource source) {
         if (source == null) return null;
-        final Long id = Thread.currentThread().getId();
+        final Long id = 
org.apache.sis.pending.jdk.JDK19.threadId(Thread.currentThread());
         INSTANCE.inProgress.merge(id, getRecords(source), 
Destination::startNested);
         return id;
     }
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/io/FileAccessView.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/io/FileAccessView.java
index 4017fb228d..6e105a1105 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/io/FileAccessView.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/io/FileAccessView.java
@@ -60,6 +60,7 @@ public final class FileAccessView extends Widget implements 
UnaryOperator<Channe
      * @param  resources   localized resources, provided because already known 
by caller.
      * @param  vocabulary  localized resources, provided because already known 
by caller.
      */
+    @SuppressWarnings("unchecked")      // Generic array construction.
     public FileAccessView(final Resources resources, final Vocabulary 
vocabulary) {
         final TableColumn<FileAccessItem, String> filenameColumn;
         final TableColumn<FileAccessItem,Pane> accessColumn;
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/GestureFollower.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/GestureFollower.java
index 72061620b3..644f4e2358 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/GestureFollower.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/GestureFollower.java
@@ -127,6 +127,7 @@ public class GestureFollower extends CanvasFollower 
implements EventHandler<Mous
      * @param  source  the canvas which is the source of zoom, pan or rotation 
events.
      * @param  target  the canvas on which to apply the changes of zoom, pan 
or rotation.
      */
+    @SuppressWarnings("this-escape")    // The invoked method does not store 
`this` and is not overrideable.
     public GestureFollower(final MapCanvas source, final MapCanvas target) {
         super(source, target);
         super.setDisabled(true);
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/StatusBar.java 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/StatusBar.java
index 034e6b144d..67f7a05107 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/StatusBar.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/StatusBar.java
@@ -477,6 +477,7 @@ public class StatusBar extends Widget implements 
EventHandler<MouseEvent> {
      *
      * @param  systemChooser  the manager of reference systems chosen by user, 
or {@code null} if none.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public StatusBar(final RecentReferenceSystems systemChooser) {
         positionReferenceSystem = new PositionSystem();
         localToObjectiveCRS     = new LocalToObjective();
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/MetadataSummary.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/MetadataSummary.java
index b621d927f7..b63d30c961 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/MetadataSummary.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/MetadataSummary.java
@@ -123,6 +123,7 @@ public class MetadataSummary extends Widget {
     /**
      * Creates an initially empty metadata overview.
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public MetadataSummary() {
         vocabulary  = Vocabulary.forLocale(null);
         formats     = new VerboseFormats(vocabulary.getLocale());
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/StandardMetadataTree.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/StandardMetadataTree.java
index c1da8b5114..40da2e1081 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/StandardMetadataTree.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/StandardMetadataTree.java
@@ -83,6 +83,7 @@ public class StandardMetadataTree extends MetadataTree {
      *
      * @param  controller  the widget to watch, or {@code null} if none.
      */
+    @SuppressWarnings("this-escape")        // `this` appears in a cyclic 
graph.
     public StandardMetadataTree(final MetadataSummary controller) {
         super(controller, true);
         setRowFactory(Row::new);
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/RecentReferenceSystems.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/RecentReferenceSystems.java
index ab256f1768..70a3fce0c3 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/RecentReferenceSystems.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/RecentReferenceSystems.java
@@ -290,6 +290,7 @@ public class RecentReferenceSystems {
      *
      * @see org.apache.sis.referencing.CRS#getAuthorityFactory(String)
      */
+    @SuppressWarnings("this-escape")    // `this` appears in a cyclic graph.
     public RecentReferenceSystems(final CRSAuthorityFactory factory, final 
Locale locale) {
         this.factory         = factory;
         this.locale          = locale;

Reply via email to