Index: trunk/build.xml
===================================================================
--- trunk/build.xml	(revision 19047)
+++ trunk/build.xml	(revision 19048)
@@ -906,5 +906,5 @@
         <ivy:cachepath log="download-only" file="${tools.ivy}" pathid="pmd.classpath" conf="pmd"/>
         <taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.classpath"/>
-        <pmd shortFilenames="true" cacheLocation="${pmd.dir}/cache" encoding="UTF-8">
+        <pmd cacheLocation="${pmd.dir}/cache" encoding="UTF-8">
             <sourceLanguage name="java" version="${java.lang.version}" />
             <ruleset>${pmd.dir}/josm-ruleset.xml</ruleset>
@@ -918,4 +918,5 @@
             </fileset>
             <fileset dir="${base.dir}/scripts" includes="**/*.java"/>
+            <relativizePathsWith><path path="${base.dir}"/></relativizePathsWith>
         </pmd>
     </target>
Index: trunk/ivy.xml
===================================================================
--- trunk/ivy.xml	(revision 19047)
+++ trunk/ivy.xml	(revision 19048)
@@ -27,7 +27,7 @@
         <dependency conf="api->default" org="jakarta.json" name="jakarta.json-api" rev="2.1.3"/>
         <!-- parsson is an implementation for jakarta.json -->
-        <dependency conf="runtimeOnly->default" org="org.eclipse.parsson" name="parsson" rev="1.1.5"/>
+        <dependency conf="runtimeOnly->default" org="org.eclipse.parsson" name="parsson" rev="1.1.6"/>
         <dependency conf="api->default" org="org.apache.commons" name="commons-jcs3-core" rev="3.2"/>
-        <dependency conf="api->default" org="org.apache.commons" name="commons-compress" rev="1.25.0"/>
+        <dependency conf="api->default" org="org.apache.commons" name="commons-compress" rev="1.26.1"/>
         <dependency conf="api->default" org="jakarta.annotation" name="jakarta.annotation-api" rev="2.1.1" />
         <!-- jsr305 has some source files with non-free CC-BY-2.5 license. Remove after 2024-06-01 to give plugins time to migrate. See #23220 for details -->
@@ -37,5 +37,5 @@
         <dependency conf="api->default" org="com.drewnoakes" name="metadata-extractor" rev="2.19.0" transitive="false"/>
         <dependency conf="api->default" org="com.formdev" name="svgSalamander" rev="1.1.4"/>
-        <dependency conf="api->default" org="ch.poole" name="OpeningHoursParser" rev="0.28.1"/>
+        <dependency conf="api->default" org="ch.poole" name="OpeningHoursParser" rev="0.28.2"/>
         <!-- Don't forget to update org.openstreetmap.josm.tools.Tag2Link#PREF_SOURCE -->
         <dependency conf="api->default" org="org.webjars.npm" name="tag2link" rev="2024.2.8"/>
@@ -45,7 +45,7 @@
         <dependency conf="sources->sources" org="org.glassfish" name="javax.json" rev="1.1.4"/>
         <dependency conf="sources->sources" org="jakarta.json" name="jakarta.json-api" rev="2.1.3"/>
-        <dependency conf="sources->sources" org="org.eclipse.parsson" name="parsson" rev="1.1.5"/>
+        <dependency conf="sources->sources" org="org.eclipse.parsson" name="parsson" rev="1.1.6"/>
         <dependency conf="sources->sources" org="org.apache.commons" name="commons-jcs3-core" rev="3.2"/>
-        <dependency conf="sources->sources" org="org.apache.commons" name="commons-compress" rev="1.25.0"/>
+        <dependency conf="sources->sources" org="org.apache.commons" name="commons-compress" rev="1.26.1"/>
         <dependency conf="sources->sources" org="jakarta.annotation" name="jakarta.annotation-api" rev="2.1.1" />
         <!-- jsr305 has some source files with non-free CC-BY-2.5 license. Remove after 2024-06-01 to give plugins time to migrate. See #23220 for details -->
@@ -55,18 +55,18 @@
         <dependency conf="sources->sources" org="com.drewnoakes" name="metadata-extractor" rev="2.19.0" transitive="false"/>
         <dependency conf="sources->sources" org="com.formdev" name="svgSalamander" rev="1.1.4"/>
-        <dependency conf="sources->sources" org="ch.poole" name="OpeningHoursParser" rev="0.28.1"/>
+        <dependency conf="sources->sources" org="ch.poole" name="OpeningHoursParser" rev="0.28.2"/>
         <dependency conf="sources->default" org="org.webjars.npm" name="tag2link" rev="2024.2.8"/><!-- sources->default sic! (tag2link-sources.jar is empty, see #19335) -->
         <!-- commonslang->default -->
         <dependency conf="commonslang->default" org="org.apache.commons" name="commons-lang3" rev="3.14.0"/>
         <!-- jacocoant->default -->
-        <dependency conf="jacocoant->default" org="org.jacoco" name="org.jacoco.ant" rev="0.8.11">
+        <dependency conf="jacocoant->default" org="org.jacoco" name="org.jacoco.ant" rev="0.8.12">
             <artifact name="org.jacoco.ant" type="jar" maven:classifier="nodeps"/>
         </dependency>
         <dependency conf="jmockit->default" org="org.jmockit" name="jmockit" rev="1.49.a"/>
         <!-- test->default -->
-        <dependency conf="test->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.8.3"/>
+        <dependency conf="test->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.8.4"/>
         <dependency conf="test->default" org="com.ginsberg" name="junit5-system-exit" rev="1.1.2"/>
-        <dependency conf="test->default" org="com.github.tomakehurst" name="wiremock-jre8" rev="2.35.0"/>
-        <dependency conf="test->default" org="io.github.classgraph" name="classgraph" rev="4.8.165"/>
+        <dependency conf="test->default" org="com.github.tomakehurst" name="wiremock" rev="3.0.1"/>
+        <dependency conf="test->default" org="io.github.classgraph" name="classgraph" rev="4.8.171"/>
         <dependency conf="test->default" org="org.junit.platform" name="junit-platform-launcher" rev="1.10.2"/>
         <dependency conf="test->default" org="org.junit.platform" name="junit-platform-suite" rev="1.10.2"/>
@@ -77,7 +77,7 @@
         <dependency conf="test->default" org="org.junit.jupiter" name="junit-jupiter-migrationsupport" rev="5.10.2"/>
         <dependency conf="test->default" org="net.trajano.commons" name="commons-testing" rev="2.1.0"/>
-        <dependency conf="test->default" org="nl.jqno.equalsverifier" name="equalsverifier" rev="3.15.6"/>
+        <dependency conf="test->default" org="nl.jqno.equalsverifier" name="equalsverifier" rev="3.16.1"/>
         <dependency conf="test->default" org="org.apache.commons" name="commons-lang3" rev="3.14.0"/>
-        <dependency conf="test->default" org="org.awaitility" name="awaitility" rev="4.2.0"/>
+        <dependency conf="test->default" org="org.awaitility" name="awaitility" rev="4.2.1"/>
     </dependencies>
 </ivy-module>
Index: trunk/ivysettings.xml
===================================================================
--- trunk/ivysettings.xml	(revision 19047)
+++ trunk/ivysettings.xml	(revision 19048)
@@ -6,6 +6,3 @@
     <ibiblio name="josm-nexus" m2compatible="true" root="https://josm.openstreetmap.de/nexus/content/repositories/public/" />
   </resolvers>
-  <!-- Remove error_prone 2.10.0 specific statements in build.xml when we drop Java 8 as a build platform -->
-  <property name="versions.error_prone" value="2.10.0" unlessset="isJava11"/>
-  <property name="versions.error_prone" value="2.24.1" ifset="isJava11"/>
 </ivysettings>
Index: trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 19048)
@@ -7,4 +7,5 @@
 import java.awt.Dimension;
 import java.awt.GraphicsEnvironment;
