Index: trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java	(revision 18808)
+++ trunk/src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java	(revision 18811)
@@ -172,8 +172,8 @@
      *
      * @param name the name without the nodes count
-     * @param primitive the primitive
+     * @param way the way
      * @since 18808
      */
-    protected void decorateNameWithNodes(StringBuilder name, IWay way) {
+    protected void decorateNameWithNodes(StringBuilder name, IWay<?> way) {
         char mark;
         // If current language is left-to-right (almost all languages)
@@ -559,6 +559,6 @@
      * Decorates the name of primitive with its id, if the preference
      * <code>osm-primitives.showid</code> is set.
-     *
-     * The id is append to the {@link StringBuilder} passed in <code>name</code>.
+     * <p>
+     * The id is appended to the {@link StringBuilder} passed in <code>name</code>.
      *
      * @param name  the name without the id
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 18808)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 18811)
@@ -76,5 +76,5 @@
 
     /** Pattern matching white spaces */
-    public static final Pattern WHITE_SPACES_PATTERN = Pattern.compile("\\s+");
+    public static final Pattern WHITE_SPACES_PATTERN = Pattern.compile("\\s+", Pattern.UNICODE_CHARACTER_CLASS);
 
     private static final long MILLIS_OF_SECOND = TimeUnit.SECONDS.toMillis(1);
@@ -105,9 +105,12 @@
 
     private static Method mapOfEntriesMethod() {
-        try {
-            return Map.class.getMethod("ofEntries", Map.Entry[].class);
-        } catch (NoSuchMethodException e) {
-            return null;
-        }
+        if (getJavaVersion() >= 9) {
+            try {
+                return Map.class.getMethod("ofEntries", Map.Entry[].class);
+            } catch (NoSuchMethodException noSuchMethodException) {
+                Logging.trace(noSuchMethodException);
+            }
+        }
+        return null;
     }
 
@@ -197,5 +200,5 @@
      *  empty string
      * @return null if values is null. The joined string otherwise.
-     * @deprecated use {@link String#join} or {@link Collectors#joining}
+     * @deprecated since 15718, use {@link String#join} or {@link Collectors#joining}
      */
     @Deprecated
@@ -521,6 +524,6 @@
 
         char[] hexChars = new char[len * 2];
-        for (int i = 0, j = 0; i < len; i++) {
-            final int v = bytes[i];
+        int j = 0;
+        for (final int v : bytes) {
             hexChars[j++] = HEX_ARRAY[(v & 0xf0) >> 4];
             hexChars[j++] = HEX_ARRAY[v & 0xf];
@@ -682,7 +685,7 @@
             try {
                 // Java 9: use Map.ofEntries(...)
-                return (Map<K, V>) mapOfEntries.invoke(null, new Object[]{map.entrySet().toArray(new Map.Entry[0])});
-            } catch (Exception ignore) {
-                Logging.trace(ignore);
+                return (Map<K, V>) mapOfEntries.invoke(null, (Object) map.entrySet().toArray(new Map.Entry[0]));
+            } catch (ReflectiveOperationException toLog) {
+                Logging.trace(toLog);
             }
         }
@@ -1520,6 +1523,5 @@
             return new byte[0];
         }
-        try { // NOPMD
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(stream.available());
+        try (ByteArrayOutputStream bout = new ByteArrayOutputStream(stream.available())) {
             byte[] buffer = new byte[8192];
             boolean finished = false;
@@ -1543,5 +1545,5 @@
      * Returns the initial capacity to pass to the HashMap / HashSet constructor
      * when it is initialized with a known number of entries.
-     *
+     * <p>
      * When a HashMap is filled with entries, the underlying array is copied over
      * to a larger one multiple times. To avoid this process when the number of
@@ -1560,5 +1562,5 @@
      * Returns the initial capacity to pass to the HashMap / HashSet constructor
      * when it is initialized with a known number of entries.
-     *
+     * <p>
      * When a HashMap is filled with entries, the underlying array is copied over
      * to a larger one multiple times. To avoid this process when the number of
@@ -1566,5 +1568,5 @@
      * given to the HashMap constructor. This method returns a suitable value
      * that avoids rehashing but doesn't waste memory.
-     *
+     * <p>
      * Assumes default load factor (0.75).
      * @param nEntries the number of entries expected
@@ -1640,4 +1642,5 @@
      */
     public static double clamp(double val, double min, double max) {
+        // Switch to Math.clamp when we move to Java 21
         if (min > max) {
             throw new IllegalArgumentException(MessageFormat.format("Parameter min ({0}) cannot be greater than max ({1})", min, max));
@@ -1674,5 +1677,5 @@
     /**
      * Convert angle from radians to degrees.
-     *
+     * <p>
      * Replacement for {@link Math#toDegrees(double)} to match the Java 9
      * version of that method. (Can be removed when JOSM support for Java 8 ends.)
@@ -1689,5 +1692,5 @@
     /**
      * Convert angle from degrees to radians.
-     *
+     * <p>
      * Replacement for {@link Math#toRadians(double)} to match the Java 9
      * version of that method. (Can be removed when JOSM support for Java 8 ends.)
@@ -1708,5 +1711,6 @@
      */
     public static int getJavaVersion() {
-        String version = getSystemProperty("java.version");
+        // Switch to Runtime.version() once we move past Java 8
+        String version = Objects.requireNonNull(getSystemProperty("java.version"));
         if (version.startsWith("1.")) {
             version = version.substring(2);
@@ -1729,5 +1733,6 @@
      */
     public static int getJavaUpdate() {
-        String version = getSystemProperty("java.version");
+        // Switch to Runtime.version() once we move past Java 8
+        String version = Objects.requireNonNull(getSystemProperty("java.version"));
         if (version.startsWith("1.")) {
             version = version.substring(2);
@@ -1738,4 +1743,6 @@
         // 9
         // 9.0.1
+        // 17.0.4.1+1-LTS
+        // $MAJOR.$MINOR.$SECURITY.$PATCH
         int undePos = version.indexOf('_');
         int dashPos = version.indexOf('-');
@@ -1745,10 +1752,10 @@
         }
         int firstDotPos = version.indexOf('.');
-        int lastDotPos = version.lastIndexOf('.');
-        if (firstDotPos == lastDotPos) {
+        int secondDotPos = version.indexOf('.', firstDotPos + 1);
+        if (firstDotPos == secondDotPos) {
             return 0;
         }
         return firstDotPos > -1 ? Integer.parseInt(version.substring(firstDotPos + 1,
-                lastDotPos > -1 ? lastDotPos : version.length())) : 0;
+                secondDotPos > -1 ? secondDotPos : version.length())) : 0;
     }
 
@@ -1759,5 +1766,6 @@
      */
     public static int getJavaBuild() {
-        String version = getSystemProperty("java.runtime.version");
+        // Switch to Runtime.version() once we move past Java 8
+        String version = Objects.requireNonNull(getSystemProperty("java.runtime.version"));
         int bPos = version.indexOf('b');
         int pPos = version.indexOf('+');
@@ -2041,7 +2049,7 @@
     public static String stripHtml(String rawString) {
         // remove HTML tags
-        rawString = rawString.replaceAll("<.*?>", " ");
+        rawString = rawString.replaceAll("<[^>]+>", " ");
         // consolidate multiple spaces between a word to a single space
-        rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
+        rawString = rawString.replaceAll("(?U)\\b\\s{2,}\\b", " ");
         // remove extra whitespaces
         return rawString.trim();
