Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java	(working copy)
@@ -6,6 +6,7 @@
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -46,7 +47,7 @@
     public void actionPerformed(ActionEvent arg0) {
         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(
                     tr("Please select one or more ways with intersections of segments."))
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java	(working copy)
@@ -114,7 +114,7 @@
                 // Otherwise calculate position by solving y=mx+c (simplified)
                 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);
 
                 nx = (c2 - c1) / (m1 - m2);
@@ -145,11 +145,10 @@
     private Set<Way> findCommonWays(Set<Node> nodes) {
         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());
             }
         }
         return ways;
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java	(working copy)
@@ -47,14 +47,13 @@
     @Override
     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."))
             .setIcon(JOptionPane.WARNING_MESSAGE).show();
             return;
         }
-        Node nd = selectedNodes.get(0);
+        Node nd = selectedNodes.iterator().next();
         Node ndCopy = new Node(nd.getCoor());
         List<Command> cmds = new LinkedList<>();
 
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java	(working copy)
@@ -27,6 +27,7 @@
 import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * Pastes relation membership from objects in the paste buffer onto selected object(s).
@@ -58,7 +59,7 @@
         for (PrimitiveData pdata : data) {
             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()) {
                         if (m.getMember().equals(p)) {
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java	(working copy)
@@ -7,6 +7,7 @@
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -21,6 +22,7 @@
 import org.openstreetmap.josm.command.DeleteCommand;
 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;
 import org.openstreetmap.josm.data.osm.Way;
@@ -55,16 +57,15 @@
      */
     @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;
         Way splitWay = null;
 
@@ -91,7 +92,7 @@
         if (selectedWay == null && !selectedNodes.isEmpty()) {
             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: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java	(working copy)
@@ -45,13 +45,13 @@
     @Override
     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<>();
 
         for (Way way : selectedWays) {
             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) {
                         // When several ways are selected, split only those among selected
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java	(working copy)
@@ -23,6 +23,7 @@
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.plugins.utilsplugin2.command.ChangeRelationMemberCommand;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * Duplicate nodes, ways and relations that are used by multiple relations.
@@ -57,7 +58,7 @@
 
         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: src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CircleArcMaker.java	(working copy)
@@ -19,7 +19,6 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 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;
 
@@ -56,21 +55,6 @@
         //// Anchor nodes
         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();
 
@@ -124,7 +108,7 @@
             }
 
             for (Node n : consideredNodes) {
-                targetWays.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
+                targetWays.addAll(n.getParentWays());
             }
         }
         if (!nodesHaveBeenChoosen) {
@@ -296,7 +280,7 @@
         }
         assert (closestIndexToP2 != 0);
 
-        double a = direction * (stepLength);
+        double a = direction * stepLength;
         points.add(p1);
         if (indexJustBeforeP2 == 0 && includeAnchors) {
             points.add(p2);
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java	(working copy)
@@ -106,7 +106,7 @@
      * Replace a node with another node (similar to MergeNodesAction)
      */
     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."));
         }
         // FIXME: handle different layers
@@ -114,7 +114,7 @@
         Command c = MergeNodesAction.mergeNodes(
             Arrays.asList(subjectNode, referenceNode), referenceNode);
         if (c == null) {
-            // User canceled
+            // User cancelled
             return null;
         }
         commands.add(c);
@@ -131,7 +131,7 @@
      * @param referenceObject object with greater spatial quality
      */
     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."));
         }
 
@@ -168,7 +168,7 @@
         try {
             commands.addAll(getTagConflictResolutionCommands(subjectNode, referenceObject));
         } catch (UserCancelException e) {
-            // user canceled tag merge dialog
+            // user cancelled tag merge dialog
             return null;
         }
 
@@ -254,7 +254,7 @@
         try {
             commands.addAll(getTagConflictResolutionCommands(referenceWay, subjectWay));
         } catch (UserCancelException e) {
-            // user canceled tag merge dialog
+            // user cancelled tag merge dialog
             Logging.trace(e);
             return null;
         }
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java	(working copy)
@@ -16,7 +16,7 @@
  * Matches all ways connected to [nodes and ways which match the expression]..
  */
 public class ConnectedMatch extends SearchCompiler.UnaryMatch {
-    private Collection<Way> connected = null;
+    private Set<Way> connected = null;
     boolean all;
 
     public ConnectedMatch(SearchCompiler.Match match, boolean all) {
@@ -79,7 +79,7 @@
     public boolean equals(Object obj) {
         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;
         if (all != other.all)
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java	(working copy)
@@ -3,6 +3,7 @@
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Set;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -15,7 +16,7 @@
  * Matches all objects contained within the match expression.
  */
 public class InsideMatch extends SearchCompiler.UnaryMatch {
-    private Collection<OsmPrimitive> inside = null;
+    private Set<OsmPrimitive> inside = null;
 
     public InsideMatch(SearchCompiler.Match match) {
         super(match);
@@ -60,7 +61,7 @@
     public boolean equals(Object obj) {
         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;
         if (inside == null) {
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java	(working copy)
@@ -15,7 +15,7 @@
  * Find (all) ways intersecting ways or nodes which match the expression.
  */
 public class IntersectingMatch extends SearchCompiler.UnaryMatch {
-    private Collection<Way> intersecting = null;
+    private Set<Way> intersecting = null;
     boolean all;
 
     public IntersectingMatch(SearchCompiler.Match match, boolean all) {
@@ -69,7 +69,7 @@
     public boolean equals(Object obj) {
         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;
         if (all != other.all)
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/search/RangeMatch.java	(working copy)
@@ -53,7 +53,7 @@
     public boolean equals(Object obj) {
         if (this == obj)
             return true;
-        if (obj == null || getClass() != obj.getClass())
+        if (!(obj instanceof RangeMatch))
             return false;
         RangeMatch other = (RangeMatch) obj;
         if (max != other.max)
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentNodesAction.java	(working copy)
@@ -8,6 +8,7 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 import org.openstreetmap.josm.actions.JosmAction;
@@ -36,23 +37,20 @@
     @Override
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
+        Set<Way> selectedWays = new LinkedHashSet<>(ds.getSelectedWays());
 
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
-
         // if no nodes and no ways are selected, do nothing
         if (selectedNodes.isEmpty() && selectedWays.isEmpty()) return;
 
         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 {
             // use only ways that were selected for adding nodes
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/AdjacentWaysAction.java	(working copy)
@@ -35,11 +35,9 @@
     @Override
     public void actionPerformed(ActionEvent e) {
         DataSet ds = getLayerManager().getEditDataSet();
-        Collection<OsmPrimitive> selection = ds.getSelected();
-        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
+        Collection<Node> selectedNodes = ds.getSelectedNodes();
+        Collection<Way> selectedWays = ds.getSelectedWays();
 
-        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(ds.getSelected(), Way.class);
-
         // select ways attached to already selected ways
         Set<Way> newWays = new HashSet<>();
         NodeWayUtils.addWaysConnectedToWays(selectedWays, newWays);
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/ConnectedWaysAction.java	(working copy)
@@ -32,9 +32,8 @@
     @Override
     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: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysAction.java	(working copy)
@@ -34,7 +34,7 @@
     @Override
     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
         if (!selectedWays.isEmpty()) {
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/IntersectedWaysRecursiveAction.java	(working copy)
@@ -35,7 +35,7 @@
     @Override
     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()) {
             Set<Way> newWays = new HashSet<>();
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/MiddleNodesAction.java	(working copy)
@@ -33,8 +33,7 @@
 
     @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
         if (selectedNodes.size() != 2) {
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java	(working copy)
@@ -46,8 +46,10 @@
      * @param nodes collection to place the nodes we found
      */
     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;
 
@@ -74,6 +76,7 @@
      * Adds all ways attached to way to specified collection
      * @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) {
         int s = ways.size();
@@ -80,7 +83,7 @@
         List<Node> nodes = w.getNodes();
         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);
         return ways.size() - s;
@@ -90,10 +93,11 @@
      * Adds all ways attached to node to specified collection
      * @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;
     }
 
@@ -102,6 +106,7 @@
      * @param ways collection of ways to search
      * @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) {
         List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
@@ -153,6 +158,7 @@
      * @param allWays collection of ways to search
      * @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) {
         int count = 0;
@@ -168,7 +174,7 @@
         }
     }
 
-    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) {
             addWaysConnectedToNode(node, newWays);
@@ -234,7 +240,7 @@
         Node n1 = it.next();
         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) {
 
             if (w.isUsable() && w.containsNode(n2) && w.containsNode(n1)) {
@@ -343,11 +349,6 @@
         }
     }
 
-    static boolean isPointInsideMultipolygon(EastNorth p, Relation rel) {
-        Set<Way> usedWays = OsmPrimitive.getFilteredSet(rel.getMemberPrimitives(), Way.class);
-        return isPointInsidePolygon(p, buildPointList(usedWays));
-    }
-
     static void addAllInsideMultipolygon(DataSet data, Relation rel, Set<Way> newWays, Set<Node> newNodes) {
         if (!rel.isMultipolygon()) return;
         BBox box = rel.getBBox();
@@ -462,33 +463,19 @@
         return interCount;
     }
 
-    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);
-            }
+        // select nodes and ways inside selected ways and multipolygons
+        for (OsmPrimitive p: selected) {
+        	if (p instanceof Way) {
+        		addAllInsideWay(dataset, (Way)p, newWays, newNodes);
+        	}
         }
-        if (!selectedRels.isEmpty()) {
-            for (Relation r: selectedRels) {
-                addAllInsideMultipolygon(dataset, r, newWays, newNodes);
-            }
+        for (OsmPrimitive p: selected) {
+        	if (!(p instanceof Relation) || p.isMultipolygon())
+        		continue;
+        	addAllInsideMultipolygon(dataset, (Relation) p, newWays, newNodes);
         }
         if (ignoreNodesOfFoundWays) {
             for (Way w : newWays) {
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectHighwayAction.java	(working copy)
@@ -41,7 +41,7 @@
     @Override
     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) {
             ds.setSelected(selectNamedRoad(selectedWays.get(0)));
@@ -63,7 +63,7 @@
             nodeQueue.add(firstWay.firstNode());
             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);
                         nodeQueue.add(p.firstNode().equals(node) ? p.lastNode() : p.firstNode());
@@ -159,7 +159,7 @@
             for (int i = 0; i < nodesToCheck.size(); i++) {
                 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)) {
                         tree.add(way);
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java	(working copy)
@@ -19,7 +19,7 @@
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
- * Unselects all nodes
+ * Select last modified nodes.
  */
 public class SelectModNodesAction extends JosmAction {
     private int lastHash;
@@ -38,7 +38,7 @@
         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 = null;
 
             if (UndoRedoHandler.getInstance().commands == null) return;
@@ -45,6 +45,7 @@
             int num = UndoRedoHandler.getInstance().commands.size();
             if (num == 0) return;
             int k = 0, idx;
+            //FIXME: selection.hashCode() changes with each call of ds.getSelected()
             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);
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java	(working copy)
@@ -14,13 +14,12 @@
 import org.openstreetmap.josm.command.Command;
 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;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
- * Unselects all nodes
+ * Select last modified ways.
  */
 public class SelectModWaysAction extends JosmAction {
     private int lastHash;
@@ -39,7 +38,7 @@
         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;
 
             if (UndoRedoHandler.getInstance().commands == null) return;
@@ -46,6 +45,7 @@
             int num = UndoRedoHandler.getInstance().commands.size();
             if (num == 0) return;
             int k = 0, idx;
+            //FIXME: selection.hashCode() changes with each call of ds.getSelected()
             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);
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UndoSelectionAction.java	(working copy)
@@ -40,7 +40,7 @@
             if (history == null || history.isEmpty()) return; // empty history
             if (lastSel != null) {
             	Collection<OsmPrimitive> selection = ds.getSelected();
-            	if (selection.containsAll(lastSel) && lastSel.containsAll(selection)) {
+            	if (selection.containsAll(lastSel) && lastSel.size() == selection.size()) {
             		// repeated action
             	} else {
             		index = -1;
@@ -50,17 +50,18 @@
             int num = history.size();
             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 (newSel.containsAll(oldSel) && oldSel.size() == newSel.size()) {
                 		// ignore no-change selection
                 		continue;
                 	}
@@ -69,7 +70,7 @@
             }
 
             // set new selection (is added to history)
-            ds.setSelected(newsel);
+            ds.setSelected(newSel);
             lastSel = ds.getSelected();
         }
     }
Index: src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java	(revision 34811)
+++ src/org/openstreetmap/josm/plugins/utilsplugin2/selection/UnselectNodesAction.java	(working copy)
@@ -7,15 +7,13 @@
 import java.awt.event.ActionEvent;
 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
+ * Unselects all nodes.
  */
 public class UnselectNodesAction extends JosmAction {
 
@@ -32,9 +30,7 @@
 
     @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());
     }
 
     @Override
