Index: trunk/src/org/openstreetmap/josm/data/projection/Projections.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 15717)
@@ -17,4 +17,5 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.projection.datum.Datum;
@@ -44,5 +45,4 @@
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -407,7 +407,7 @@
 
     private static String listKeys(Map<String, ?> map) {
-        List<String> keys = new ArrayList<>(map.keySet());
-        Collections.sort(keys);
-        return Utils.join(", ", keys);
+        return map.keySet().stream()
+                .sorted()
+                .collect(Collectors.joining(", "));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 15717)
@@ -76,5 +76,4 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
 
@@ -816,8 +815,9 @@
      */
     public String getLayerInformationForSourceTag() {
-        final Set<String> layerInfo = layerManager.getVisibleLayersInZOrder().stream()
+        return layerManager.getVisibleLayersInZOrder().stream()
                 .filter(layer -> layer.getChangesetSourceTag() != null && !layer.getChangesetSourceTag().trim().isEmpty())
-                .map(layer -> layer.getChangesetSourceTag().trim()).distinct().collect(Collectors.toSet());
-        return Utils.join("; ", layerInfo);
+                .map(layer -> layer.getChangesetSourceTag().trim())
+                .distinct()
+                .collect(Collectors.joining("; "));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/AbstractCopyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/AbstractCopyAction.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/AbstractCopyAction.java	(revision 15717)
@@ -3,10 +3,10 @@
 
 import java.awt.event.ActionEvent;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
 import java.util.function.IntFunction;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 import javax.swing.AbstractAction;
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.data.osm.Tagged;
 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -44,19 +43,16 @@
     public void actionPerformed(ActionEvent ae) {
         int[] rows = tagTable.getSelectedRows();
-        Set<String> values = new TreeSet<>();
         Collection<? extends Tagged> sel = objectSupplier.get();
         if (rows.length == 0 || sel == null || sel.isEmpty()) return;
 
-        for (int row: rows) {
-            String key = keySupplier.apply(row);
-            for (Tagged p : sel) {
-                Collection<String> s = getString(p, key);
-                if (s != null) {
-                    values.addAll(s);
-                }
-            }
-        }
+        final String values = Arrays.stream(rows)
+                .mapToObj(keySupplier)
+                .flatMap(key -> sel.stream().map(p -> getString(p, key)))
+                .filter(Objects::nonNull)
+                .flatMap(Collection::stream)
+                .sorted()
+                .collect(Collectors.joining("\n"));
         if (!values.isEmpty()) {
-            ClipboardUtils.copyString(Utils.join("\n", values));
+            ClipboardUtils.copyString(values);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java	(revision 15717)
@@ -13,4 +13,5 @@
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.JLabel;
@@ -33,5 +34,4 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
 
@@ -219,5 +219,5 @@
         txt.setColumns(40);
         txt.setRows(1);
-        txt.setText(Utils.join(", ", errs));
+        txt.setText(errs.stream().map(String::valueOf).collect(Collectors.joining(", ")));
         JScrollPane scroll = new JScrollPane(txt);
         p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 15717)
@@ -7,8 +7,6 @@
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
 import javax.swing.ImageIcon;
@@ -347,6 +345,5 @@
             return (MapCSSStyleSource) entry;
         }
-        Set<String> mimes = new HashSet<>(Arrays.asList(MapCSSStyleSource.MAPCSS_STYLE_MIME_TYPES.split(", ")));
-        try (CachedFile cf = new CachedFile(entry.url).setHttpAccept(Utils.join(", ", mimes))) {
+        try (CachedFile cf = new CachedFile(entry.url).setHttpAccept(MapCSSStyleSource.MAPCSS_STYLE_MIME_TYPES)) {
             String zipEntryPath = cf.findZipEntryPath("mapcss", "style");
             if (zipEntryPath != null) {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(revision 15717)
@@ -307,9 +307,9 @@
      * @param args arguments
      * @return assembled string
-     * @see Utils#join
+     * @see Collectors#joining
      */
     @NullableArguments
     public static String concat(Object... args) { // NO_UCD (unused code)
-        return Utils.join("", Arrays.asList(args));
+        return Arrays.stream(args).map(String::valueOf).collect(Collectors.joining());
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java	(revision 15717)
@@ -4,8 +4,8 @@
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.gui.mappaint.StyleSource;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -109,5 +109,7 @@
     @Override
     public String toString() {
-        return selector + " {\n  " + Utils.join("\n  ", declaration.instructions) + "\n}";
+        return selector + declaration.instructions.stream()
+                .map(String::valueOf)
+                .collect(Collectors.joining("\n  ", " {\n  ", "\n}"));
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 15717)
@@ -29,4 +29,5 @@
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -811,5 +812,5 @@
     @Override
     public String toString() {
-        return Utils.join("\n", rules);
+        return rules.stream().map(MapCSSRule::toString).collect(Collectors.joining("\n"));
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 15717)
@@ -14,4 +14,5 @@
 import java.util.function.IntSupplier;
 import java.util.regex.PatternSyntaxException;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.osm.INode;
@@ -783,5 +784,7 @@
         @Override
         public String toString() {
-            return base + (Range.ZERO_TO_INFINITY.equals(range) ? "" : range) + (conds != null ? Utils.join("", conds) : "")
+            return base
+                    + (Range.ZERO_TO_INFINITY.equals(range) ? "" : range)
+                    + (conds != null ? conds.stream().map(String::valueOf).collect(Collectors.joining("")) : "")
                     + (subpart != null && subpart != Subpart.DEFAULT_SUBPART ? ("::" + subpart) : "");
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java	(revision 15717)
@@ -30,5 +30,4 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -161,5 +160,6 @@
                 )
             );
-            name.setText(wms.buildRootUrlWithoutCapabilities() + ": " + Utils.join(", ", tree.getSelectedLayers()));
+            name.setText(wms.buildRootUrlWithoutCapabilities() + ": " +
+                    tree.getSelectedLayers().stream().map(LayerDetails::toString).collect(Collectors.joining(", ")));
         }
         showBounds.setEnabled(tree.getSelectedLayers().size() == 1);
Index: trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java	(revision 15717)
@@ -3,5 +3,5 @@
 
 import java.util.Set;
-import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
@@ -17,6 +17,7 @@
     @Override
     protected String buildRequestString(final OsmPrimitiveType type, Set<Long> idPackage) {
-        final Function<Long, Object> toOverpassExpression = x -> type.getAPIName() + '(' + x + ");>;";
-        final String query = '(' + Utils.join("", Utils.transform(idPackage, toOverpassExpression)) + ");out meta;";
+        final String query = idPackage.stream()
+                .map(x -> type.getAPIName() + '(' + x + ");>;")
+                .collect(Collectors.joining("", "(", ");out meta;"));
         return "interpreter?data=" + Utils.encodeUrl(query);
     }
Index: trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 15717)
@@ -23,4 +23,5 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -270,5 +271,5 @@
      */
     protected String buildRequestString(final OsmPrimitiveType type, Set<Long> idPackage) {
-        return type.getAPIName() + "s?" + type.getAPIName() + "s=" + Utils.join(",", idPackage);
+        return type.getAPIName() + "s?" + type.getAPIName() + "s=" + idPackage.stream().map(String::valueOf).collect(Collectors.joining(","));
     }
 
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 15717)
@@ -9,10 +9,11 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
@@ -237,17 +238,15 @@
             }
             Set<Layer> deps = dependencies.get(layer);
