Index: src/org/openstreetmap/josm/actions/SimplifyWayAction.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision 12609)
+++ src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision )
@@ -7,14 +7,7 @@
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
@@ -134,25 +127,31 @@
      *
      * @param way the way to be simplified
      * @param node the node to check
-     * @return true if <code>node</code> is a required node which can't be removed
+     * @param hist precounted frequencies of nodes in way
+	 * @return true if <code>node</code> is a required node which can't be removed
      * in order to simplify the way.
      */
-    protected static boolean isRequiredNode(Way way, Node node) {
-        int frequency = Collections.frequency(way.getNodes(), node);
+    protected static boolean isRequiredNode(Way way, Node node, Map<Node, Integer> hist) {
+
+		// node is more than once in given way
+        int frequency = hist.get(node);
         if ((way.getNode(0) == node) && (way.getNode(way.getNodesCount()-1) == node)) {
             frequency = frequency - 1; // closed way closing node counted only once
         }
-        boolean isRequired = frequency > 1;
-        if (!isRequired) {
-            List<OsmPrimitive> parents = new LinkedList<>();
-            parents.addAll(node.getReferrers());
-            parents.remove(way);
-            isRequired = !parents.isEmpty();
-        }
-        if (!isRequired) {
-            isRequired = node.isTagged();
-        }
-        return isRequired;
+        if (frequency > 1){
+        	return true;
+		}
+
+		// other referrers than given way
+		List<OsmPrimitive> parents = new LinkedList<>();
+		parents.addAll(node.getReferrers());
+		parents.remove(way);
+		if (!parents.isEmpty()){
+			return true;
+		}
+
+		// has tags??
+        return node.isTagged();
     }
 
     /**
@@ -177,9 +176,12 @@
     public static SequenceCommand simplifyWay(Way w, double threshold) {
         int lower = 0;
         int i = 0;
+
         List<Node> newNodes = new ArrayList<>(w.getNodesCount());
+		Map<Node, Integer> hist = makeHistogram(w.getNodes());
+
         while (i < w.getNodesCount()) {
-            if (isRequiredNode(w, w.getNode(i))) {
+            if (isRequiredNode(w, w.getNode(i), hist)) {
                 // copy a required node to the list of new nodes. Simplify not possible
                 newNodes.add(w.getNode(i));
                 i++;
@@ -188,7 +190,7 @@
             }
             i++;
             // find the longest sequence of not required nodes ...
-            while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i))) {
+            while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i), hist)) {
                 i++;
             }
             // ... and simplify them
@@ -198,7 +200,7 @@
         }
 
         // Closed way, check if the first node could also be simplified ...
-        if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0))) {
+        if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0), hist)) {
             final List<Node> l1 = Arrays.asList(newNodes.get(newNodes.size() - 2), newNodes.get(0), newNodes.get(1));
             final List<Node> l2 = new ArrayList<>(3);
             buildSimplifiedNodeList(l1, 0, 2, threshold, l2);
@@ -208,9 +210,10 @@
             }
         }
 
-        Set<Node> delNodes = new HashSet<>();
-        delNodes.addAll(w.getNodes());
-        delNodes.removeAll(newNodes);
+		Set<Node> delNodes = new HashSet<>(w.getNodes());
+		for (Node n : newNodes) {
+			delNodes.remove(n);
+		}
 
         if (delNodes.isEmpty()) return null;
 
@@ -224,7 +227,21 @@
                 trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds);
     }
 
-    /**
+	private static Map<Node, Integer> makeHistogram(List<Node> nodes) {
+    	Map<Node, Integer> h = new HashMap<>(nodes.size());
+		for (Node node : nodes) {
+			Integer c = h.get(node);
+			if (c == null){
+				h.put(node, 1);
+			}
+			else {
+				h.put(node, c + 1);
+			}
+		}
+		return h;
+	}
+
+	/**
      * Builds the simplified list of nodes for a way segment given by a lower index <code>from</code>
      * and an upper index <code>to</code>
      *
