Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java	(revision 34812)
@@ -7,4 +7,5 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -47,5 +48,5 @@
         if (!isEnabled())
             return;
-        List<Way> ways = OsmPrimitive.getFilteredList(getLayerManager().getEditDataSet().getSelected(), Way.class);
+        List<Way> ways = new ArrayList<>(getLayerManager().getEditDataSet().getSelectedWays());
         if (ways.isEmpty()) {
             new Notification(
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java	(revision 34812)
@@ -115,5 +115,5 @@
                 double m1 = (by - ay) / (bx - ax);
                 double c1 = ay - (ax * m1);
-                double m2 = (-1) / m1;
+                double m2 = -1.0 / m1;
                 double c2 = ny - (nx * m2);
 
@@ -146,9 +146,8 @@
         Set<Way> ways = null;
         for (Node n : nodes.stream().filter(n -> n.getDataSet() != null).collect(Collectors.toList())) {
-            List<Way> referrers = OsmPrimitive.getFilteredList(n.getReferrers(), Way.class);
             if (ways == null)
-                ways = new HashSet<>(referrers);
+                ways = new HashSet<>(n.getParentWays());
             else {
-                ways.retainAll(referrers);
+                ways.retainAll(n.getParentWays());
             }
         }
@@ -171,4 +170,7 @@
      *
      * TODO: not the maximum node count, but maximum distance!
+     * @param way the way
+     * @param nodes the selected nodes
+     * @return the index of the node right after the largest empty span
      */
     private int findFirstNode(Way way, Set<Node> nodes) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java	(revision 34812)
@@ -48,6 +48,5 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
         if (selectedNodes.size() != 1) {
             new Notification(tr("This tool extracts node from its ways and requires single node to be selected."))
@@ -55,5 +54,5 @@
             return;
         }
-        Node nd = selectedNodes.get(0);
+        Node nd = selectedNodes.iterator().next();
         Node ndCopy = new Node(nd.getCoor());
         List<Command> cmds = new LinkedList<>();
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java	(revision 34812)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -59,5 +60,5 @@
             OsmPrimitive p = getLayerManager().getEditDataSet().getPrimitiveById(pdata.getUniqueId(), pdata.getType());
             if (p != null) {
-                for (Relation r : OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class)) {
+                for (Relation r : Utils.filteredCollection(p.getReferrers(), Relation.class)) {
                     String role = relations.get(r);
                     for (RelationMember m : r.getMembers()) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java	(revision 34812)
@@ -8,4 +8,5 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -22,4 +23,5 @@
 import org.openstreetmap.josm.command.SplitWayCommand;
 import org.openstreetmap.josm.data.UndoRedoHandler;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -56,13 +58,12 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected();
-
-        List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
-        List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class);
-
-        if (!checkSelection(selection)) {
+    	DataSet ds = getLayerManager().getEditDataSet();
+        if (!checkSelection(ds.getSelected())) {
             showWarningNotification(tr("The current selection cannot be used for splitting."));
             return;
         }
+
+        List<Node> selectedNodes = new ArrayList<>(ds.getSelectedNodes());
+        List<Way> selectedWays = new ArrayList<>(ds.getSelectedWays());
 
         Way selectedWay = null;
@@ -92,5 +93,5 @@
             Map<Way, Integer> wayOccurenceCounter = new HashMap<>();
             for (Node n : selectedNodes) {
-                for (Way w : OsmPrimitive.getFilteredList(n.getReferrers(), Way.class)) {
+                for (Way w : n.getParentWays()) {
                     if (!w.isUsable()) {
                         continue;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java	(revision 34812)
@@ -46,5 +46,5 @@
     public void actionPerformed(ActionEvent e) {
         List<Command> list = new ArrayList<>();
-        List<Way> selectedWays = OsmPrimitive.getFilteredList(getLayerManager().getEditDataSet().getSelected(), Way.class);
+        List<Way> selectedWays = new ArrayList<>(getLayerManager().getEditDataSet().getSelectedWays());
         Map<Way, List<Node>> splitWays = new HashMap<>();
 
@@ -52,5 +52,5 @@
             if (way.getNodesCount() > 1 && !way.hasIncompleteNodes() && !way.isClosed())
                 for (Node node : new Node[] {way.getNode(0), way.getNode(way.getNodesCount() - 1)}) {
-                    List<Way> refs = OsmPrimitive.getFilteredList(node.getReferrers(), Way.class);
+                    List<Way> refs = node.getParentWays();
                     refs.remove(way);
                     if (selectedWays.size() > 1) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SymmetryAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SymmetryAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SymmetryAction.java	(revision 34812)
@@ -31,5 +31,5 @@
  * Note: If a ways are selected, their nodes are mirrored
  *
- * @author Alexei Kasatkin, based on much copy&Paste from other MirrorAction :)
+ * @author Alexei Kasatkin, based on much copy+paste from other MirrorAction :)
  */
 public final class SymmetryAction extends JosmAction {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/TagBufferAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/TagBufferAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/TagBufferAction.java	(revision 34812)
@@ -87,6 +87,7 @@
 
     /**
-     * Find those tags which appear in all primitives of the selection
+     * Find those tags which appear in all tagged primitives of the selection.
      * @param selection the selection
+     * @return the common tags of all tagged primitives in the selection
      */
     private static TagCollection getCommonTags(List<OsmPrimitive> selection) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java	(revision 34812)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.plugins.utilsplugin2.command.ChangeRelationMemberCommand;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -58,5 +59,5 @@
         for (OsmPrimitive p : selection) {
             boolean first = true;
-            for (Relation relation : OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class)) {
+            for (Relation relation : Utils.filteredCollection(p.getReferrers(), Relation.class)) {
                 if (relation.isDeleted()) {
                     continue;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java	(revision 34812)
@@ -20,5 +20,4 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -57,19 +56,4 @@
         Node n1 = null, n2 = null, n3 = null;
 
-        if (false) {
-            int nodeCount = selectedNodes.size();
-            int wayCount = selectedWays.size();
-
-            // TODO: filter garbage nodes based on selected ways
-
-            // Never interested in more than 3 nodes. Nodes prioritized by reverse selection order, but keep their order.
-            // TODO: replace by helper function (eg. getPostFixList(int count))
-            Node[] nodesOfInterest = new Node[3];
-            int nodesOfInterestCount = Math.min(nodeCount, 3);
-            for (int i = nodesOfInterestCount - 1; i >= 0; i--) {
-                nodesOfInterest[i] = selectedNodes.get(nodeCount - 1 - i);
-            }
-        }
-
         Set<Way> targetWays = new HashSet<>();
         DataSet ds = MainApplication.getLayerManager().getEditDataSet();
@@ -125,5 +109,5 @@
 
             for (Node n : consideredNodes) {
-                targetWays.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+                targetWays.addAll(n.getParentWays());
             }
         }
@@ -222,9 +206,12 @@
      * Return a list of coordinates lying an the circle arc determined by n1, n2 and n3.
      * The order of the list and which of the 3 possible arcs to construct are given by the order of n1, n2, n3
-     *
-     * @param includeAnchors include the anchorpoints in the list. The original objects will be used, not copies.
+     * @param p1 n1
+     * @param p2 n2
+     * @param p3 n3
+     * @param angleSeparation maximum angle separation between the arc points
+     * @param includeAnchors include the anchor points in the list. The original objects will be used, not copies.
      *                       If {@code false}, p2 will be replaced by the closest arcpoint.
      * @param anchor2Index if non-null, it's value will be set to p2's index in the returned list.
-     * @param angleSparation maximum angle separation between the arc points
+     * @return list of coordinates lying an the circle arc determined by n1, n2 and n3
      */
     private static List<EastNorth> circleArcPoints(EastNorth p1, EastNorth p2, EastNorth p3,
@@ -297,5 +284,5 @@
         assert (closestIndexToP2 != 0);
 
-        double a = direction * (stepLength);
+        double a = direction * stepLength;
         points.add(p1);
         if (indexJustBeforeP2 == 0 && includeAnchors) {
@@ -330,5 +317,7 @@
 
     /**
-     * Normalizes {@code a} so it is between 0 and 2 PI
+     * Normalizes {@code angle} so it is between 0 and 2 PI
+     * @param angle the angle
+     * @return the normalized angle
      */
     private static double normalizeAngle(double angle) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/OpenPageAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/OpenPageAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/OpenPageAction.java	(revision 34812)
@@ -26,9 +26,8 @@
 
 /**
- * Mirror the selected ways nodes or ways along line given by two first selected points
  *
- * Note: If a ways are selected, their nodes are mirrored
+ * Open custom URL
  *
- * @author Alexei Kasatkin, based on much copy&Paste from other MirrorAction :)
+ * @author Alexei Kasatkin
  */
 public final class OpenPageAction extends JosmAction {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java	(revision 34812)
@@ -19,5 +19,5 @@
 
 /**
- * Replaces already existing object (id>0) with a new object (id<0).
+ * Replaces already existing object (id&gt;0) with a new object (id&lt;0).
  *
  * @author Zverik
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java	(revision 34812)
@@ -107,5 +107,5 @@
      */
     public static ReplaceGeometryCommand buildReplaceNodeCommand(Node subjectNode, Node referenceNode) {
-        if (!OsmPrimitive.getFilteredList(subjectNode.getReferrers(), Way.class).isEmpty()) {
+        if (!subjectNode.getParentWays().isEmpty()) {
             throw new ReplaceGeometryException(tr("Node belongs to way(s), cannot replace."));
         }
@@ -115,5 +115,5 @@
             Arrays.asList(subjectNode, referenceNode), referenceNode);
         if (c == null) {
-            // User canceled
+            // User cancelled
             return null;
         }
@@ -132,5 +132,5 @@
      */
     public static ReplaceGeometryCommand buildUpgradeNodeCommand(Node subjectNode, OsmPrimitive referenceObject) {
-        if (!OsmPrimitive.getFilteredList(subjectNode.getReferrers(), Way.class).isEmpty()) {
+    	if (!subjectNode.getParentWays().isEmpty()) {
             throw new ReplaceGeometryException(tr("Node belongs to way(s), cannot replace."));
         }
@@ -169,5 +169,5 @@
             commands.addAll(getTagConflictResolutionCommands(subjectNode, referenceObject));
         } catch (UserCancelException e) {
-            // user canceled tag merge dialog
+            // user cancelled tag merge dialog
             return null;
         }
@@ -255,5 +255,5 @@
             commands.addAll(getTagConflictResolutionCommands(referenceWay, subjectWay));
         } catch (UserCancelException e) {
-            // user canceled tag merge dialog
+            // user cancelled tag merge dialog
             Logging.trace(e);
             return null;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java	(revision 34812)
@@ -17,5 +17,5 @@
  */
 public class ConnectedMatch extends SearchCompiler.UnaryMatch {
-    private Collection<Way> connected = null;
+    private Set<Way> connected = null;
     boolean all;
 
@@ -80,5 +80,5 @@
         if (this == obj)
             return true;
-        if (!super.equals(obj) || getClass() != obj.getClass())
+        if (!super.equals(obj) || !(obj instanceof ConnectedMatch))
             return false;
         ConnectedMatch other = (ConnectedMatch) obj;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java	(revision 34812)
@@ -4,4 +4,5 @@
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Set;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -16,5 +17,5 @@
  */
 public class InsideMatch extends SearchCompiler.UnaryMatch {
-    private Collection<OsmPrimitive> inside = null;
+    private Set<OsmPrimitive> inside = null;
 
     public InsideMatch(SearchCompiler.Match match) {
@@ -61,5 +62,5 @@
         if (this == obj)
             return true;
-        if (!super.equals(obj) || getClass() != obj.getClass())
+        if (!super.equals(obj) || !(obj instanceof InsideMatch))
             return false;
         InsideMatch other = (InsideMatch) obj;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java	(revision 34812)
@@ -16,5 +16,5 @@
  */
 public class IntersectingMatch extends SearchCompiler.UnaryMatch {
-    private Collection<Way> intersecting = null;
+    private Set<Way> intersecting = null;
     boolean all;
 
@@ -70,5 +70,5 @@
         if (this == obj)
             return true;
-        if (!super.equals(obj) || getClass() != obj.getClass())
+        if (!super.equals(obj) || !(obj instanceof IntersectingMatch))
             return false;
         IntersectingMatch other = (IntersectingMatch) obj;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java	(revision 34812)
@@ -54,5 +54,5 @@
         if (this == obj)
             return true;
-        if (obj == null || getClass() != obj.getClass())
+        if (!(obj instanceof RangeMatch))
             return false;
         RangeMatch other = (RangeMatch) obj;
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java	(revision 34812)
@@ -9,4 +9,5 @@
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -37,8 +38,6 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
+        Set<Way> selectedWays = new LinkedHashSet<>(ds.getSelectedWays());
 
         // if no nodes and no ways are selected, do nothing
@@ -46,12 +45,11 @@
 
         if (selectedWays.isEmpty()) {
-            // if one node is selected, used ways connected to it to extend selecteons
+            // if one node is selected, use ways connected to it to extend selection
             // activeWays are remembered for next extend action (!!!)
 
-            // FIXME: some strange behaviour is possible if user delete some of these way
+            // FIXME: some strange behaviour is possible if user deletes some of these ways
             // how to clear activeWays during such user actions? Do not know
             if (selectedNodes.size() == 1) {
                 activeWays.clear();
-                //                System.out.println("Cleared active ways");
             }
         } else {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java	(revision 34812)
@@ -36,8 +36,6 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
+        Collection<Way> selectedWays = ds.getSelectedWays();
 
         // select ways attached to already selected ways
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java	(revision 34812)
@@ -33,7 +33,6 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
+        Collection<Way> selectedWays = ds.getSelectedWays();
 
         Set<Way> newWays = new HashSet<>();
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java	(revision 34812)
@@ -35,5 +35,5 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
+        Collection<Way> selectedWays = ds.getSelectedWays();
 
         // select ways attached to already selected ways
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(revision 34812)
@@ -36,5 +36,5 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
+        Collection<Way> selectedWays = ds.getSelectedWays();
 
         if (!selectedWays.isEmpty()) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java	(revision 34812)
@@ -34,6 +34,5 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Set<Node> selectedNodes = new HashSet<>(getLayerManager().getEditDataSet().getSelectedNodes());
 
         // if no 2 nodes and no ways are selected, do nothing
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java	(revision 34812)
@@ -47,6 +47,8 @@
      */
     static void addNeighbours(Way w, Node n, Collection<Node> nodes) {
+        if (!n.getParentWays().contains(w))
+        	return;
+
         List<Node> nodeList = w.getNodes();
-
         int idx = nodeList.indexOf(n);
         if (idx == -1) return;
@@ -75,4 +77,5 @@
      * @param w way to find attached ways
      * @param ways  collection to place the ways we found
+     * @return number of ways added
      */
     static int addWaysConnectedToWay(Way w, Set<Way> ways) {
@@ -81,5 +84,5 @@
         boolean flag = ways.contains(w);
         for (Node n: nodes) {
-            ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+            ways.addAll(n.getParentWays());
         }
         if (!flag) ways.remove(w);
@@ -91,8 +94,9 @@
      * @param n Node to find attached ways
      * @param ways  collection to place the ways we found
+     * @return number of ways added
      */
     static int addWaysConnectedToNode(Node n, Set<Way> ways) {
         int s = ways.size();
-        ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+        ways.addAll(n.getParentWays());
         return ways.size() - s;
     }
@@ -103,4 +107,5 @@
      * @param w way to check intersections
      * @param newWays set to place the ways we found
+     * @return number of ways possibly added added to newWays
      */
     static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays, Set<Way> excludeWays) {
@@ -154,4 +159,5 @@
      * @param initWays ways to check intersections
      * @param newWays set to place the ways we found
+     * @return number of ways added to newWays
      */
     public static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
@@ -169,5 +175,5 @@
     }
 
-    public static int addWaysConnectedToNodes(Set<Node> selectedNodes, Set<Way> newWays) {
+    public static int addWaysConnectedToNodes(Collection<Node> selectedNodes, Set<Way> newWays) {
         int s = newWays.size();
         for (Node node: selectedNodes) {
@@ -235,5 +241,5 @@
         Node n2 = it.next();
         Set<Way> ways = new HashSet<>();
-        ways.addAll(OsmPrimitive.getFilteredList(n1.getReferrers(), Way.class));
+        ways.addAll(n1.getParentWays());
         for (Way w: ways) {
 
@@ -342,9 +348,4 @@
             }
         }
-    }
-
-    static boolean isPointInsideMultipolygon(EastNorth p, Relation rel) {
-        Set<Way> usedWays = OsmPrimitive.getFilteredSet(rel.getMemberPrimitives(), Way.class);
-        return isPointInsidePolygon(p, buildPointList(usedWays));
     }
 
@@ -463,31 +464,17 @@
     }
 
-    public static Collection<OsmPrimitive> selectAllInside(Collection<OsmPrimitive> selected, DataSet dataset) {
-        return selectAllInside(selected, dataset, true);
-    }
-
-    public static Collection<OsmPrimitive> selectAllInside(Collection<OsmPrimitive> selected, DataSet dataset, boolean ignoreNodesOfFoundWays) {
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(selected, Way.class);
-        Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(selected, Relation.class);
-
-        for (Iterator<Relation> it = selectedRels.iterator(); it.hasNext();) {
-            Relation r = it.next();
-            if (!r.isMultipolygon()) {
-                it.remove();
-            }
-        }
-
+    public static Set<OsmPrimitive> selectAllInside(Collection<OsmPrimitive> selected, DataSet dataset, boolean ignoreNodesOfFoundWays) {
         Set<Way> newWays = new HashSet<>();
         Set<Node> newNodes = new HashSet<>();
-        // select nodes and ways inside slexcted ways and multipolygons
-        if (!selectedWays.isEmpty()) {
-            for (Way w: selectedWays) {
-                addAllInsideWay(dataset, w, newWays, newNodes);
-            }
-        }
-        if (!selectedRels.isEmpty()) {
-            for (Relation r: selectedRels) {
-                addAllInsideMultipolygon(dataset, r, newWays, newNodes);
-            }
+        // select nodes and ways inside selected ways and multipolygons
+        for (OsmPrimitive p: selected) {
+        	if (p instanceof Way) {
+        		addAllInsideWay(dataset, (Way)p, newWays, newNodes);
+        	}
+        }
+        for (OsmPrimitive p: selected) {
+        	if (!(p instanceof Relation) || p.isMultipolygon())
+        		continue;
+        	addAllInsideMultipolygon(dataset, (Relation) p, newWays, newNodes);
         }
         if (ignoreNodesOfFoundWays) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java	(revision 34812)
@@ -42,5 +42,5 @@
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        List<Way> selectedWays = OsmPrimitive.getFilteredList(ds.getSelected(), Way.class);
+        List<Way> selectedWays = new ArrayList<>(ds.getSelectedWays());
 
         if (selectedWays.size() == 1) {
@@ -64,5 +64,5 @@
             while (!nodeQueue.isEmpty()) {
                 Node node = nodeQueue.remove();
-                for (Way p : OsmPrimitive.getFilteredList(node.getReferrers(), Way.class)) {
+                for (Way p : node.getParentWays()) {
                     if (!newWays.contains(p) && p.hasKey(key) && p.get(key).equals(value)) {
                         newWays.add(p);
@@ -160,5 +160,5 @@
                 Node node = nodesToCheck.get(i);
                 Integer nodeRef = nodeRefs.get(i);
-                for (Way way : OsmPrimitive.getFilteredList(node.getReferrers(), Way.class)) {
+                for (Way way : node.getParentWays()) {
                     if ((way.firstNode().equals(node) || way.lastNode().equals(node)) &&
                             !tree.contains(way) && suits(way)) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java	(revision 34812)
@@ -20,8 +20,7 @@
 
 /**
- * Unselects all nodes
+ * Select last modified nodes.
  */
 public class SelectModNodesAction extends JosmAction {
-    private int lastHash;
     private Command lastCmd;
 
@@ -39,5 +38,5 @@
         if (ds != null) {
             Collection<OsmPrimitive> selection = ds.getSelected();
-            ds.clearSelection(OsmPrimitive.getFilteredSet(selection, Node.class));
+            ds.clearSelection(ds.getSelectedWays());
             Command cmd = null;
 
@@ -46,7 +45,7 @@
             if (num == 0) return;
             int k = 0, idx;
-            if (selection != null && !selection.isEmpty() && selection.hashCode() == lastHash) {
-                // we are selecting next command in history if nothing is selected
-                idx = UndoRedoHandler.getInstance().commands.indexOf(lastCmd);
+         // check if executed again, we cycle through all available commands
+            if (lastCmd != null && !selection.isEmpty() ) {
+                idx = UndoRedoHandler.getInstance().commands.lastIndexOf(lastCmd);
             } else {
                 idx = num;
@@ -57,18 +56,19 @@
                 if (idx > 0) idx--; else idx = num-1;
                 cmd = UndoRedoHandler.getInstance().commands.get(idx);
-                Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
-                nodes.clear();
-                for (OsmPrimitive p : pp) {  // find all affected ways
-                    if (p instanceof Node && !p.isDeleted()) nodes.add((Node) p);
-                }
-                if (!nodes.isEmpty()) {
-                    ds.setSelected(nodes);
-                    lastCmd = cmd; // remember last used command and last selection
-                    lastHash = ds.getSelected().hashCode();
-                    return;
+                if (cmd.getAffectedDataSet() == ds) {
+                	Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
+                	nodes.clear();
+                	for (OsmPrimitive p : pp) {  // find all affected ways
+                		if (p instanceof Node && !p.isDeleted()) nodes.add((Node) p);
+                	}
+                	if (!nodes.isEmpty() && !ds.getSelectedNodes().containsAll(nodes)) {
+                		ds.setSelected(nodes);
+                		lastCmd = cmd; // remember last used command and last selection
+                		return;
+                	}
                 }
                 k++;
             } while (k < num); // try to find previous command if this affects nothing
-            lastCmd = null; lastHash = 0;
+            lastCmd = null;
         }
     }
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java	(revision 34812)
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.data.UndoRedoHandler;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
@@ -21,8 +20,7 @@
 
 /**
- * Unselects all nodes
+ * Select last modified ways.
  */
 public class SelectModWaysAction extends JosmAction {
-    private int lastHash;
     private Command lastCmd;
 
@@ -39,6 +37,5 @@
         DataSet ds = getLayerManager().getEditDataSet();
         if (ds != null) {
-            Collection<OsmPrimitive> selection = ds.getSelected();
-            ds.clearSelection(OsmPrimitive.getFilteredSet(selection, Node.class));
+            ds.clearSelection(ds.getSelectedNodes());
             Command cmd;
 
@@ -47,7 +44,7 @@
             if (num == 0) return;
             int k = 0, idx;
-            if (selection != null && !selection.isEmpty() && selection.hashCode() == lastHash) {
-                // we are selecting next command in history if nothing is selected
-                idx = UndoRedoHandler.getInstance().commands.indexOf(lastCmd);
+            // check if executed again, we cycle through all available commands
+            if (lastCmd != null && !ds.getSelectedWays().isEmpty() ) {
+                idx = UndoRedoHandler.getInstance().commands.lastIndexOf(lastCmd);
             } else {
                 idx = num;
@@ -58,19 +55,20 @@
                 if (idx > 0) idx--; else idx = num-1;
                 cmd = UndoRedoHandler.getInstance().commands.get(idx);
-                Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
-                ways.clear();
-                for (OsmPrimitive p : pp) {  // find all affected ways
-                    if (p instanceof Way && !p.isDeleted()) ways.add((Way) p);
-                }
-                if (!ways.isEmpty() && !ds.getSelected().containsAll(ways)) {
-                    ds.setSelected(ways);
-                    lastCmd = cmd; // remember last used command and last selection
-                    lastHash = ds.getSelected().hashCode();
-                    return;
+                if (cmd.getAffectedDataSet() == ds) {
+                	Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
+                	ways.clear();
+                	for (OsmPrimitive p : pp) {
+                		// find all affected ways
+                		if (p instanceof Way && !p.isDeleted()) ways.add((Way) p);
+                	}
+                	if (!ways.isEmpty() && !ds.getSelectedWays().containsAll(ways)) {
+                		ds.setSelected(ways);
+                		lastCmd = cmd; // remember last used command and last selection
+                		return;
+                	}
                 }
                 k++;
             } while (k < num); // try to find previous command if this affects nothing
             lastCmd = null;
-            lastHash = 0;
         }
     }
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java	(revision 34812)
@@ -18,5 +18,5 @@
 
 /**
- * Use selection istory to restore previous selection
+ * Use selection history to restore previous selection
  */
 public class UndoSelectionAction extends JosmAction {
@@ -41,5 +41,5 @@
             if (lastSel != null) {
             	Collection<OsmPrimitive> selection = ds.getSelected();
-            	if (selection.containsAll(lastSel) && lastSel.containsAll(selection)) {
+            	if (lastSel.size() == selection.size() && selection.containsAll(lastSel)) {
             		// repeated action
             	} else {
@@ -51,15 +51,16 @@
             int k = 0;
 
-            Set<OsmPrimitive> newsel = new HashSet<>();
+            Set<OsmPrimitive> newSel = new HashSet<>();
             while (k < num) {
                 if (index+1 < history.size()) index++; else index = 0;
                 Collection<? extends OsmPrimitive> histsel = history.get(index);
                 // remove deleted entities from selection
-                newsel.clear();
-                newsel.addAll(histsel);
-                newsel.removeIf(p -> p == null || p.isDeleted());
+                newSel.clear();
+                newSel.addAll(histsel);
+                newSel.removeIf(p -> p == null || p.isDeleted());
                 k++;
-                if (!newsel.isEmpty()) {
-                	if (newsel.containsAll(ds.getSelected()) && ds.getSelected().containsAll(newsel)) {
+                if (!newSel.isEmpty()) {
+                	Collection<OsmPrimitive> oldSel = ds.getSelected();
+                	if (oldSel.size() == newSel.size() && newSel.containsAll(oldSel)) {
                 		// ignore no-change selection
                 		continue;
@@ -70,5 +71,5 @@
 
             // set new selection (is added to history)
-            ds.setSelected(newsel);
+            ds.setSelected(newSel);
             lastSel = ds.getSelected();
         }
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java	(revision 34793)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java	(revision 34812)
@@ -8,13 +8,11 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
-import java.util.Set;
 
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
- * Unselects all nodes
+ * Unselect all nodes.
  */
 public class UnselectNodesAction extends JosmAction {
@@ -33,7 +31,5 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-        getLayerManager().getEditDataSet().clearSelection(selectedNodes);
+        getLayerManager().getEditDataSet().clearSelection(getLayerManager().getEditDataSet().getSelectedNodes());
     }
 