-            if (deps != null && !deps.isEmpty()) {
-                List<Integer> depsInt = new ArrayList<>();
-                for (Layer depLayer : deps) {
-                    int depIndex = layers.indexOf(depLayer);
-                    if (depIndex == -1) {
-                        Logging.warn("Unable to find " + depLayer);
-                    } else {
-                        depsInt.add(depIndex+1);
-                    }
+            final String depends = deps == null ? "" : deps.stream().map(depLayer -> {
+                int depIndex = layers.indexOf(depLayer);
+                if (depIndex == -1) {
+                    Logging.warn("Unable to find " + depLayer);
+                    return null;
+                } else {
+                    return Integer.toString(depIndex+1);
                 }
-                if (!depsInt.isEmpty()) {
-                    el.setAttribute("depends", Utils.join(",", depsInt));
-                }
+            }).filter(Objects::nonNull).collect(Collectors.joining(","));
+            if (!depends.isEmpty()) {
+                el.setAttribute("depends", depends);
             }
             layersEl.appendChild(el);
Index: trunk/src/org/openstreetmap/josm/tools/MultiMap.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/MultiMap.java	(revision 15716)
+++ trunk/src/org/openstreetmap/josm/tools/MultiMap.java	(revision 15717)
@@ -2,14 +2,13 @@
 package org.openstreetmap.josm.tools;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
@@ -246,9 +245,7 @@
     @Override
     public String toString() {
-        List<String> entries = new ArrayList<>(map.size());
-        for (Entry<A, Set<B>> entry : map.entrySet()) {
-            entries.add(entry.getKey() + "->{" + Utils.join(",", entry.getValue()) + '}');
-        }
-        return '(' + Utils.join(",", entries) + ')';
+        return map.entrySet().stream()
+                .map(entry -> entry.getKey() + "->" + entry.getValue())
+                .collect(Collectors.joining(",", "(", ")"));
     }
 }