+import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
@@ -14,5 +15,4 @@
 import java.time.Year;
 import java.time.ZoneOffset;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -26,6 +26,4 @@
 import javax.swing.JScrollPane;
 
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.imagery.DefaultLayer;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
@@ -62,9 +60,9 @@
         SelectWmsLayersDialog(WMSLayerTree tree, JComboBox<String> formats) {
             super(MainApplication.getMainFrame(), tr("Select WMS layers"), tr("Add layers"), tr("Cancel"));
-            final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
+            final var scrollPane = new JScrollPane(tree.getLayerTree());
             scrollPane.setPreferredSize(new Dimension(400, 400));
-            final JPanel panel = new JPanel(new GridBagLayout());
+            final var panel = new JPanel(new GridBagLayout());
             panel.add(scrollPane, GBC.eol().fill());
-            panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
+            panel.add(formats, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
             setContent(panel);
         }
@@ -84,5 +82,5 @@
 
         // change toolbar icon from if specified
-        String icon = info.getIcon();
+        var icon = info.getIcon();
         if (icon != null) {
             new ImageProvider(icon).setOptional(true).getResourceAsync(result -> {
@@ -103,8 +101,8 @@
         try {
             if (info.getUrl() != null && info.getUrl().contains("{time}")) {
-                final String instant = Year.now(ZoneOffset.UTC).atDay(1).atStartOfDay(ZoneOffset.UTC).toInstant().toString();
-                final String example = String.join("/", instant, instant);
-                final String initialSelectionValue = info.getDate() != null ? info.getDate() : example;
-                final String userDate = JOptionPane.showInputDialog(MainApplication.getMainFrame(),
+                final var instant = Year.now(ZoneOffset.UTC).atDay(1).atStartOfDay(ZoneOffset.UTC).toInstant().toString();
+                final var example = String.join("/", instant, instant);
+                final var initialSelectionValue = info.getDate() != null ? info.getDate() : example;
+                final var userDate = JOptionPane.showInputDialog(MainApplication.getMainFrame(),
                         tr("Time filter for \"{0}\" such as \"{1}\"", info.getName(), example),
                         initialSelectionValue);
@@ -115,5 +113,5 @@
                 // TODO persist new {time} value (via ImageryLayerInfo.save?)
             }
-            switch(info.getImageryType()) {
+            switch (info.getImageryType()) {
             case WMS_ENDPOINT:
                 // convert to WMS type
@@ -126,10 +124,10 @@
                 // specify which layer to use
                 if (Utils.isEmpty(info.getDefaultLayers())) {
-                    WMTSTileSource tileSource = new WMTSTileSource(info);
-                    DefaultLayer layerId = tileSource.userSelectLayer();
+                    var tileSource = new WMTSTileSource(info);
+                    var layerId = tileSource.userSelectLayer();
                     if (layerId != null) {
-                        ImageryInfo copy = new ImageryInfo(info);
+                        var copy = new ImageryInfo(info);
                         copy.setDefaultLayers(Collections.singletonList(layerId));
-                        String layerName = tileSource.getLayers().stream()
+                        var layerName = tileSource.getLayers().stream()
                                 .filter(x -> x.getIdentifier().equals(layerId.getLayerName()))
                                 .map(Layer::getUserTitle)
@@ -165,5 +163,5 @@
         ImageryLayer layer = null;
         try {
-            final ImageryInfo infoToAdd = convertImagery(info);
+            final var infoToAdd = convertImagery(info);
             if (infoToAdd != null) {
                 layer = ImageryLayer.create(infoToAdd);
@@ -207,14 +205,14 @@
 
     private static LayerSelection askToSelectLayers(WMSImagery wms) {
-        final WMSLayerTree tree = new WMSLayerTree();
-
-        Collection<String> wmsFormats = wms.getFormats();
-        final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[0]));
+        final var tree = new WMSLayerTree();
+
+        var wmsFormats = wms.getFormats();
+        final var formats = new JComboBox<String>(wmsFormats.toArray(new String[0]));
         formats.setSelectedItem(wms.getPreferredFormat());
         formats.setToolTipText(tr("Select image format for WMS layer"));
 
-        JCheckBox checkBounds = new JCheckBox(tr("Show only layers for current view"), true);
+        var checkBounds = new JCheckBox(tr("Show only layers for current view"), true);
         Runnable updateTree = () -> {
-            LatLon latLon = checkBounds.isSelected() && MainApplication.isDisplayingMapView()
+            var latLon = checkBounds.isSelected() && MainApplication.isDisplayingMapView()
                     ? MainApplication.getMap().mapView.getProjection().eastNorth2latlon(MainApplication.getMap().mapView.getCenter())
                     : null;
@@ -227,12 +225,12 @@
 
         if (!GraphicsEnvironment.isHeadless()) {
-            ExtendedDialog dialog = new ExtendedDialog(MainApplication.getMainFrame(),
+            var dialog = new ExtendedDialog(MainApplication.getMainFrame(),
                     tr("Select WMS layers"), tr("Add layers"), tr("Cancel"));
-            final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
+            final var scrollPane = new JScrollPane(tree.getLayerTree());
             scrollPane.setPreferredSize(new Dimension(400, 400));
-            final JPanel panel = new JPanel(new GridBagLayout());
+            final var panel = new JPanel(new GridBagLayout());
             panel.add(scrollPane, GBC.eol().fill());
-            panel.add(checkBounds, GBC.eol().fill(GBC.HORIZONTAL));
-            panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
+            panel.add(checkBounds, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
+            panel.add(formats, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
             dialog.setContent(panel);
 
@@ -283,12 +281,12 @@
         CheckParameterUtil.ensureThat(ImageryType.WMS_ENDPOINT == info.getImageryType(), "wms_endpoint imagery type expected");
         // We need to get the URL with {apikey} replaced. See #22642.
-        final TemplatedWMSTileSource tileSource = new TemplatedWMSTileSource(info, ProjectionRegistry.getProjection());
-        final WMSImagery wms = new WMSImagery(tileSource.getBaseUrl(), info.getCustomHttpHeaders());
-        LayerSelection selection = choice.apply(wms);
+        final var tileSource = new TemplatedWMSTileSource(info, ProjectionRegistry.getProjection());
+        final var wms = new WMSImagery(tileSource.getBaseUrl(), info.getCustomHttpHeaders());
+        var selection = choice.apply(wms);
         if (selection == null) {
             return null;
         }
 
-        final String url = wms.buildGetMapUrl(
+        final var url = wms.buildGetMapUrl(
                 selection.layers.stream().map(LayerDetails::getName).collect(Collectors.toList()),
                 (List<String>) null,
@@ -297,9 +295,9 @@
                 );
 
-        String selectedLayers = selection.layers.stream()
+        var selectedLayers = selection.layers.stream()
                 .map(LayerDetails::getName)
                 .collect(Collectors.joining(", "));
         // Use full copy of original Imagery info to copy all attributes. Only overwrite what's different
-        ImageryInfo ret = new ImageryInfo(info);
+        var ret = new ImageryInfo(info);
         ret.setUrl(url);
         ret.setImageryType(ImageryType.WMS);
Index: trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 19048)
@@ -8,5 +8,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.awt.geom.Area;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -23,5 +22,4 @@
 import org.openstreetmap.josm.data.DataSource;
 import org.openstreetmap.josm.data.conflict.Conflict;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.OsmData;
@@ -34,5 +32,4 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener;
-import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.ValidatorDialog.ValidatorBoundingXYVisitor;
@@ -146,5 +143,5 @@
      */
     public static void zoomTo(Collection<? extends IPrimitive> sel) {
-        BoundingXYVisitor bboxCalculator = new BoundingXYVisitor();
+        final var bboxCalculator = new BoundingXYVisitor();
         bboxCalculator.computeBoundingBox(sel);
         if (bboxCalculator.getBounds() != null) {
@@ -244,5 +241,5 @@
     public void autoScale() {
         if (MainApplication.isDisplayingMapView()) {
-            MapView mapView = MainApplication.getMap().mapView;
+            final var mapView = MainApplication.getMap().mapView;
             switch (mode) {
             case PREVIOUS:
@@ -312,5 +309,5 @@
     private void modeLayer(BoundingXYVisitor v) {
         // try to zoom to the first selected layer
-        Layer l = getFirstSelectedLayer();
+        final var l = getFirstSelectedLayer();
         if (l == null)
             return;
@@ -327,5 +324,5 @@
             }
         } else {
-            ConflictDialog conflictDialog = MainApplication.getMap().conflictDialog;
+            final var conflictDialog = MainApplication.getMap().conflictDialog;
             Conflict<? extends IPrimitive> c = conflictDialog.getSelectedConflict();
             if (c != null) {
@@ -359,5 +356,5 @@
         }
         Bounds bbox = null;
-        final DataSet dataset = getLayerManager().getActiveDataSet();
+        final var dataset = getLayerManager().getActiveDataSet();
         if (dataset != null) {
             List<DataSource> dataSources = new ArrayList<>(dataset.getDataSources());
@@ -372,5 +369,5 @@
                 } else {
                     lastZoomArea = -1;
-                    Area sourceArea = getLayerManager().getActiveDataSet().getDataSourceArea();
+                    final var sourceArea = getLayerManager().getActiveDataSet().getDataSourceArea();
                     if (sourceArea != null) {
                         bbox = new Bounds(sourceArea.getBounds2D());
@@ -439,5 +436,5 @@
      * Adapter for zoom change events
      */
-    private class ZoomChangeAdapter implements ZoomChangeListener {
+    private final class ZoomChangeAdapter implements ZoomChangeListener {
         @Override
         public void zoomChanged() {
Index: trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java	(revision 19048)
@@ -49,5 +49,5 @@
     }
 
-    private class ChangesetCacheManagerClosedHandler extends WindowAdapter {
+    private final class ChangesetCacheManagerClosedHandler extends WindowAdapter {
         @Override
         public void windowClosed(WindowEvent e) {
Index: trunk/src/org/openstreetmap/josm/actions/DownloadOsmInViewAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DownloadOsmInViewAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/DownloadOsmInViewAction.java	(revision 19048)
@@ -37,6 +37,6 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        final Bounds bounds = MainApplication.getMap().mapView.getRealBounds();
-        DownloadOsmInViewTask task = new DownloadOsmInViewTask();
+        final var bounds = MainApplication.getMap().mapView.getRealBounds();
+        final var task = new DownloadOsmInViewTask();
         task.setZoomAfterDownload(false);
         Future<?> future = task.download(bounds);
Index: trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 19048)
@@ -210,9 +210,9 @@
 
         public List<Node> getNodes() {
-            List<Node> nodes = new ArrayList<>();
+            final var nodes = new ArrayList<Node>();
             for (WayInPolygon way : this.ways) {
                 //do not add the last node as it will be repeated in the next way
                 if (way.insideToTheRight) {
-                    for (int pos = 0; pos < way.way.getNodesCount() - 1; pos++) {
+                    for (var pos = 0; pos < way.way.getNodesCount() - 1; pos++) {
                         nodes.add(way.way.getNode(pos));
                     }
@@ -343,7 +343,7 @@
          */
         private static double getAngle(Node n1, Node n2, Node n3) {
-            EastNorth en1 = n1.getEastNorth();
-            EastNorth en2 = n2.getEastNorth();
-            EastNorth en3 = n3.getEastNorth();
+            final var en1 = n1.getEastNorth();
+            final var en2 = n2.getEastNorth();
+            final var en3 = n3.getEastNorth();
             double angle = Math.atan2(en3.getY() - en1.getY(), en3.getX() - en1.getX()) -
                     Math.atan2(en2.getY() - en1.getY(), en2.getX() - en1.getX());
@@ -362,6 +362,6 @@
          */
         public WayInPolygon walk() {
-            Node headNode = getHeadNode();
-            Node prevNode = getPrevNode();
+            final var headNode = getHeadNode();
+            final var prevNode = getPrevNode();
 
             double headAngle = Math.atan2(headNode.getEastNorth().east() - prevNode.getEastNorth().east(),
@@ -371,5 +371,5 @@
             //find best next way
             WayInPolygon bestWay = null;
-            boolean bestWayReverse = false;
+            var bestWayReverse = false;
 
             for (WayInPolygon way : availableWays) {
@@ -418,9 +418,9 @@
          */
         public WayInPolygon leftComingWay() {
-            Node headNode = getHeadNode();
-            Node prevNode = getPrevNode();
+            final var headNode = getHeadNode();
+            final var prevNode = getPrevNode();
 
             WayInPolygon mostLeft = null; // most left way connected to head node
-            boolean comingToHead = false; // true if candidate come to head node
+            var comingToHead = false; // true if candidate come to head node
             double angle = 2*Math.PI;
 
@@ -649,9 +649,9 @@
         }
 
-        boolean hasChanges = false;
-
-        List<Way> allStartingWays = new ArrayList<>();
-        List<Way> innerStartingWays = new ArrayList<>();
-        List<Way> outerStartingWays = new ArrayList<>();
+        var hasChanges = false;
+
+        final var allStartingWays = new ArrayList<Way>();
+        final var innerStartingWays = new ArrayList<Way>();
+        final var outerStartingWays = new ArrayList<Way>();
 
         for (Multipolygon area : areas) {
@@ -721,10 +721,10 @@
         if (discardedWays.stream().anyMatch(w -> !w.isNew())) {
             for (AssembledPolygon ring : boundaries) {
-                for (int k = 0; k < ring.ways.size(); k++) {
+                for (var k = 0; k < ring.ways.size(); k++) {
                     WayInPolygon ringWay = ring.ways.get(k);
                     Way older = keepOlder(ringWay.way, oldestWayMap, discardedWays);
 
                     if (ringWay.way != older) {
-                        WayInPolygon repl = new WayInPolygon(older, ringWay.insideToTheRight);
+                        final var repl = new WayInPolygon(older, ringWay.insideToTheRight);
                         ring.ways.set(k, repl);
                     }
@@ -769,5 +769,5 @@
         // Delete the discarded inner ways
         if (!discardedWays.isEmpty()) {
-            Command deleteCmd = DeleteCommand.delete(discardedWays, true);
+            final var deleteCmd = DeleteCommand.delete(discardedWays, true);
             if (deleteCmd != null) {
                 cmds.add(deleteCmd);
@@ -796,6 +796,6 @@
     private Way keepOlder(Way way, Map<Node, Way> oldestWayMap, List<Way> discardedWays) {
         Way oldest = null;
-        for (Node n : way.getNodes()) {
-            Way orig = oldestWayMap .get(n);
+        for (var n : way.getNodes()) {
+            final var orig = oldestWayMap .get(n);
             if (orig != null && (oldest == null || oldest.getUniqueId() > orig.getUniqueId())
                     && discardedWays.contains(orig)) {
@@ -830,5 +830,5 @@
         }
 
-        TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
+        final var wayTags = TagCollection.unionOfAllPrimitives(ways);
         try {
             cmds.addAll(CombinePrimitiveResolverDialog.launchIfNecessary(wayTags, ways, ways));
@@ -847,6 +847,6 @@
      */
     private boolean removeDuplicateNodes(List<Way> ways) {
-        Map<Node, Node> nodeMap = new TreeMap<>(new NodePositionComparator());
-        int totalWaysModified = 0;
+        final var nodeMap = new TreeMap<Node, Node>(new NodePositionComparator());
+        var totalWaysModified = 0;
 
         for (Way way : ways) {
@@ -855,10 +855,10 @@
             }
 
-            List<Node> newNodes = new ArrayList<>();
+            final var newNodes = new ArrayList<Node>();
             Node prevNode = null;
-            boolean modifyWay = false;
+            var modifyWay = false;
 
             for (Node node : way.getNodes()) {
-                Node representator = nodeMap.get(node);
+                var representator = nodeMap.get(node);
                 if (representator == null) {
                     //new node
@@ -898,5 +898,5 @@
      */
     private void commitCommands(String description) {
-        switch(cmds.size()) {
+        switch (cmds.size()) {
         case 0:
             return;
@@ -923,5 +923,5 @@
         cmds.clear();
         if (addUndoRedo && !executedCmds.isEmpty()) {
-            UndoRedoHandler ur = UndoRedoHandler.getInstance();
+            final var ur = UndoRedoHandler.getInstance();
             if (executedCmds.size() == 1) {
                 ur.add(executedCmds.getFirst(), false);
@@ -945,5 +945,5 @@
         Map<Way, Way> nextWayMap = new HashMap<>();
 
-        for (int pos = 0; pos < parts.size(); pos++) {
+        for (var pos = 0; pos < parts.size(); pos++) {
 
             if (!parts.get(pos).lastNode().equals(parts.get((pos + 1) % parts.size()).firstNode()))
@@ -956,10 +956,10 @@
         Way topWay = null;
         Node topNode = null;
-        int topIndex = 0;
+        var topIndex = 0;
         double minY = Double.POSITIVE_INFINITY;
 
         for (Way way : parts) {
-            for (int pos = 0; pos < way.getNodesCount(); pos++) {
-                Node node = way.getNode(pos);
+            for (var pos = 0; pos < way.getNodesCount(); pos++) {
+                final var node = way.getNode(pos);
 
                 if (node.getEastNorth().getY() < minY) {
@@ -996,5 +996,5 @@
             for (Way way : parts) {
                 if (way.firstNode().equals(headNode)) {
-                    Node nextNode = way.getNode(1);
+                    final var nextNode = way.getNode(1);
 
                     if (topWay == null || !Geometry.isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode)) {
@@ -1008,5 +1008,5 @@
                 if (way.lastNode().equals(headNode)) {
                     //end adjacent to headNode
-                    Node nextNode = way.getNode(way.getNodesCount() - 2);
+                    final var nextNode = way.getNode(way.getNodesCount() - 2);
 
                     if (topWay == null || !Geometry.isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode)) {
@@ -1020,6 +1020,6 @@
         } else {
             //node is inside way - pick the clockwise going end.
-            Node prev = topWay.getNode(topIndex - 1);
-            Node next = topWay.getNode(topIndex + 1);
+            final var prev = topWay.getNode(topIndex - 1);
+            final var next = topWay.getNode(topIndex + 1);
 
             //there will be no parallel segments in the middle of way, so all fine.
@@ -1027,5 +1027,5 @@
         }
 
-        Way curWay = topWay;
+        var curWay = topWay;
         boolean curWayInsideToTheRight = wayClockwise ^ isInner;
         List<WayInPolygon> result = new ArrayList<>();
@@ -1035,12 +1035,12 @@
 
             //add cur way
-            WayInPolygon resultWay = new WayInPolygon(curWay, curWayInsideToTheRight);
+            final var resultWay = new WayInPolygon(curWay, curWayInsideToTheRight);
             result.add(resultWay);
 
             //process next way
-            Way nextWay = nextWayMap.get(curWay);
-            Node prevNode = curWay.getNode(curWay.getNodesCount() - 2);
-            Node headNode = curWay.lastNode();
-            Node nextNode = nextWay.getNode(1);
+            final var nextWay = nextWayMap.get(curWay);
+            final var prevNode = curWay.getNode(curWay.getNodesCount() - 2);
+            final var headNode = curWay.lastNode();
+            final var nextNode = nextWay.getNode(1);
 
             if (nextWay == topWay) {
@@ -1068,5 +1068,5 @@
             //                       |
 
-            int intersectionCount = 0;
+            var intersectionCount = 0;
 
             for (Way wayA : parts) {
@@ -1078,10 +1078,10 @@
                 if (wayA.lastNode().equals(headNode)) {
 
-                    Way wayB = nextWayMap.get(wayA);
+                    final var wayB = nextWayMap.get(wayA);
 
                     //test if wayA is opposite wayB relative to curWay and nextWay
 
-                    Node wayANode = wayA.getNode(wayA.getNodesCount() - 2);
-                    Node wayBNode = wayB.getNode(1);
+                    final var wayANode = wayA.getNode(wayA.getNodesCount() - 2);
+                    final var wayBNode = wayB.getNode(1);
 
                     boolean wayAToTheRight = Geometry.isToTheRightSideOfLine(prevNode, headNode, nextNode, wayANode);
@@ -1117,5 +1117,5 @@
      */
     private static void revertDuplicateTwoNodeWays(List<WayInPolygon> parts) {
-        for (int i = 0; i < parts.size(); i++) {
+        for (var i = 0; i < parts.size(); i++) {
             WayInPolygon w1 = parts.get(i);
             if (w1.way.getNodesCount() != 2)
@@ -1141,9 +1141,9 @@
     private List<Way> splitWayOnNodes(Way way, Set<Node> nodes, Map<Node, Way> oldestWayMap) {
 
-        List<Way> result = new ArrayList<>();
+        final var result = new ArrayList<Way>();
         List<List<Node>> chunks = buildNodeChunks(way, nodes);
 
         if (chunks.size() > 1) {
-            SplitWayCommand split = SplitWayCommand.splitWay(way, chunks,
+            final var split = SplitWayCommand.splitWay(way, chunks,
                     Collections.emptyList(), SplitWayCommand.Strategy.keepFirstChunk());
 
@@ -1159,6 +1159,6 @@
                 if (!way.isNew() && result.size() > 1) {
                     for (Way part : result) {
-                        Node n = part.firstNode();
-                        Way old = oldestWayMap.get(n);
+                        final var n = part.firstNode();
+                        final var old = oldestWayMap.get(n);
                         if (old == null || old.getUniqueId() > way.getUniqueId()) {
                             oldestWayMap.put(n, way);
@@ -1231,10 +1231,10 @@
 
         //TODO: bad performance for deep nestings...
-        List<PolygonLevel> result = new ArrayList<>();
+        final var result = new ArrayList<PolygonLevel>();
 
         for (AssembledPolygon outerWay : boundaryWays) {
 
-            boolean outerGood = true;
-            List<AssembledPolygon> innerCandidates = new ArrayList<>();
+            var outerGood = true;
+            final var innerCandidates = new ArrayList<AssembledPolygon>();
 
             for (AssembledPolygon innerWay : boundaryWays) {
@@ -1256,6 +1256,6 @@
 
             //add new outer polygon
-            AssembledMultipolygon pol = new AssembledMultipolygon(outerWay);
-            PolygonLevel polLev = new PolygonLevel(pol, level);
+            final var pol = new AssembledMultipolygon(outerWay);
+            final var polLev = new PolygonLevel(pol, level);
 
             //process inner ways
@@ -1288,16 +1288,16 @@
         // This seems to appear when is apply over invalid way like #9911 test-case
         // Remove all of these way to make the next work.
-        List<WayInPolygon> cleanMultigonWays = new ArrayList<>();
+        final var cleanMultigonWays = new ArrayList<WayInPolygon>();
         for (WayInPolygon way: multigonWays) {
             if (way.way.getNodesCount() != 2 || !way.way.isClosed())
                 cleanMultigonWays.add(way);
         }
-        WayTraverser traverser = new WayTraverser(cleanMultigonWays);
-        List<AssembledPolygon> result = new ArrayList<>();
+        final var traverser = new WayTraverser(cleanMultigonWays);
+        final var result = new ArrayList<AssembledPolygon>();
 
         WayInPolygon startWay;
         while ((startWay = traverser.startNewWay()) != null) {
-            List<WayInPolygon> path = new ArrayList<>();
-            List<WayInPolygon> startWays = new ArrayList<>();
+            final var path = new ArrayList<WayInPolygon>();
+            final var startWays = new ArrayList<WayInPolygon>();
             path.add(startWay);
             while (true) {
@@ -1318,5 +1318,5 @@
                 if (path.get(0) == nextWay) {
                     // path is closed -> stop here
-                    AssembledPolygon ring = new AssembledPolygon(path);
+                    final var ring = new AssembledPolygon(path);
                     if (ring.getNodes().size() <= 2) {
                         // Invalid ring (2 nodes) -> remove
@@ -1357,13 +1357,13 @@
      */
     public static List<AssembledPolygon> fixTouchingPolygons(List<AssembledPolygon> polygons) {
-        List<AssembledPolygon> newPolygons = new ArrayList<>();
+        final var newPolygons = new ArrayList<AssembledPolygon>();
 
         for (AssembledPolygon ring : polygons) {
             ring.reverse();
-            WayTraverser traverser = new WayTraverser(ring.ways);
+            final var traverser = new WayTraverser(ring.ways);
             WayInPolygon startWay;
 
             while ((startWay = traverser.startNewWay()) != null) {
-                List<WayInPolygon> simpleRingWays = new ArrayList<>();
+                final var simpleRingWays = new ArrayList<WayInPolygon>();
                 simpleRingWays.add(startWay);
                 WayInPolygon nextWay;
@@ -1374,5 +1374,5 @@
                 }
                 traverser.removeWays(simpleRingWays);
-                AssembledPolygon simpleRing = new AssembledPolygon(simpleRingWays);
+                final var simpleRing = new AssembledPolygon(simpleRingWays);
                 simpleRing.reverse();
                 newPolygons.add(simpleRing);
@@ -1411,5 +1411,5 @@
      */
     private Multipolygon joinPolygon(AssembledMultipolygon polygon) throws UserCancelException {
-        Multipolygon result = new Multipolygon(joinWays(polygon.outerWay.ways));
+        final var result = new Multipolygon(joinWays(polygon.outerWay.ways));
 
         for (AssembledPolygon pol : polygon.innerWays) {
@@ -1429,5 +1429,5 @@
 
         //leave original orientation, if all paths are reverse.
-        boolean allReverse = true;
+        var allReverse = true;
         for (WayInPolygon way : ways) {
             allReverse &= !way.insideToTheRight;
@@ -1440,5 +1440,5 @@
         }
 
-        Way joinedWay = joinOrientedWays(ways);
+        final var joinedWay = joinOrientedWays(ways);
 
         //should not happen
@@ -1462,6 +1462,6 @@
         // the user about this.
 
-        List<Way> actionWays = new ArrayList<>(ways.size());
-        int oldestPos = 0;
+        final var actionWays = new ArrayList<Way>(ways.size());
+        var oldestPos = 0;
         Way oldest = ways.get(0).way;
         for (WayInPolygon way : ways) {
@@ -1511,5 +1511,5 @@
             }
 
-            boolean hasKnownOuter = false;
+            var hasKnownOuter = false;
             outerWays.clear();
             innerWays.clear();
@@ -1538,5 +1538,5 @@
             }
 
-            Way outerWay = outerWays.get(0);
+            final var outerWay = outerWays.get(0);
 
             //retain only selected inner ways
@@ -1588,5 +1588,5 @@
             processedInnerWays.addAll(innerWays);
 
-            Multipolygon pol = new Multipolygon(outerWay);
+            final var pol = new Multipolygon(outerWay);
             pol.innerWays.addAll(innerWays);
 
@@ -1615,5 +1615,5 @@
         OsmDataLayer layer = getLayerManager().getEditLayer();
         // Create new multipolygon relation and add all inner ways to it
-        Relation newRel = new Relation();
+        final var newRel = new Relation();
         newRel.put("type", "multipolygon");
         for (Way w : inner) {
@@ -1650,5 +1650,5 @@
 
                 cmds.add(new ChangeMembersCommand(r, members));
-                RelationRole saverel = new RelationRole(r, rm.getRole());
+                final var saverel = new RelationRole(r, rm.getRole());
                 if (!result.contains(saverel)) {
                     result.add(saverel);
@@ -1701,5 +1701,5 @@
         default:
             // Create a new relation with all previous members and (Way)outer as outer.
-            Relation newRel = new Relation();
+            final var newRel = new Relation();
             for (RelationRole r : multiouters) {
                 // Add members
Index: trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 19048)
@@ -7,4 +7,5 @@
 
 import java.awt.Component;
+import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
@@ -146,6 +147,6 @@
 
         // Finally, applicableWays contains only one perfect way
-        final Way selectedWay = applicableWays.get(0);
-        final List<OsmPrimitive> sel = new ArrayList<>(ds.getSelectedRelations());
+        final var selectedWay = applicableWays.get(0);
+        final var sel = new ArrayList<OsmPrimitive>(ds.getSelectedRelations());
         sel.addAll(selectedWays);
         doSplitWayShowSegmentSelection(selectedWay, selectedNodes, sel);
@@ -164,5 +165,5 @@
         if (wayChunks != null) {
             final List<Way> newWays = SplitWayCommand.createNewWaysFromChunks(splitWay, wayChunks);
-            final Way wayToKeep = SplitWayCommand.Strategy.keepLongestChunk().determineWayToKeep(newWays);
+            final var wayToKeep = SplitWayCommand.Strategy.keepLongestChunk().determineWayToKeep(newWays);
 
             if (ExpertToggleAction.isExpert() && !splitWay.isNew()) {
@@ -210,7 +211,7 @@
 
             setButtonIcons("ok", "cancel");
-            final JPanel pane = new JPanel(new GridBagLayout());
-            pane.add(new JLabel(getTitle()), GBC.eol().fill(GBC.HORIZONTAL));
-            pane.add(list, GBC.eop().fill(GBC.HORIZONTAL));
+            final var pane = new JPanel(new GridBagLayout());
+            pane.add(new JLabel(getTitle()), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
+            pane.add(list, GBC.eop().fill(GridBagConstraints.HORIZONTAL));
             setContent(pane);
             setDefaultCloseOperation(HIDE_ON_CLOSE);
@@ -224,7 +225,7 @@
                     final Collection<WaySegment> segments = new ArrayList<>(selected.getNodesCount() - 1);
                     final Iterator<Node> it = selected.getNodes().iterator();
-                    Node previousNode = it.next();
+                    var previousNode = it.next();
                     while (it.hasNext()) {
-                        final Node node = it.next();
+                        final var node = it.next();
                         segments.add(WaySegment.forNodePair(selectedWay, previousNode, node));
                         previousNode = node;
@@ -237,5 +238,5 @@
 
         protected void setHighlightedWaySegments(Collection<WaySegment> segments) {
-            DataSet ds = selectedWay.getDataSet();
+            final var ds = selectedWay.getDataSet();
             if (ds != null) {
                 ds.setHighlightedWaySegments(segments);
@@ -247,5 +248,5 @@
         public void setVisible(boolean visible) {
             super.setVisible(visible);
-            DataSet ds = selectedWay.getDataSet();
+            final var ds = selectedWay.getDataSet();
             if (visible) {
                 DISPLAY_COUNT.incrementAndGet();
@@ -276,5 +277,5 @@
         }
 
-        private class SplitWayDataSetListener implements DataSetListener {
+        private final class SplitWayDataSetListener implements DataSetListener {
 
             @Override
@@ -336,5 +337,5 @@
         @Override
         public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
-            final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+            final var c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
             final String name = DefaultNameFormatter.getInstance().format((Way) value);
             // get rid of id from DefaultNameFormatter.decorateNameWithId()
@@ -359,5 +360,5 @@
         // Special case - one of the selected ways touches (not cross) way that we want to split
         if (selectedNodes.size() == 1) {
-            Node n = selectedNodes.get(0);
+            final var n = selectedNodes.get(0);
             List<Way> referredWays = n.getParentWays();
             Way inTheMiddle = null;
Index: trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 19048)
@@ -23,5 +23,4 @@
 import java.util.function.Predicate;
 import java.util.function.Supplier;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -160,5 +159,5 @@
         @Override
         public Match get(String keyword, boolean caseSensitive, boolean regexSearch, PushbackTokenizer tokenizer) throws SearchParseError {
-            switch(keyword) {
+            switch (keyword) {
             case MODIFIED:
                 return new Modified();
@@ -1140,6 +1139,6 @@
                     value = Normalizer.normalize(value, Normalizer.Form.NFC);
 
-                    Matcher keyMatcher = searchRegex.matcher(key);
-                    Matcher valMatcher = searchRegex.matcher(value);
+                    final var keyMatcher = searchRegex.matcher(key);
+                    final var valMatcher = searchRegex.matcher(value);
 
                     boolean keyMatchFound = keyMatcher.find();
@@ -1623,5 +1622,5 @@
      * Matches objects that are new (i.e. have not been uploaded to the server)
      */
-    private static class New extends Match {
+    private static final class New extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1638,5 +1637,5 @@
      * Matches all objects that have been modified, created, or undeleted
      */
-    private static class Modified extends Match {
+    private static final class Modified extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1653,5 +1652,5 @@
      * Matches all objects that have been deleted
      */
-    private static class Deleted extends Match {
+    private static final class Deleted extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1668,5 +1667,5 @@
      * Matches all objects currently selected
      */
-    private static class Selected extends Match {
+    private static final class Selected extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1685,5 +1684,5 @@
      * fetched from the server.
      */
-    private static class Incomplete extends Match {
+    private static final class Incomplete extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1702,5 +1701,5 @@
      * org.openstreetmap.josm.data.osm.OsmPrimitive.getUninterestingKeys()
      */
-    private static class Untagged extends Match {
+    private static final class Untagged extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1717,5 +1716,5 @@
      * Matches ways which are closed (i.e. first and last node are the same)
      */
-    private static class Closed extends Match {
+    private static final class Closed extends Match {
         @Override
         public boolean match(OsmPrimitive osm) {
@@ -1818,5 +1817,5 @@
             if (!(osm instanceof Way))
                 return null;
-            Way way = (Way) osm;
+            final var way = (Way) osm;
             return (long) way.getLength();
         }
@@ -1971,5 +1970,5 @@
 
             try {
-                String groupSuffix = name.substring(0, name.length() - 2); // try to remove '/*'
+                final var groupSuffix = name.substring(0, name.length() - 2); // try to remove '/*'
                 TaggingPresetMenu group = preset.group;
 
@@ -2179,9 +2178,9 @@
             } else if (tokenizer.readIfEqual(Token.COLON)) {
                 // see if we have a Match that takes a data parameter
-                SimpleMatchFactory factory = simpleMatchFactoryMap.get(key);
+                final var factory = simpleMatchFactoryMap.get(key);
                 if (factory != null)
                     return factory.get(key, caseSensitive, regexSearch, tokenizer);
 
-                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
+                final var unaryFactory = unaryMatchFactoryMap.get(key);
                 if (unaryFactory != null)
                     return getValidate(unaryFactory, key, tokenizer);
@@ -2196,9 +2195,9 @@
                 return new BooleanMatch(key, false);
             else {
-                SimpleMatchFactory factory = simpleMatchFactoryMap.get(key);
+                final var factory = simpleMatchFactoryMap.get(key);
                 if (factory != null)
                     return factory.get(key, caseSensitive, regexSearch, null).validate();
 
-                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
+                final var unaryFactory = unaryMatchFactoryMap.get(key);
                 if (unaryFactory != null)
                     return getValidate(unaryFactory, key, null);
@@ -2222,5 +2221,5 @@
 
     private static int regexFlags(boolean caseSensitive) {
-        int searchFlags = 0;
+        var searchFlags = 0;
 
         // Enables canonical Unicode equivalence so that e.g. the two
Index: trunk/src/org/openstreetmap/josm/data/validation/ValidatorCLI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/ValidatorCLI.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/data/validation/ValidatorCLI.java	(revision 19048)
@@ -11,5 +11,4 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -27,9 +26,8 @@
 import java.util.stream.Collectors;
 
-import org.apache.commons.compress.utils.FileNameUtils;
+import org.apache.commons.io.FilenameUtils;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
 import org.openstreetmap.josm.cli.CLIModule;
 import org.openstreetmap.josm.data.Preferences;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.preferences.JosmBaseDirectories;
 import org.openstreetmap.josm.data.preferences.JosmUrls;
@@ -176,5 +174,5 @@
             }
             this.initialize();
-            final ProgressMonitor fileMonitor = progressMonitorFactory.get();
+            final var fileMonitor = progressMonitorFactory.get();
             fileMonitor.beginTask(tr("Processing files..."), this.input.size());
             for (String inputFile : this.input) {
@@ -202,5 +200,5 @@
      */
     private static void processMapcssFile(final String inputFile) throws ParseException {
-        final MapCSSStyleSource styleSource = new MapCSSStyleSource(new File(inputFile).toURI().getPath(), inputFile, inputFile);
+        final var styleSource = new MapCSSStyleSource(new File(inputFile).toURI().getPath(), inputFile, inputFile);
         styleSource.loadStyleSource();
         if (!styleSource.getErrors().isEmpty()) {
@@ -221,6 +219,6 @@
         // Check asserts
         Config.getPref().putBoolean("validator.check_assert_local_rules", true);
-        final MapCSSTagChecker mapCSSTagChecker = new MapCSSTagChecker();
-        final Collection<String> assertionErrors = new ArrayList<>();
+        final var mapCSSTagChecker = new MapCSSTagChecker();
+        final var assertionErrors = new ArrayList<String>();
         final MapCSSTagChecker.ParseResult result = mapCSSTagChecker.addMapCSS(new File(inputFile).toURI().getPath(),
                 assertionErrors::add);
@@ -247,8 +245,8 @@
      */
     private void processFile(final String inputFile) throws IllegalDataException, IOException {
-        final File inputFileFile = new File(inputFile);
+        final var inputFileFile = new File(inputFile);
         final List<FileImporter> inputFileImporters = ExtensionFileFilter.getImporters().stream()
                 .filter(importer -> importer.acceptFile(inputFileFile)).collect(Collectors.toList());
-        final Stopwatch stopwatch = Stopwatch.createStarted();
+        final var stopwatch = Stopwatch.createStarted();
         if (inputFileImporters.stream().noneMatch(fileImporter ->
                 fileImporter.importDataHandleExceptions(inputFileFile, progressMonitorFactory.get()))) {
@@ -263,24 +261,24 @@
                     .stream().filter(layer -> inputFileFile.equals(layer.getAssociatedFile()))
                     .findFirst().orElseThrow(() -> new JosmRuntimeException(tr("Could not find a layer for {0}", inputFile)));
-            final DataSet dataSet = dataLayer.getDataSet();
+            final var dataSet = dataLayer.getDataSet();
             if (this.changeFiles.containsKey(inputFile)) {
-                ProgressMonitor changeFilesMonitor = progressMonitorFactory.get();
+                final var changeFilesMonitor = progressMonitorFactory.get();
                 for (String changeFile : this.changeFiles.getOrDefault(inputFile, Collections.emptyList())) {
-                    try (InputStream changeStream = Compression.getUncompressedFileInputStream(Paths.get(changeFile))) {
+                    try (var changeStream = Compression.getUncompressedFileInputStream(Paths.get(changeFile))) {
                         dataSet.mergeFrom(OsmChangeReader.parseDataSet(changeStream, changeFilesMonitor));
                     }
                 }
             }
-            Path path = Paths.get(outputFile);
+            final var path = Paths.get(outputFile);
             if (path.toFile().isFile() && !Files.deleteIfExists(path)) {
                 Logging.error("Could not delete {0}, attempting to append", outputFile);
             }
-            GeoJSONMapRouletteWriter geoJSONMapRouletteWriter = new GeoJSONMapRouletteWriter(dataSet);
+            final var geoJSONMapRouletteWriter = new GeoJSONMapRouletteWriter(dataSet);
             OsmValidator.initializeTests();
 
-            try (OutputStream fileOutputStream = Files.newOutputStream(path)) {
+            try (var fileOutputStream = Files.newOutputStream(path)) {
                 // The first writeErrors catches anything that was written, for whatever reason. This is probably never
                 // going to be called.
-                ValidationTask validationTask = new ValidationTask(errors -> writeErrors(geoJSONMapRouletteWriter, fileOutputStream, errors),
+                final var validationTask = new ValidationTask(errors -> writeErrors(geoJSONMapRouletteWriter, fileOutputStream, errors),
                         progressMonitorFactory.get(), OsmValidator.getEnabledTests(false),
                         dataSet.allPrimitives(), Collections.emptyList(), false);
@@ -320,12 +318,12 @@
      */
     private static String getDefaultOutputName(final String inputString) {
-        final String extension = FileNameUtils.getExtension(inputString);
+        final String extension = FilenameUtils.getExtension(inputString);
         if (!Arrays.asList("zip", "bz", "xz", "geojson").contains(extension)) {
-            return FileNameUtils.getBaseName(inputString) + ".geojson";
+            return FilenameUtils.getBaseName(inputString) + ".geojson";
         } else if ("geojson".equals(extension)) {
             // Account for geojson input files
-            return FileNameUtils.getBaseName(inputString) + ".validated.geojson";
-        }
-        return FileNameUtils.getBaseName(FileNameUtils.getBaseName(inputString)) + ".geojson";
+            return FilenameUtils.getBaseName(inputString) + ".validated.geojson";
+        }
+        return FilenameUtils.getBaseName(FilenameUtils.getBaseName(inputString)) + ".geojson";
     }
 
@@ -348,5 +346,5 @@
     /**
      * Initialize everything that might be needed
-     *
+     * <p>
      * Arguments may need to be parsed first.
      */
@@ -369,6 +367,6 @@
         Logging.setLogLevel(Level.INFO);
 
-        OptionParser parser = new OptionParser("JOSM validate");
-        final AtomicReference<String> currentInput = new AtomicReference<>(null);
+        final var parser = new OptionParser("JOSM validate");
+        final var currentInput = new AtomicReference<String>(null);
         for (Option o : Option.values()) {
             if (o.requiresArgument()) {
@@ -425,7 +423,7 @@
             break;
         case LOAD_PREFERENCES:
-            final Preferences tempPreferences = new Preferences();
+            final var tempPreferences = new Preferences();
             tempPreferences.enableSaveOnPut(false);
-            CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(tempPreferences);
+            final var config = new CustomConfigurator.XMLCommandProcessor(tempPreferences);
             try (InputStream is = Utils.openStream(new File(argument).toURI().toURL())) {
                 config.openAndReadXML(is);
@@ -435,5 +433,5 @@
             final IPreferences pref = Config.getPref();
             if (pref instanceof MemoryPreferences) {
-                final MemoryPreferences memoryPreferences = (MemoryPreferences) pref;
+                final var memoryPreferences = (MemoryPreferences) pref;
                 tempPreferences.getAllSettings().forEach(memoryPreferences::putSetting);
             } else {
@@ -454,5 +452,5 @@
 
     private static String getHelp() {
-        final String helpPadding = "\t                          ";
+        final var helpPadding = "\t                          ";
         // CHECKSTYLE.OFF: SingleSpaceSeparator
         return tr("JOSM Validation command line interface") + "\n\n" +
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 19048)
@@ -48,5 +48,5 @@
      * {@code type=associatedStreet} and {@code type=street} relations.
      */
-    private static class AssociatedStreetRoleStreetSorter implements AdditionalSorter {
+    private static final class AssociatedStreetRoleStreetSorter implements AdditionalSorter {
 
         @Override
@@ -65,5 +65,5 @@
      * {@code type=associatedStreet} and {@code type=street} relations.
      */
-    private static class AssociatedStreetRoleAddressHouseSorter implements AdditionalSorter {
+    private static final class AssociatedStreetRoleAddressHouseSorter implements AdditionalSorter {
 
         @Override
@@ -93,5 +93,5 @@
      * {@code type=public_transport} relations.
      */
-    private static class PublicTransportRoleStopPlatformSorter implements AdditionalSorter {
+    private static final class PublicTransportRoleStopPlatformSorter implements AdditionalSorter {
 
         @Override
@@ -140,5 +140,5 @@
      * {@code type=restriction} relations.
      */
-    private static class FromViaToSorter implements AdditionalSorter {
+    private static final class FromViaToSorter implements AdditionalSorter {
 
         private static final List<String> ROLES = Arrays.asList("from", "via", "to");
@@ -173,5 +173,5 @@
         // Dispatch members to the first adequate sorter
         for (RelationMember m : relationMembers) {
-            boolean wasAdded = false;
+            var wasAdded = false;
             for (AdditionalSorter sorter : ADDITIONAL_SORTERS) {
                 if (sorter.acceptsMember(relationMembers, m)) {
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 19048)
@@ -141,5 +141,5 @@
                 ht("/Action/Upload#ChangesetFull")
         );
-        switch(ret) {
+        switch (ret) {
         case 0: return MaxChangesetSizeExceededPolicy.AUTOMATICALLY_OPEN_NEW_CHANGESETS;
         case 1: return MaxChangesetSizeExceededPolicy.FILL_ONE_CHANGESET_AND_RETURN_TO_UPLOAD_DIALOG;
@@ -168,7 +168,7 @@
             strategy.setPolicy(promptUserForPolicy());
         }
-        switch(strategy.getPolicy()) {
+        switch (strategy.getPolicy()) {
         case AUTOMATICALLY_OPEN_NEW_CHANGESETS:
-            Changeset newChangeSet = new Changeset();
+            final var newChangeSet = new Changeset();
             newChangeSet.setKeys(changeset.getKeys());
             closeChangeset();
@@ -280,5 +280,5 @@
                         processedPrimitives.addAll(writer.getProcessedPrimitives()); // OsmPrimitive in => OsmPrimitive out
                     }
-                    switch(e.getSource()) {
+                    switch (e.getSource()) {
                     case UPLOAD_DATA:
                         // Most likely the changeset is full. Try to recover and continue
@@ -319,5 +319,5 @@
             }
         } finally {
-            if (MessageNotifier.PROP_NOTIFIER_ENABLED.get()) {
+            if (Boolean.TRUE.equals(MessageNotifier.PROP_NOTIFIER_ENABLED.get())) {
                 MessageNotifier.start();
             }
@@ -372,5 +372,5 @@
             if (uploadCanceled) return;
             if (lastException == null) {
-                HtmlPanel panel = new HtmlPanel(
+                final var panel = new HtmlPanel(
                         "<h3><a href=\"" + Config.getUrls().getBaseBrowseUrl() + "/changeset/" + changeset.getId() + "\">"
                                 + tr("Upload successful!") + "</a></h3>");
@@ -393,5 +393,5 @@
                     return;
                 if (e.getSource() == ChangesetClosedException.Source.UPLOAD_DATA) {
-                    switch(strategy.getPolicy()) {
+                    switch (strategy.getPolicy()) {
                     case ABORT:
                         break; /* do nothing - we return to map editing */
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 19048)
@@ -67,5 +67,4 @@
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
 import org.openstreetmap.josm.gui.layer.geoimage.AdjustTimezoneAndOffsetDialog.AdjustListener;
-import org.openstreetmap.josm.gui.layer.geoimage.SynchronizeTimeFromPhotoDialog.TimeZoneItem;
 import org.openstreetmap.josm.gui.layer.gpx.GpxDataHelper;
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
@@ -173,8 +172,8 @@
                 // Search whether an other layer has yet defined some bounding box.
                 // If none, we'll zoom to the bounding box of the layer with the photos.
-                boolean boundingBoxedLayerFound = false;
+                var boundingBoxedLayerFound = false;
                 for (Layer l: MainApplication.getLayerManager().getLayers()) {
                     if (l != yLayer) {
-                        BoundingXYVisitor bbox = new BoundingXYVisitor();
+                        final var bbox = new BoundingXYVisitor();
                         l.visitBoundingBox(bbox);
                         if (bbox.getBounds() != null) {
@@ -185,5 +184,5 @@
                 }
                 if (!boundingBoxedLayerFound) {
-                    BoundingXYVisitor bbox = new BoundingXYVisitor();
+                    final var bbox = new BoundingXYVisitor();
                     yLayer.visitBoundingBox(bbox);
                     MainApplication.getMap().mapView.zoomTo(bbox);
@@ -261,16 +260,16 @@
      * been loaded yet. It displays a FileChooser dialog to select the GPX file to be loaded.
      */
-    private class LoadGpxDataActionListener implements ActionListener {
+    private final class LoadGpxDataActionListener implements ActionListener {
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            File sel = GpxDataHelper.chooseGpxDataFile();
+            final var sel = GpxDataHelper.chooseGpxDataFile();
             if (sel != null) {
                 try {
                     outerPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                     removeDuplicates(sel);
-                    GpxData data = GpxDataHelper.loadGpxData(sel);
+                    final var data = GpxDataHelper.loadGpxData(sel);
                     if (data != null) {
-                        GpxDataWrapper elem = new GpxDataWrapper(sel.getName(), data, sel);
+                        final var elem = new GpxDataWrapper(sel.getName(), data, sel);
                         gpxModel.addElement(elem);
                         gpxModel.setSelectedItem(elem);
@@ -284,5 +283,5 @@
     }
 
-    private class UseSupportLayerActionListener implements ActionListener {
+    private final class UseSupportLayerActionListener implements ActionListener {
 
         @Override
@@ -296,9 +295,9 @@
     }
 
-    private class AdvancedSettingsActionListener implements ActionListener {
+    private final class AdvancedSettingsActionListener implements ActionListener {
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            AdvancedCorrelationSettingsDialog ed = new AdvancedCorrelationSettingsDialog(MainApplication.getMainFrame(), forceTags);
+            final var ed = new AdvancedCorrelationSettingsDialog(MainApplication.getMainFrame(), forceTags);
             if (ed.showDialog().getValue() == 1) {
                 forceTags = ed.isForceTaggingSelected(); // This setting is not supposed to be saved permanently
@@ -317,12 +316,11 @@
      * @author chris
      */
-    private class SetOffsetActionListener implements ActionListener {
+    private final class SetOffsetActionListener implements ActionListener {
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            boolean isOk = false;
+            var isOk = false;
             while (!isOk) {
-                SynchronizeTimeFromPhotoDialog ed = new SynchronizeTimeFromPhotoDialog(
-                        MainApplication.getMainFrame(), yLayer.getImageData().getImages());
+                final var ed = new SynchronizeTimeFromPhotoDialog(MainApplication.getMainFrame(), yLayer.getImageData().getImages());
                 int answer = ed.showDialog().getValue();
                 if (answer != 1)
@@ -340,5 +338,5 @@
                 }
 
-                TimeZoneItem selectedTz = ed.getTimeZoneItem();
+                final var selectedTz = ed.getTimeZoneItem();
 
                 Config.getPref().put("geoimage.timezoneid", selectedTz.getID());
@@ -354,13 +352,13 @@
     }
 
-    private static class GpxLayerAddedListener implements LayerChangeListener {
+    private static final class GpxLayerAddedListener implements LayerChangeListener {
         @Override
         public void layerAdded(LayerAddEvent e) {
-            Layer layer = e.getAddedLayer();
+            final var layer = e.getAddedLayer();
             if (layer instanceof GpxDataContainer) {
-                GpxData gpx = ((GpxDataContainer) layer).getGpxData();
-                File file = gpx.storageFile;
+                final var gpx = ((GpxDataContainer) layer).getGpxData();
+                final var file = gpx.storageFile;
                 removeDuplicates(file);
-                GpxDataWrapper gdw = new GpxDataWrapper(layer.getName(), gpx, file);
+                final var gdw = new GpxDataWrapper(layer.getName(), gpx, file);
                 layer.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
                 gpxModel.addElement(gdw);
@@ -376,7 +374,7 @@
         @Override
         public void layerRemoving(LayerRemoveEvent e) {
-            Layer layer = e.getRemovedLayer();
+            final var layer = e.getRemovedLayer();
             if (layer instanceof GpxDataContainer) {
-                GpxData removedGpxData = ((GpxDataContainer) layer).getGpxData();
+                final var removedGpxData = ((GpxDataContainer) layer).getGpxData();
                 for (int i = gpxModel.getSize() - 1; i >= 0; i--) {
                     GpxData data = gpxModel.getElementAt(i).data;
@@ -428,6 +426,6 @@
         for (AbstractModifiableLayer cur : MainApplication.getLayerManager().getLayersOfType(AbstractModifiableLayer.class)) {
             if (cur instanceof GpxDataContainer) {
-                GpxData data = ((GpxDataContainer) cur).getGpxData();
-                GpxDataWrapper gdw = new GpxDataWrapper(cur.getName(), data, data.storageFile);
+                final var data = ((GpxDataContainer) cur).getGpxData();
+                final var gdw = new GpxDataWrapper(cur.getName(), data, data.storageFile);
                 cur.addPropertyChangeListener(new GpxLayerRenamedListener(gdw));
                 gpxModel.addElement(gdw);
@@ -471,10 +469,10 @@
     @Override
     public void actionPerformed(ActionEvent ae) {
-        NoGpxDataWrapper nogdw = new NoGpxDataWrapper();
+        final var nogdw = new NoGpxDataWrapper();
         if (gpxModel == null) {
             constructGpxModel(nogdw);
         }
 
-        JPanel panelCb = new JPanel();
+        final var panelCb = new JPanel();
 
         panelCb.add(new JLabel(tr("GPX track: ")));
@@ -485,5 +483,5 @@
         panelCb.add(cbGpx);
 
-        JButton buttonOpen = new JButton(tr("Open another GPX trace"));
+        final var buttonOpen = new JButton(tr("Open another GPX trace"));
         buttonOpen.addActionListener(new LoadGpxDataActionListener());
         panelCb.add(buttonOpen);
@@ -493,5 +491,5 @@
         panelCb.add(buttonSupport);
 
-        JPanel panelTf = new JPanel(new GridBagLayout());
+        final var panelTf = new JPanel(new GridBagLayout());
 
         timezone = loadTimezone();
@@ -505,19 +503,19 @@
         tfOffset.setText(delta.formatOffset());
 
-        JButton buttonViewGpsPhoto = new JButton(tr("<html>Use photo of an accurate clock,<br>e.g. GPS receiver display</html>"));
+        final var buttonViewGpsPhoto = new JButton(tr("<html>Use photo of an accurate clock,<br>e.g. GPS receiver display</html>"));
         buttonViewGpsPhoto.setIcon(ImageProvider.get("clock"));
         buttonViewGpsPhoto.addActionListener(new SetOffsetActionListener());
 
-        JButton buttonAutoGuess = new JButton(tr("Auto-Guess"));
+        final var buttonAutoGuess = new JButton(tr("Auto-Guess"));
         buttonAutoGuess.setToolTipText(tr("Matches first photo with first gpx point"));
         buttonAutoGuess.addActionListener(new AutoGuessActionListener());
 
-        JButton buttonAdjust = new JButton(tr("Manual adjust"));
+        final var buttonAdjust = new JButton(tr("Manual adjust"));
         buttonAdjust.addActionListener(new AdjustActionListener());
 
-        JButton buttonAdvanced = new JButton(tr("Advanced settings..."));
+        final var buttonAdvanced = new JButton(tr("Advanced settings..."));
         buttonAdvanced.addActionListener(new AdvancedSettingsActionListener());
 
-        JLabel labelPosition = new JLabel(tr("Override position for: "));
+        final var labelPosition = new JLabel(tr("Override position for: "));
 
         int numAll = yLayer.getSortedImgList(true, true).size();
@@ -537,11 +535,11 @@
         cbShowThumbs.setEnabled(!yLayer.thumbsLoaded);
 
-        int y = 0;
-        GBC gbc = GBC.eol();
+        var y = 0;
+        var gbc = GBC.eol();
         gbc.gridx = 0;
         gbc.gridy = y++;
         panelTf.add(panelCb, gbc);
 
-        gbc = GBC.eol().fill(GBC.HORIZONTAL).insets(0, 0, 0, 12);
+        gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 12);
         gbc.gridx = 0;
         gbc.gridy = y++;
@@ -553,5 +551,5 @@
         panelTf.add(new JLabel(tr("Timezone: ")), gbc);
 
-        gbc = GBC.std().fill(GBC.HORIZONTAL);
+        gbc = GBC.std().fill(GridBagConstraints.HORIZONTAL);
         gbc.gridx = 1;
         gbc.gridy = y++;
@@ -564,5 +562,5 @@
         panelTf.add(new JLabel(tr("Offset:")), gbc);
 
-        gbc = GBC.std().fill(GBC.HORIZONTAL);
+        gbc = GBC.std().fill(GridBagConstraints.HORIZONTAL);
         gbc.gridx = 1;
         gbc.gridy = y++;
@@ -579,5 +577,5 @@
         panelTf.add(buttonViewGpsPhoto, gbc);
 
-        gbc = GBC.std().fill(GBC.BOTH).insets(5, 5, 5, 5);
+        gbc = GBC.std().fill(GridBagConstraints.BOTH).insets(5, 5, 5, 5);
         gbc.gridx = 1;
         gbc.gridy = y++;
@@ -591,5 +589,5 @@
         panelTf.add(buttonAdjust, gbc);
 
-        gbc = GBC.eol().fill(GBC.HORIZONTAL).insets(0, 12, 0, 0);
+        gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0);
         gbc.gridx = 0;
         gbc.gridy = y++;
@@ -616,5 +614,5 @@
         panelTf.add(cbShowThumbs, gbc);
 
-        gbc = GBC.eol().fill(GBC.HORIZONTAL).insets(0, 12, 0, 0);
+        gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0);
         sepDirectionPosition = new JSeparator(SwingConstants.HORIZONTAL);
         panelTf.add(sepDirectionPosition, gbc);
@@ -627,5 +625,5 @@
         expertChanged(ExpertToggleAction.isExpert());
 
-        final JPanel statusBar = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+        final var statusBar = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
         statusBar.setBorder(BorderFactory.createLoweredBevelBorder());
         statusBarText = new JLabel(" ");
@@ -633,5 +631,5 @@
         statusBar.add(statusBarText);
 
-        RepaintTheMapListener repaintTheMap = new RepaintTheMapListener(yLayer);
+        final var repaintTheMap = new RepaintTheMapListener(yLayer);
         pDirectionPosition.addFocusListenerOnComponent(repaintTheMap);
         tfTimezone.addFocusListener(repaintTheMap);
@@ -808,10 +806,10 @@
      * Presents dialog with sliders for manual adjust.
      */
-    private class AdjustActionListener implements ActionListener {
+    private final class AdjustActionListener implements ActionListener {
 
         @Override
         public void actionPerformed(ActionEvent e) {
 
-            final GpxTimeOffset offset = GpxTimeOffset.milliseconds(
+            final var offset = GpxTimeOffset.milliseconds(
                     delta.getMilliseconds() + Math.round(timezone.getHours() * TimeUnit.HOURS.toMillis(1)));
             final int dayOffset = offset.getDayOffset();
@@ -895,5 +893,5 @@
     }
 
-    private class AutoGuessActionListener implements ActionListener {
+    private final class AutoGuessActionListener implements ActionListener {
 
         @Override
@@ -943,5 +941,5 @@
     }
 
-    private GpxDataWrapper selectedGPX(boolean complain) {
+    private static GpxDataWrapper selectedGPX(boolean complain) {
         Object item = gpxModel.getSelectedItem();
 
@@ -961,5 +959,5 @@
         if (cbGpx != null) {
             // Force the JCombobox to remove its eventListener from the static GpxDataWrapper
-            cbGpx.setModel(new DefaultComboBoxModel<GpxDataWrapper>());
+            cbGpx.setModel(new DefaultComboBoxModel<>());
             cbGpx = null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/RemoteEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/RemoteEntry.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/RemoteEntry.java	(revision 19048)
@@ -296,9 +296,9 @@
     @Override
     public InputStream getInputStream() throws IOException {
-        URI u = getImageURI();
+        final var u = getImageURI();
         if (u.getScheme().contains("file")) {
             return Files.newInputStream(Paths.get(u));
         }
-        HttpClient client = HttpClient.create(u.toURL());
+        final var client = HttpClient.create(u.toURL());
         InputStream actual = client.connect().getContent();
         return new BufferedInputStream(actual) {
@@ -343,5 +343,5 @@
     @Override
     public boolean equals(Object obj) {
-        if (super.equals(obj)) {
+        if (this == obj) {
             return true;
         }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LabelCompositionStrategy.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LabelCompositionStrategy.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LabelCompositionStrategy.java	(revision 19048)
@@ -167,17 +167,15 @@
         /* Is joining an array really that complicated in Java? */
         private static String[] getDefaultNameTags() {
-            ArrayList<String> tags = new ArrayList<String>(Arrays.asList(LanguageInfo.getOSMLocaleCodes("name:")));
-            tags.addAll(Arrays.asList(new String[]{
-                "name",
-                "int_name",
-                "distance",
-                "railway:position",
-                "ref",
-                "operator",
-                "brand",
-                "addr:unit",
-                "addr:flats",
-                "addr:housenumber"
-            }));
+            final var tags = new ArrayList<String>(Arrays.asList(LanguageInfo.getOSMLocaleCodes("name:")));
+            tags.addAll(Arrays.asList("name",
+                    "int_name",
+                    "distance",
+                    "railway:position",
+                    "ref",
+                    "operator",
+                    "brand",
+                    "addr:unit",
+                    "addr:flats",
+                    "addr:housenumber"));
             return tags.toArray(String[]::new);
         }
@@ -251,5 +249,5 @@
 
         private String getPrimitiveName(IPrimitive n) {
-            StringBuilder name = new StringBuilder();
+            final var name = new StringBuilder();
             if (!n.hasKeys()) return null;
             nameTags.stream().map(n::get).filter(Objects::nonNull).findFirst()
Index: trunk/src/org/openstreetmap/josm/gui/widgets/JosmTextField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/JosmTextField.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/JosmTextField.java	(revision 19048)
@@ -5,5 +5,4 @@
 import java.awt.ComponentOrientation;
 import java.awt.Font;
-import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
@@ -19,8 +18,8 @@
 
 import javax.swing.Icon;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
 import javax.swing.JTextField;
 import javax.swing.RepaintManager;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
 import javax.swing.UIManager;
 import javax.swing.text.BadLocationException;
@@ -30,4 +29,5 @@
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.tools.Destroyable;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -254,5 +254,5 @@
      */
     public static Color getHintTextColor() {
-        Color color = UIManager.getColor("TextField[Disabled].textForeground"); // Nimbus?
+        var color = UIManager.getColor("TextField[Disabled].textForeground"); // Nimbus?
         if (color == null)
             color = UIManager.getColor("TextField.inactiveForeground");
@@ -290,6 +290,7 @@
         int x;
         try {
-            x = modelToView(0).x;
+            x = (int) Math.round(modelToView2D(0).getX());
         } catch (BadLocationException exc) {
+            Logging.trace(exc);
             return; // can't happen
         }
@@ -304,5 +305,5 @@
             g.drawString(getHint(), x, getBaseline(getWidth(), getHeight()));
         } else {
-            FontMetrics metrics = g.getFontMetrics(g.getFont());
+            final var metrics = g.getFontMetrics(g.getFont());
             int dx = metrics.stringWidth(getHint());
             g.drawString(getHint(), x - dx, getBaseline(getWidth(), getHeight()));
Index: trunk/src/org/openstreetmap/josm/io/NoteReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NoteReader.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/io/NoteReader.java	(revision 19048)
@@ -52,5 +52,5 @@
      * Reads both API style and planet dump style formats.
      */
-    private class Parser extends DefaultHandler {
+    private final class Parser extends DefaultHandler {
 
         private NoteParseMode parseMode;
@@ -73,5 +73,5 @@
         public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
             buffer.setLength(0);
-            switch(qName) {
+            switch (qName) {
             case "osm":
                 parseMode = NoteParseMode.API;
@@ -92,5 +92,5 @@
 
             //The rest only applies for dump mode
-            switch(qName) {
+            switch (qName) {
             case "note":
                 thisNote = parseNoteFull(attrs);
@@ -113,7 +113,9 @@
             }
             if ("comment".equals(qName)) {
-                User commentUser = User.createOsmUser(commentUid, commentUsername);
+                final User commentUser;
                 if (commentUid == 0) {
                     commentUser = User.getAnonymous();
+                } else {
+                    commentUser = User.createOsmUser(commentUid, commentUsername);
                 }
                 if (parseMode == NoteParseMode.API) {
@@ -177,6 +179,6 @@
 
     static LatLon parseLatLon(UnaryOperator<String> attrs) {
-        double lat = Double.parseDouble(attrs.apply("lat"));
-        double lon = Double.parseDouble(attrs.apply("lon"));
+        final var lat = Double.parseDouble(attrs.apply("lat"));
+        final var lon = Double.parseDouble(attrs.apply("lon"));
         return new LatLon(lat, lon);
     }
@@ -195,5 +197,5 @@
 
     static Note parseNoteFull(UnaryOperator<String> attrs) {
-        Note note = parseNoteBasic(attrs);
+        final var note = parseNoteBasic(attrs);
         String id = attrs.apply("id");
         if (id != null) {
Index: trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java	(revision 19048)
@@ -16,5 +16,5 @@
 import java.util.Set;
 
-import org.apache.commons.compress.utils.CountingInputStream;
+import org.apache.commons.io.input.BoundedInputStream;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.DataSource;
@@ -88,12 +88,12 @@
 
     private void parse(InputStream source) throws IllegalDataException, IOException {
-        final CountingInputStream inputStream;
+        final BoundedInputStream inputStream;
         if (source.markSupported()) {
-            inputStream = new CountingInputStream(source);
+            inputStream = new BoundedInputStream(source);
         } else {
-            inputStream = new CountingInputStream(new BufferedInputStream(source));
-        }
-        try (ProtobufParser parser = new ProtobufParser(inputStream)) {
-            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            inputStream = new BoundedInputStream(new BufferedInputStream(source));
+        }
+        try (var parser = new ProtobufParser(inputStream)) {
+            final var baos = new ByteArrayOutputStream();
             HeaderBlock headerBlock = null;
             BlobHeader blobHeader = null;
@@ -106,5 +106,5 @@
                     }
                     // OSM PBF is fun -- it has *nested* pbf data
-                    Blob blob = parseBlob(blobHeader, inputStream, parser, baos);
+                    final var blob = parseBlob(blobHeader, inputStream, parser, baos);
                     headerBlock = parseHeaderBlock(blob, baos);
                     checkRequiredFeatures(headerBlock);
@@ -114,5 +114,5 @@
                         throw new IllegalStateException("A header block must occur before the first data block");
                     }
-                    Blob blob = parseBlob(blobHeader, inputStream, parser, baos);
+                    final var blob = parseBlob(blobHeader, inputStream, parser, baos);
                     parseDataBlock(baos, headerBlock, blob);
                     blobHeader = null;
@@ -133,13 +133,13 @@
      */
     @Nonnull
-    private static BlobHeader parseBlobHeader(CountingInputStream cis, ByteArrayOutputStream baos, ProtobufParser parser)
+    private static BlobHeader parseBlobHeader(BoundedInputStream cis, ByteArrayOutputStream baos, ProtobufParser parser)
             throws IOException, IllegalDataException {
         String type = null;
         byte[] indexData = null;
         int datasize = Integer.MIN_VALUE;
-        int length = 0;
-        long start = cis.getBytesRead();
-        while (parser.hasNext() && (length == 0 || cis.getBytesRead() - start < length)) {
-            final ProtobufRecord current = new ProtobufRecord(baos, parser);
+        var length = 0;
+        long start = cis.getCount();
+        while (parser.hasNext() && (length == 0 || cis.getCount() - start < length)) {
+            final var current = new ProtobufRecord(baos, parser);
             switch (current.getField()) {
                 case 1:
@@ -153,5 +153,5 @@
                     break;
                 default:
-                    start = cis.getBytesRead();
+                    start = cis.getCount();
                     length += current.asUnsignedVarInt().intValue();
                     if (length > MAX_BLOBHEADER_SIZE) { // There is a hard limit of 64 KiB for the BlobHeader. It *should* be less than 32 KiB.
@@ -181,7 +181,7 @@
      */
     @Nonnull
-    private static Blob parseBlob(BlobHeader header, CountingInputStream cis, ProtobufParser parser, ByteArrayOutputStream baos)
+    private static Blob parseBlob(BlobHeader header, BoundedInputStream cis, ProtobufParser parser, ByteArrayOutputStream baos)
             throws IOException {
-        long start = cis.getBytesRead();
+        long start = cis.getCount();
         int size = Integer.MIN_VALUE;
         Blob.CompressionType type = null;
@@ -189,5 +189,5 @@
         // Needed since size and compression type + compression data may be in a different order
         byte[] bytes = null;
-        while (parser.hasNext() && cis.getBytesRead() - start < header.dataSize()) {
+        while (parser.hasNext() && cis.getCount() - start < header.dataSize()) {
             current = new ProtobufRecord(baos, parser);
             switch (current.getField()) {
@@ -239,9 +239,9 @@
     @Nonnull
     private static HeaderBlock parseHeaderBlock(Blob blob, ByteArrayOutputStream baos) throws IOException {
-        try (InputStream blobInput = blob.inputStream();
-             ProtobufParser parser = new ProtobufParser(blobInput)) {
+        try (var blobInput = blob.inputStream();
+             var parser = new ProtobufParser(blobInput)) {
             BBox bbox = null;
-            List<String> required = new ArrayList<>();
-            List<String> optional = new ArrayList<>();
+            final var required = new ArrayList<String>();
+            final var optional = new ArrayList<String>();
             String program = null;
             String source = null;
@@ -250,5 +250,5 @@
             String osmosisReplicationBaseUrl = null;
             while (parser.hasNext()) {
-                final ProtobufRecord current = new ProtobufRecord(baos, parser);
+                final var current = new ProtobufRecord(baos, parser);
                 switch (current.getField()) {
                     case 1: // bbox
@@ -311,13 +311,13 @@
         String[] stringTable = null; // field 1, note that stringTable[0] is a delimiter, so it is always blank and unused
         // field 2 -- we cannot parse these live just in case the following fields come later
-        List<ProtobufRecord> primitiveGroups = new ArrayList<>();
-        int granularity = 100; // field 17
+        final var primitiveGroups = new ArrayList<ProtobufRecord>();
+        var granularity = 100; // field 17
         long latOffset = 0; // field 19
         long lonOffset = 0; // field 20
-        int dateGranularity = 1000; // field 18, default is milliseconds since the 1970 epoch
-        try (InputStream inputStream = blob.inputStream();
-             ProtobufParser parser = new ProtobufParser(inputStream)) {
+        var dateGranularity = 1000; // field 18, default is milliseconds since the 1970 epoch
+        try (var inputStream = blob.inputStream();
+             var parser = new ProtobufParser(inputStream)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -343,7 +343,7 @@
             }
         }
-        final PrimitiveBlockRecord primitiveBlockRecord = new PrimitiveBlockRecord(stringTable, granularity, latOffset, lonOffset,
+        final var primitiveBlockRecord = new PrimitiveBlockRecord(stringTable, granularity, latOffset, lonOffset,
                 dateGranularity);
-        final DataSet ds = getDataSet();
+        final var ds = getDataSet();
         if (!primitiveGroups.isEmpty() && headerBlock.bbox() != null) {
             try {
@@ -375,6 +375,6 @@
     @Nullable
     private static BBox parseBBox(ByteArrayOutputStream baos, ProtobufRecord current) throws IOException {
-        try (ByteArrayInputStream bboxInputStream = new ByteArrayInputStream(current.getBytes());
-             ProtobufParser bboxParser = new ProtobufParser(bboxInputStream)) {
+        try (var bboxInputStream = new ByteArrayInputStream(current.getBytes());
+             var bboxParser = new ProtobufParser(bboxInputStream)) {
             double left = Double.NaN;
             double right = Double.NaN;
@@ -382,5 +382,5 @@
             double bottom = Double.NaN;
             while (bboxParser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, bboxParser);
+                final var protobufRecord = new ProtobufRecord(baos, bboxParser);
                 if (protobufRecord.getType() == WireType.VARINT) {
                     double value = protobufRecord.asSignedVarInt().longValue() * NANO_DEGREES;
@@ -419,9 +419,9 @@
     @Nonnull
     private static String[] parseStringTable(ByteArrayOutputStream baos, byte[] bytes) throws IOException {
-        try (ByteArrayInputStream is = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(is)) {
-            List<String> list = new ArrayList<>();
+        try (var is = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(is)) {
+            final var list = new ArrayList<String>();
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 if (protobufRecord.getField() == 1) {
                     list.add(protobufRecord.asString().intern()); // field is technically repeated bytes
@@ -444,8 +444,8 @@
     private void parsePrimitiveGroup(ByteArrayOutputStream baos, byte[] bytes, PrimitiveBlockRecord primitiveBlockRecord)
             throws IllegalDataException, IOException {
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1: // Nodes, repeated
@@ -480,14 +480,14 @@
     private void parseNode(ByteArrayOutputStream baos, byte[] bytes, PrimitiveBlockRecord primitiveBlockRecord)
             throws IllegalDataException, IOException {
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             long id = Long.MIN_VALUE;
-            List<String> keys = new ArrayList<>();
-            List<String> values = new ArrayList<>();
+            final var keys = new ArrayList<String>();
+            final var values = new ArrayList<String>();
             Info info = null;
             long lat = Long.MIN_VALUE;
             long lon = Long.MIN_VALUE;
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -519,5 +519,5 @@
                 throw new IllegalDataException("OSM PBF did not provide all the required node information");
             }
-            NodeData node = new NodeData(id);
+            final var node = new NodeData(id);
             node.setCoor(calculateLatLon(primitiveBlockRecord, lat, lon));
             addTags(node, keys, values);
@@ -547,8 +547,8 @@
         long[] keyVals = EMPTY_LONG; // technically can be int
         Info[] denseInfo = null;
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1: // packed node ids, DELTA encoded
@@ -576,15 +576,15 @@
         }
 
-        int keyValIndex = 0; // This index must not reset between nodes, and must always increment
+        var keyValIndex = 0; // This index must not reset between nodes, and must always increment
         if (ids.length == lats.length && lats.length == lons.length && (denseInfo == null || denseInfo.length == lons.length)) {
             long id = 0;
             long lat = 0;
             long lon = 0;
-            for (int i = 0; i < ids.length; i++) {
+            for (var i = 0; i < ids.length; i++) {
                 final NodeData node;
                 id += ids[i];
                 node = new NodeData(id);
                 if (denseInfo != null) {
-                    Info info = denseInfo[i];
+                    final var info = denseInfo[i];
                     setOsmPrimitiveData(primitiveBlockRecord, node, info);
                 } else {
@@ -638,8 +638,8 @@
         // We don't do live drawing, so we don't care about lats and lons (we essentially throw them away with the current parser)
         // This is for the optional feature "LocationsOnWays"
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -672,6 +672,6 @@
             throw new IllegalDataException("A way with either no id or no nodes was found");
         }
-        WayData wayData = new WayData(id);
-        List<Long> nodeIds = new ArrayList<>(refs.length);
+        final var wayData = new WayData(id);
+        final var nodeIds = new ArrayList<Long>(refs.length);
         long ref = 0;
         for (long tRef : refs) {
@@ -701,14 +701,14 @@
             throws IllegalDataException, IOException {
         long id = Long.MIN_VALUE;
-        List<String> keys = new ArrayList<>();
-        List<String> values = new ArrayList<>();
+        final var keys = new ArrayList<String>();
+        final var values = new ArrayList<String>();
         Info info = null;
         long[] rolesStringId = EMPTY_LONG; // Technically int
         long[] memids = EMPTY_LONG;
         long[] types = EMPTY_LONG; // Technically an enum
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -747,5 +747,5 @@
             throw new IllegalDataException("OSM PBF contains a bad relation definition");
         }
-        RelationData data = new RelationData(id);
+        final var data = new RelationData(id);
         if (info != null) {
             setOsmPrimitiveData(primitiveBlockRecord, data, info);
@@ -757,5 +757,5 @@
         List<RelationMemberData> members = new ArrayList<>(rolesStringId.length);
         long memberId = 0;
-        for (int i = 0; i < rolesStringId.length; i++) {
+        for (var i = 0; i < rolesStringId.length; i++) {
             String role = primitiveBlockRecord.stringTable[(int) rolesStringId[i]];
             memberId += memids[i];
@@ -777,6 +777,6 @@
     @Nonnull
     private static Info parseInfo(ByteArrayOutputStream baos, byte[] bytes) throws IOException {
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             int version = -1;
             Long timestamp = null;
@@ -784,7 +784,7 @@
             Integer uid = null;
             Integer userSid = null;
-            boolean visible = true;
+            var visible = true;
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -839,5 +839,5 @@
         }
         Map<String, String> tagMap = new HashMap<>(keys.size());
-        for (int i = 0; i < keys.size(); i++) {
+        for (var i = 0; i < keys.size(); i++) {
             tagMap.put(keys.get(i), values.get(i));
         }
@@ -879,5 +879,5 @@
     @Nonnull
     private static long[] decodePackedSInt64(long[] numbers) {
-        for (int i = 0; i < numbers.length; i++) {
+        for (var i = 0; i < numbers.length; i++) {
             numbers[i] = ProtobufParser.decodeZigZag(numbers[i]);
         }
@@ -922,8 +922,8 @@
         long[] userSid = EMPTY_LONG; // technically int
         long[] visible = EMPTY_LONG; // optional, true if not set, technically booleans
-        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-             ProtobufParser parser = new ProtobufParser(bais)) {
+        try (var bais = new ByteArrayInputStream(bytes);
+             var parser = new ProtobufParser(bais)) {
             while (parser.hasNext()) {
-                ProtobufRecord protobufRecord = new ProtobufRecord(baos, parser);
+                final var protobufRecord = new ProtobufRecord(baos, parser);
                 switch (protobufRecord.getField()) {
                     case 1:
@@ -956,10 +956,10 @@
         }
         if (version.length > 0) {
-            Info[] infos = new Info[version.length];
+            final var infos = new Info[version.length];
             long lastTimestamp = 0; // delta encoded
             long lastChangeset = 0; // delta encoded
             long lastUid = 0; // delta encoded,
             long lastUserSid = 0; // delta encoded, string id for username
-            for (int i = 0; i < version.length; i++) {
+            for (var i = 0; i < version.length; i++) {
                 if (timestamp.length > i)
                     lastTimestamp += timestamp[i];
Index: trunk/src/org/openstreetmap/josm/tools/ImageResizeMode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageResizeMode.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/tools/ImageResizeMode.java	(revision 19048)
@@ -87,6 +87,6 @@
      */
     BufferedImage createBufferedImage(Dimension dim, Dimension icon, Consumer<Graphics2D> renderer, Image sourceIcon) {
-        final Dimension real = computeDimension(dim, icon);
-        final BufferedImage bufferedImage = new BufferedImage(real.width, real.height, BufferedImage.TYPE_INT_ARGB);
+        final var real = computeDimension(dim, icon);
+        final var bufferedImage = new BufferedImage(real.width, real.height, BufferedImage.TYPE_INT_ARGB);
         final Graphics2D g = bufferedImage.createGraphics();
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -119,4 +119,5 @@
      * @return a cache key
      */
+    @SuppressWarnings("EnumOrdinal")
     int cacheKey(Dimension dim) {
         return (ordinal() << 28) | ((dim.width & 0xfff) << 16) | (dim.height & 0xfff);
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 19047)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 19048)
@@ -30,5 +30,4 @@
 import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -153,6 +152,6 @@
      */
     public static <T> int indexOf(Iterable<? extends T> collection, Predicate<? super T> predicate) {
-        int i = 0;
-        for (T item : collection) {
+        var i = 0;
+        for (var item : collection) {
             if (predicate.test(item))
                 return i;
@@ -186,5 +185,5 @@
         if (n <= 0)
             throw new IllegalArgumentException("n must be <= 0 but is " + n);
-        int res = a % n;
+        var res = a % n;
         if (res < 0) {
             res += n;
@@ -304,8 +303,8 @@
             Logging.warn("Unable to create directory "+out.getPath());
         }
-        File[] files = in.listFiles();
+        var files = in.listFiles();
         if (files != null) {
-            for (File f : files) {
-                File target = new File(out, f.getName());
+            for (var f : files) {
+                var target = new File(out, f.getName());
                 if (f.isDirectory()) {
                     copyDirectory(f, target);
@@ -325,7 +324,7 @@
     public static boolean deleteDirectory(File path) {
         if (path.exists()) {
-            File[] files = path.listFiles();
+            var files = path.listFiles();
             if (files != null) {
-                for (File file : files) {
+                for (var file : files) {
                     if (file.isDirectory()) {
                         deleteDirectory(file);
@@ -372,5 +371,5 @@
      */
     public static boolean deleteFile(File file, String warnMsg) {
-        boolean result = file.delete();
+        var result = file.delete();
         if (!result) {
             Logging.warn(tr(warnMsg, file.getPath()));
@@ -398,5 +397,5 @@
      */
     public static boolean mkDirs(File dir, String warnMsg) {
-        boolean result = dir.mkdirs();
+        var result = dir.mkdirs();
         if (!result) {
             Logging.warn(tr(warnMsg, dir.getPath()));
@@ -498,6 +497,6 @@
             throw new JosmRuntimeException(e);
         }
-        byte[] byteData = data.getBytes(StandardCharsets.UTF_8);
-        byte[] byteDigest = md.digest(byteData);
+        var byteData = data.getBytes(StandardCharsets.UTF_8);
+        var byteDigest = md.digest(byteData);
         return toHexString(byteDigest);
     }
@@ -518,11 +517,11 @@
         }
 
-        final int len = bytes.length;
+        final var len = bytes.length;
         if (len == 0) {
             return "";
         }
 
-        char[] hexChars = new char[len * 2];
-        int j = 0;
+        var hexChars = new char[len * 2];
+        var j = 0;
         for (final int v : bytes) {
             hexChars[j++] = HEX_ARRAY[(v & 0xf0) >> 4];
@@ -542,8 +541,8 @@
      */
     public static <T> List<T> topologicalSort(final MultiMap<T, T> dependencies) {
-        MultiMap<T, T> deps = new MultiMap<>();
-        for (T key : dependencies.keySet()) {
+        var deps = new MultiMap<T, T>();
+        for (var key : dependencies.keySet()) {
             deps.putVoid(key);
-            for (T val : dependencies.get(key)) {
+            for (var val : dependencies.get(key)) {
                 deps.putVoid(val);
                 deps.put(key, val);
@@ -551,8 +550,8 @@
         }
 
-        int size = deps.size();
+        var size = deps.size();
         List<T> sorted = new ArrayList<>();
-        for (int i = 0; i < size; ++i) {
-            T parentless = deps.keySet().stream()
+        for (var i = 0; i < size; ++i) {
+            var parentless = deps.keySet().stream()
                     .filter(key -> deps.get(key).isEmpty())
                     .findFirst().orElse(null);
@@ -560,5 +559,5 @@
             sorted.add(parentless);
             deps.remove(parentless);
-            for (T key : deps.keySet()) {
+            for (var key : deps.keySet()) {
                 deps.remove(key, parentless);
             }
@@ -680,5 +679,5 @@
             return Collections.emptyMap();
         } else if (map.size() == 1) {
-            final Map.Entry<K, V> entry = map.entrySet().iterator().next();
+            final var entry = map.entrySet().iterator().next();
             return Collections.singletonMap(entry.getKey(), entry.getValue());
         } else if (mapOfEntries != null) {
@@ -796,7 +795,7 @@
         }
 
-        int start = 0;
-        int end = str.length();
-        boolean leadingSkipChar = true;
+        var start = 0;
+        var end = str.length();
+        var leadingSkipChar = true;
         while (leadingSkipChar && start < end) {
             leadingSkipChar = isStrippedChar(str.charAt(start), skipChars);
@@ -805,5 +804,5 @@
             }
         }
-        boolean trailingSkipChar = true;
+        var trailingSkipChar = true;
         while (trailingSkipChar && end > start) {
             trailingSkipChar = isStrippedChar(str.charAt(end - 1), skipChars);
@@ -867,7 +866,7 @@
             Logging.debug(String.join(" ", command));
         }
-        Path out = Files.createTempFile("josm_exec_" + command.get(0) + "_", ".txt");
+        var out = Files.createTempFile("josm_exec_" + command.get(0) + "_", ".txt");
         try {
-            Process p = new ProcessBuilder(command).redirectErrorStream(true).redirectOutput(out.toFile()).start();
+            var p = new ProcessBuilder(command).redirectErrorStream(true).redirectOutput(out.toFile()).start();
             if (!p.waitFor(timeout, unit) || p.exitValue() != 0) {
                 throw new ExecutionException(command.toString(), null);
@@ -889,9 +888,9 @@
      */
     public static File getJosmTempDir() {
-        String tmpDir = getSystemProperty("java.io.tmpdir");
+        var tmpDir = getSystemProperty("java.io.tmpdir");
         if (tmpDir == null) {
             return null;
         }
-        File josmTmpDir = new File(tmpDir, "JOSM");
+        final var josmTmpDir = new File(tmpDir, "JOSM");
         if (!josmTmpDir.exists() && !josmTmpDir.mkdirs()) {
             Logging.warn("Unable to create temp directory " + josmTmpDir);
@@ -921,13 +920,13 @@
         // Is it less than 1 hour ?
         if (elapsedTime < MILLIS_OF_HOUR) {
-            final long min = elapsedTime / MILLIS_OF_MINUTE;
+            final var min = elapsedTime / MILLIS_OF_MINUTE;
             return String.format("%d %s %d %s", min, tr("min"), (elapsedTime - min * MILLIS_OF_MINUTE) / MILLIS_OF_SECOND, tr("s"));
         }
         // Is it less than 1 day ?
         if (elapsedTime < MILLIS_OF_DAY) {
-            final long hour = elapsedTime / MILLIS_OF_HOUR;
+            final var hour = elapsedTime / MILLIS_OF_HOUR;
             return String.format("%d %s %d %s", hour, tr("h"), (elapsedTime - hour * MILLIS_OF_HOUR) / MILLIS_OF_MINUTE, tr("min"));
         }
-        long days = elapsedTime / MILLIS_OF_DAY;
+        var days = elapsedTime / MILLIS_OF_DAY;
         return String.format("%d %s %d %s", days, trn("day", "days", days), (elapsedTime - days * MILLIS_OF_DAY) / MILLIS_OF_HOUR, tr("h"));
     }
@@ -944,5 +943,5 @@
             throw new IllegalArgumentException("bytes must be >= 0");
         }
-        int unitIndex = 0;
+        var unitIndex = 0;
         double value = bytes;
         while (value >= 1024 && unitIndex < SIZE_UNITS.length) {
@@ -968,9 +967,9 @@
     public static String getPositionListString(List<Integer> positionList) {
         Collections.sort(positionList);
-        final StringBuilder sb = new StringBuilder(32);
+        final var sb = new StringBuilder(32);
         sb.append(positionList.get(0));
-        int cnt = 0;
+        var cnt = 0;
         int last = positionList.get(0);
-        for (int i = 1; i < positionList.size(); ++i) {
+        for (var i = 1; i < positionList.size(); ++i) {
             int cur = positionList.get(i);
             if (cur == last + 1) {
@@ -1031,7 +1030,7 @@
      */
     public static Throwable getRootCause(Throwable t) {
-        Throwable result = t;
+        var result = t;
         if (result != null) {
-            Throwable cause = result.getCause();
+            var cause = result.getCause();
             while (cause != null && !cause.equals(result)) {
                 result = cause;
@@ -1051,5 +1050,5 @@
      */
     public static <T> T[] addInArrayCopy(T[] array, T item) {
-        T[] biggerCopy = Arrays.copyOf(array, array.length + 1);
+        var biggerCopy = Arrays.copyOf(array, array.length + 1);
         biggerCopy[array.length] = item;
         return biggerCopy;
@@ -1064,5 +1063,5 @@
      */
     public static String shortenString(String s, int maxLength) {
-        final String ellipses = "...";
+        final var ellipses = "...";
         CheckParameterUtil.ensureThat(maxLength >= ellipses.length(), "maxLength is shorter than " + ellipses.length());
         if (s != null && s.length() > maxLength) {
@@ -1102,5 +1101,5 @@
             if (elements.size() > maxElements) {
                 final Collection<T> r = new ArrayList<>(maxElements);
-                final Iterator<T> it = elements.iterator();
+                final var it = elements.iterator();
                 while (r.size() < maxElements - 1) {
                     r.add(it.next());
@@ -1127,10 +1126,10 @@
             return url;
 
-        String query = url.substring(url.indexOf('?') + 1);
-
-        StringBuilder sb = new StringBuilder(url.substring(0, url.indexOf('?') + 1));
-
-        for (int i = 0; i < query.length(); i++) {
-            String c = query.substring(i, i + 1);
+        final var query = url.substring(url.indexOf('?') + 1);
+
+        final var sb = new StringBuilder(url.substring(0, url.indexOf('?') + 1));
+
+        for (var i = 0; i < query.length(); i++) {
+            final var c = query.substring(i, i + 1);
             if (URL_CHARS.contains(c)) {
                 sb.append(c);
@@ -1153,5 +1152,5 @@
      */
     public static String encodeUrl(String s) {
-        final String enc = StandardCharsets.UTF_8.name();
+        final var enc = StandardCharsets.UTF_8.name();
         try {
             return URLEncoder.encode(s, enc);
@@ -1173,5 +1172,5 @@
      */
     public static String decodeUrl(String s) {
-        final String enc = StandardCharsets.UTF_8.name();
+        final var enc = StandardCharsets.UTF_8.name();
         try {
             return URLDecoder.decode(s, enc);
@@ -1221,5 +1220,5 @@
             @Override
             public Thread newThread(final Runnable runnable) {
-                final Thread thread = new Thread(runnable, String.format(Locale.ENGLISH, nameFormat, count.getAndIncrement()));
+                final var thread = new Thread(runnable, String.format(Locale.ENGLISH, nameFormat, count.getAndIncrement()));
                 thread.setPriority(threadPriority);
                 return thread;
@@ -1299,5 +1298,5 @@
     public static boolean isSimilar(String string1, String string2) {
         // check plain strings
-        int distance = getLevenshteinDistance(string1, string2);
+        var distance = getLevenshteinDistance(string1, string2);
 
         // check if only the case differs, so we don't consider large distance as different strings
@@ -1340,5 +1339,5 @@
         }
 
-        for (double length : values) {
+        for (var length : values) {
             standardDeviation += Math.pow(length - mean, 2);
         }
@@ -1361,7 +1360,7 @@
         }
         List<int[]> groups = new ArrayList<>();
-        int[] current = {Integer.MIN_VALUE, Integer.MIN_VALUE};
+        var current = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
         groups.add(current);
-        for (int row : integers) {
+        for (var row : integers) {
             if (current[0] == Integer.MIN_VALUE) {
                 current[0] = row;
@@ -1398,5 +1397,5 @@
     @SuppressWarnings("ThreadPriorityCheck")
     public static ForkJoinPool newForkJoinPool(String pref, final String nameFormat, final int threadPriority) {
-        int noThreads = Config.getPref().getInt(pref, Runtime.getRuntime().availableProcessors());
+        final var noThreads = Config.getPref().getInt(pref, Runtime.getRuntime().availableProcessors());
         return new ForkJoinPool(noThreads, new ForkJoinPool.ForkJoinWorkerThreadFactory() {
             final AtomicLong count = new AtomicLong(0);
@@ -1468,5 +1467,5 @@
         if (value != null) {
             try {
-                String old = System.setProperty(key, value);
+                var old = System.setProperty(key, value);
                 if (Logging.isDebugEnabled() && !value.equals(old)) {
                     if (!key.toLowerCase(Locale.ENGLISH).contains("password")) {
@@ -1494,5 +1493,5 @@
      */
     public static boolean hasExtension(String filename, String... extensions) {
-        String name = filename.toLowerCase(Locale.ENGLISH).replace("?format=raw", "");
+        var name = filename.toLowerCase(Locale.ENGLISH).replace("?format=raw", "");
         return Arrays.stream(extensions)
                 .anyMatch(ext -> name.endsWith('.' + ext.toLowerCase(Locale.ENGLISH)));
@@ -1523,9 +1522,9 @@
             return new byte[0];
         }
-        try (ByteArrayOutputStream bout = new ByteArrayOutputStream(stream.available())) {
-            byte[] buffer = new byte[8192];
-            boolean finished = false;
+        try (stream; var bout = new ByteArrayOutputStream(stream.available())) {
+            final var buffer = new byte[8192];
+            var finished = false;
             do {
-                int read = stream.read(buffer);
+                var read = stream.read(buffer);
                 if (read >= 0) {
                     bout.write(buffer, 0, read);
@@ -1537,6 +1536,4 @@
                 return new byte[0];
             return bout.toByteArray();
-        } finally {
-            stream.close();
         }
     }
@@ -1603,17 +1600,17 @@
      */
     public static List<GlyphVector> getGlyphVectorsBidi(String string, Font font, FontRenderContext frc) {
-        List<GlyphVector> gvs = new ArrayList<>();
-        Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
-        byte[] levels = new byte[bidi.getRunCount()];
-        DirectionString[] dirStrings = new DirectionString[levels.length];
-        for (int i = 0; i < levels.length; ++i) {
+        final var gvs = new ArrayList<GlyphVector>();
+        final var bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        final var levels = new byte[bidi.getRunCount()];
+        final var dirStrings = new DirectionString[levels.length];
+        for (var i = 0; i < levels.length; ++i) {
             levels[i] = (byte) bidi.getRunLevel(i);
-            String substr = string.substring(bidi.getRunStart(i), bidi.getRunLimit(i));
-            int dir = levels[i] % 2 == 0 ? Bidi.DIRECTION_LEFT_TO_RIGHT : Bidi.DIRECTION_RIGHT_TO_LEFT;
+            final var substr = string.substring(bidi.getRunStart(i), bidi.getRunLimit(i));
+            final var dir = levels[i] % 2 == 0 ? Bidi.DIRECTION_LEFT_TO_RIGHT : Bidi.DIRECTION_RIGHT_TO_LEFT;
             dirStrings[i] = new DirectionString(dir, substr);
         }
         Bidi.reorderVisually(levels, 0, dirStrings, 0, levels.length);
-        for (DirectionString dirString : dirStrings) {
-            char[] chars = dirString.str.toCharArray();
+        for (var dirString : dirStrings) {
+            var chars = dirString.str.toCharArray();
             gvs.add(font.layoutGlyphVector(frc, chars, 0, chars.length, dirString.direction));
         }
@@ -1712,5 +1709,5 @@
     public static int getJavaVersion() {
         // Switch to Runtime.version() once we move past Java 8
-        String version = Objects.requireNonNull(getSystemProperty("java.version"));
+        var version = Objects.requireNonNull(getSystemProperty("java.version"));
         if (version.startsWith("1.")) {
             version = version.substring(2);
@@ -1721,6 +1718,6 @@
         // 9
         // 9.0.1
-        int dotPos = version.indexOf('.');
-        int dashPos = version.indexOf('-');
+        var dotPos = version.indexOf('.');
+        var dashPos = version.indexOf('-');
         return Integer.parseInt(version.substring(0,
                 dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : version.length()));
@@ -1734,5 +1731,5 @@
     public static int getJavaUpdate() {
         // Switch to Runtime.version() once we move past Java 8
-        String version = Objects.requireNonNull(getSystemProperty("java.version"));
+        var version = Objects.requireNonNull(getSystemProperty("java.version"));
         if (version.startsWith("1.")) {
             version = version.substring(2);
@@ -1745,12 +1742,12 @@
         // 17.0.4.1+1-LTS
         // $MAJOR.$MINOR.$SECURITY.$PATCH
-        int undePos = version.indexOf('_');
-        int dashPos = version.indexOf('-');
+        var undePos = version.indexOf('_');
+        var dashPos = version.indexOf('-');
         if (undePos > -1) {
             return Integer.parseInt(version.substring(undePos + 1,
                     dashPos > -1 ? dashPos : version.length()));
         }
-        int firstDotPos = version.indexOf('.');
-        int secondDotPos = version.indexOf('.', firstDotPos + 1);
+        var firstDotPos = version.indexOf('.');
+        var secondDotPos = version.indexOf('.', firstDotPos + 1);
         if (firstDotPos == secondDotPos) {
             return 0;
@@ -1767,7 +1764,7 @@
     public static int getJavaBuild() {
         // 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('+');
+        var version = Objects.requireNonNull(getSystemProperty("java.runtime.version"));
+        var bPos = version.indexOf('b');
+        var pPos = version.indexOf('+');
         try {
             return Integer.parseInt(version.substring(bPos > -1 ? bPos + 1 : pPos + 1));
@@ -1786,5 +1783,5 @@
         try {
             Object value;
-            Class<?> c = Class.forName("com.sun.deploy.config.BuiltInProperties");
+            var c = Class.forName("com.sun.deploy.config.BuiltInProperties");
             try {
                 value = c.getDeclaredField("JRE_EXPIRATION_DATE").get(null);
@@ -1810,5 +1807,5 @@
     public static String getJavaLatestVersion() {
         try {
-            String[] versions = HttpClient.create(
+            var versions = HttpClient.create(
                     new URL(Config.getPref().get(
                             "java.baseline.version.url",
@@ -1816,5 +1813,5 @@
                     .connect().fetchContent().split("\n", -1);
             if (getJavaVersion() <= 11 && isRunningWebStart()) { // OpenWebStart currently only has Java 11
-                for (String version : versions) {
+                for (var version : versions) {
                     if (version.startsWith("11")) {
                         return version;
@@ -1822,5 +1819,5 @@
                 }
             } else if (getJavaVersion() <= 17) {
-                for (String version : versions) {
+                for (var version : versions) {
                     if (version.startsWith("17")) { // Use current Java LTS
                         return version;
@@ -1945,5 +1942,5 @@
                     return url.openStream();
                 } catch (FileNotFoundException | InvalidPathException e) {
-                    URL betterUrl = betterJarUrl(url);
+                    final var betterUrl = betterJarUrl(url);
                     if (betterUrl != null) {
                         try {
@@ -1982,13 +1979,13 @@
     public static URL betterJarUrl(URL jarUrl, URL defaultUrl) throws IOException {
         // Workaround to https://bugs.openjdk.java.net/browse/JDK-4523159
-        String urlPath = jarUrl.getPath().replace("%20", " ");
+        var urlPath = jarUrl.getPath().replace("%20", " ");
         if (urlPath.startsWith("file:/") && urlPath.split("!", -1).length > 2) {
             // Locate jar file
-            int index = urlPath.lastIndexOf("!/");
-            Path jarFile = Paths.get(urlPath.substring("file:/".length(), index));
-            Path filename = jarFile.getFileName();
-            FileTime jarTime = Files.readAttributes(jarFile, BasicFileAttributes.class).lastModifiedTime();
+            var index = urlPath.lastIndexOf("!/");
+            final var jarFile = Paths.get(urlPath.substring("file:/".length(), index));
+            var filename = jarFile.getFileName();
+            var jarTime = Files.readAttributes(jarFile, BasicFileAttributes.class).lastModifiedTime();
             // Copy it to temp directory (hopefully free of exclamation mark) if needed (missing or older jar)
-            Path jarCopy = Paths.get(getSystemProperty("java.io.tmpdir")).resolve(filename);
+            final var jarCopy = Paths.get(getSystemProperty("java.io.tmpdir")).resolve(filename);
             if (!jarCopy.toFile().exists() ||
                     Files.readAttributes(jarCopy, BasicFileAttributes.class).lastModifiedTime().compareTo(jarTime) < 0) {
@@ -2029,5 +2026,5 @@
             Logging.trace(e);
             try {
-                URL betterUrl = betterJarUrl(cl.getResource(path));
+                final var betterUrl = betterJarUrl(cl.getResource(path));
                 if (betterUrl != null) {
                     return betterUrl.openStream();
Index: trunk/tools/eclipse/JOSM (Java 8).launch
===================================================================
--- trunk/tools/eclipse/JOSM (Java 8).launch	(revision 19047)
+++ 	(revision )
@@ -1,18 +1,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
-    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-        <listEntry value="/JOSM/src/org/openstreetmap/josm/gui/MainApplication.java"/>
-    </listAttribute>
-    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-        <listEntry value="1"/>
-    </listAttribute>
-    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
-    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
-    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
-    <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
-    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.openstreetmap.josm.gui.MainApplication"/>
-    <stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="JOSM"/>
-    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--trace"/>
-    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="JOSM"/>
-    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Xverify:none"/>
-</launchConfiguration>
Index: trunk/tools/ivy.xml
===================================================================
--- trunk/tools/ivy.xml	(revision 19047)
+++ trunk/tools/ivy.xml	(revision 19048)
@@ -17,8 +17,9 @@
         <dependency org="net.java.dev.javacc" name="javacc" rev="7.0.13" conf="javacc->default"/>
         <!-- checkstyle->default -->
-        <dependency org="com.puppycrawl.tools" name="checkstyle" rev="9.3" conf="checkstyle->default"/>
+        <dependency org="com.puppycrawl.tools" name="checkstyle" rev="10.15.0" conf="checkstyle->default"/>
         <!-- proguard->default -->
         <dependency org="com.guardsquare" name="proguard-ant" rev="7.4.2" conf="proguard->default"/>
         <!-- pmd->default -->
+        <!-- PMD 7.0.0 has too many false positives right now. When updating, don't forget to add pmd-ant as a new dependency -->
         <dependency org="net.sourceforge.pmd" name="pmd-core" rev="6.55.0" conf="pmd->default"/>
         <dependency org="net.sourceforge.pmd" name="pmd-java" rev="6.55.0" conf="pmd->default"/>
@@ -28,10 +29,8 @@
         </dependency>
         <!-- spotbugs->default -->
-        <dependency org="com.github.spotbugs" name="spotbugs" rev="4.8.3" conf="spotbugs->default"/>
-        <dependency org="com.github.spotbugs" name="spotbugs-ant" rev="4.8.3" conf="spotbugs->default"/>
+        <dependency org="com.github.spotbugs" name="spotbugs" rev="4.8.4" conf="spotbugs->default"/>
+        <dependency org="com.github.spotbugs" name="spotbugs-ant" rev="4.8.4" conf="spotbugs->default"/>
         <!-- errorprone->default -->
-        <dependency org="com.google.errorprone" name="error_prone_core" rev="${versions.error_prone}" conf="errorprone->default"/>
-        <!-- errorprone->default -->
-        <dependency org="com.google.errorprone" name="javac" rev="9+181-r4173-1" conf="errorprone_javac->default"/>
+        <dependency org="com.google.errorprone" name="error_prone_core" rev="2.26.1" conf="errorprone->default"/>
         <!-- animal->default -->
         <dependency org="org.codehaus.mojo" name="animal-sniffer-ant-tasks" rev="1.23" conf="animal->default"/>
