Index: trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java	(revision 14654)
@@ -9,5 +9,4 @@
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -139,7 +138,6 @@
      */
     public static void runOn(DataSet ds) {
-        Collection<OsmPrimitive> sel = ds.getSelected();
-        List<Node> nodes = OsmPrimitive.getFilteredList(sel, Node.class);
-        List<Way> ways = OsmPrimitive.getFilteredList(sel, Way.class);
+        List<Node> nodes = new ArrayList<>(ds.getSelectedNodes());
+        Collection<Way> ways = ds.getSelectedWays();
 
         Way existingWay = null;
@@ -148,5 +146,5 @@
         // then use the way's nodes
         if (nodes.isEmpty() && (ways.size() == 1)) {
-            existingWay = ways.get(0);
+            existingWay = ways.iterator().next();
             for (Node n : existingWay.getNodes()) {
                 if (!nodes.contains(n)) {
@@ -203,9 +201,8 @@
 
         // Order nodes by angle
-        PolarNode[] angles = new PolarNode[nodes.size()];
-        for (int i = 0; i < nodes.size(); i++) {
-            angles[i] = new PolarNode(center, nodes.get(i));
-        }
-        Arrays.sort(angles, new PolarNodeComparator());
+        final PolarNode[] angles = nodes.stream()
+                .map(n -> new PolarNode(center, n))
+                .sorted()
+                .toArray(PolarNode[]::new);
         int[] count = distributeNodes(angles,
                 numberOfNodesInCircle >= nodes.size() ? (numberOfNodesInCircle - nodes.size()) : 0);
Index: trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java	(revision 14654)
@@ -190,5 +190,5 @@
             final Set<Relation> relatedRelations = new HashSet<>();
             for (final Way w : selectedWays) {
-                relatedRelations.addAll(Utils.filteredCollection(w.getReferrers(), Relation.class));
+                w.referrers(Relation.class).forEach(relatedRelations::add);
             }
             return relatedRelations.size() == 1 ? relatedRelations.iterator().next() : null;
Index: trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 14654)
@@ -17,4 +17,5 @@
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.JOptionPane;
@@ -75,7 +76,7 @@
         if (!isEnabled())
             return;
-        Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getAllSelected();
-        List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
-        selectedNodes.removeIf(n -> n.isDeleted() || n.isIncomplete());
+        final List<Node> selectedNodes = getLayerManager().getEditDataSet().getSelectedNodes().stream()
+                .filter(n -> !n.isDeleted() && !n.isIncomplete())
+                .collect(Collectors.toList());
 
         if (selectedNodes.size() == 1) {
@@ -203,5 +204,5 @@
         Set<Way> waysToDelete = new HashSet<>();
 
-        for (Way w: OsmPrimitive.getFilteredList(OsmPrimitive.getReferrer(nodesToDelete), Way.class)) {
+        for (Way w: (Iterable<Way>) nodesToDelete.stream().flatMap(p -> p.referrers(Way.class))::iterator) {
             List<Node> newNodes = new ArrayList<>(w.getNodesCount());
             for (Node n: w.getNodes()) {
Index: trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequences.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequences.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequences.java	(revision 14654)
@@ -89,6 +89,5 @@
         Way foundWay = null;
 
-        for (Way way : OsmPrimitive.getFilteredList(node.getReferrers(),
-                Way.class)) {
+        for (Way way : node.getParentWays()) {
             if (way.getNodesCount() < 2 || !way.isFirstLastNode(node)
                     || !way.isSelectable()
Index: trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision 14654)
@@ -16,4 +16,5 @@
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.JOptionPane;
@@ -98,6 +99,7 @@
         ds.beginUpdate();
         try {
-            List<Way> ways = OsmPrimitive.getFilteredList(ds.getSelected(), Way.class);
-            ways.removeIf(OsmPrimitive::isIncomplete);
+            List<Way> ways = ds.getSelectedWays().stream()
+                    .filter(p -> !p.isIncomplete())
+                    .collect(Collectors.toList());
             if (ways.isEmpty()) {
                 alertSelectAtLeastOneWay();
Index: trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 14654)
@@ -32,5 +32,4 @@
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
-import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.WaySegment;
@@ -83,8 +82,6 @@
         }
 
-        Collection<OsmPrimitive> selection = ds.getSelected();
-
-        List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
-        List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class);
+        List<Node> selectedNodes = new ArrayList<>(ds.getSelectedNodes());
+        List<Way> selectedWays = new ArrayList<>(ds.getSelectedWays());
         List<Way> applicableWays = getApplicableWays(selectedWays, selectedNodes);
 
@@ -139,8 +136,6 @@
         final List<List<Node>> wayChunks = SplitWayCommand.buildSplitChunks(selectedWay, selectedNodes);
         if (wayChunks != null) {
-            List<Relation> selectedRelations = OsmPrimitive.getFilteredList(selection, Relation.class);
-            final List<OsmPrimitive> sel = new ArrayList<>(selectedWays.size() + selectedRelations.size());
+            final List<OsmPrimitive> sel = new ArrayList<>(ds.getSelectedRelations());
             sel.addAll(selectedWays);
-            sel.addAll(selectedRelations);
 
             final List<Way> newWays = SplitWayCommand.createNewWaysFromChunks(selectedWay, wayChunks);
Index: trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 14654)
@@ -390,5 +390,5 @@
         }
         // modify all relations containing the node
-        for (Relation r : OsmPrimitive.getFilteredList(originalNode.getReferrers(), Relation.class)) {
+        for (Relation r : OsmPrimitive.getParentRelations(Collections.singleton(originalNode))) {
             if (r.isDeleted()) {
                 continue;
Index: trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java	(revision 14654)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.command.RemoveNodesCommand;
 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;
@@ -46,8 +47,7 @@
     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);
+        final DataSet dataSet = getLayerManager().getEditDataSet();
+        List<Node> selectedNodes = new ArrayList<>(dataSet.getSelectedNodes());
+        List<Way> selectedWays = new ArrayList<>(dataSet.getSelectedWays());
 
         selectedNodes = cleanSelectedNodes(selectedWays, selectedNodes);
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 14654)
@@ -1024,10 +1024,10 @@
     public static Way getWayForNode(Node n) {
         Way way = null;
-        for (Way w : Utils.filteredCollection(n.getReferrers(), Way.class)) {
+        for (Way w : (Iterable<Way>) n.referrers(Way.class)::iterator) {
             if (!w.isUsable() || w.getNodesCount() < 1) {
                 continue;
             }
-            Node firstNode = w.getNode(0);
-            Node lastNode = w.getNode(w.getNodesCount() - 1);
+            Node firstNode = w.firstNode();
+            Node lastNode = w.lastNode();
             if ((firstNode == n || lastNode == n) && (firstNode != lastNode)) {
                 if (way != null)
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 14654)
@@ -18,4 +18,5 @@
 import java.util.LinkedList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import javax.swing.JOptionPane;
@@ -432,13 +433,7 @@
                 virtualCmds.add(new AddCommand(ds, virtualNode));
 
-                // Looking for candidateSegment copies in ways that are
-                // referenced
-                // by candidateSegment nodes
-                List<Way> firstNodeWays = OsmPrimitive.getFilteredList(
-                        candidateSegment.getFirstNode().getReferrers(),
-                        Way.class);
-                List<Way> secondNodeWays = OsmPrimitive.getFilteredList(
-                        candidateSegment.getFirstNode().getReferrers(),
-                        Way.class);
+                // Looking for candidateSegment copies in ways that are referenced by candidateSegment nodes
+                List<Way> firstNodeWays = candidateSegment.getFirstNode().referrers(Way.class).collect(Collectors.toList());
+                List<Way> secondNodeWays = candidateSegment.getFirstNode().referrers(Way.class).collect(Collectors.toList());
 
                 Collection<WaySegment> virtualSegments = new LinkedList<>();
@@ -484,7 +479,7 @@
 
                 //check to see if node is in use by more than one object
-                List<OsmPrimitive> referrers = candidateNode.getReferrers();
-                List<Way> ways = OsmPrimitive.getFilteredList(referrers, Way.class);
-                if (referrers.size() != 1 || ways.size() != 1) {
+                long referrersCount = candidateNode.referrers(OsmPrimitive.class).count();
+                long referrerWayCount = candidateNode.referrers(Way.class).count();
+                if (referrersCount != 1 || referrerWayCount != 1) {
                     // detach node from way
                     final Way newWay = new Way(targetWay);
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 14654)
@@ -59,5 +59,4 @@
 import org.openstreetmap.josm.tools.PlatformManager;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -884,16 +883,11 @@
     private boolean movesHiddenWay() {
         DataSet ds = getLayerManager().getEditDataSet();
-        final Collection<OsmPrimitive> elementsToTest = new HashSet<>(ds.getSelected());
+        final Collection<Node> elementsToTest = new HashSet<>(ds.getSelectedNodes());
         for (Way osm : ds.getSelectedWays()) {
             elementsToTest.addAll(osm.getNodes());
         }
-        for (OsmPrimitive node : Utils.filteredCollection(elementsToTest, Node.class)) {
-            for (Way ref : Utils.filteredCollection(node.getReferrers(), Way.class)) {
-                if (ref.isDisabledAndHidden()) {
-                    return true;
-                }
-            }
-        }
-        return false;
+        return elementsToTest.stream()
+                .flatMap(n -> n.referrers(Way.class))
+                .anyMatch(Way::isDisabledAndHidden);
     }
 
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 14654)
@@ -19,4 +19,5 @@
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.Icon;
@@ -361,5 +362,5 @@
     protected static Collection<Node> computeNodesToDelete(Collection<OsmPrimitive> primitivesToDelete) {
         Collection<Node> nodesToDelete = new HashSet<>();
-        for (Way way : OsmPrimitive.getFilteredList(primitivesToDelete, Way.class)) {
+        for (Way way : Utils.filteredCollection(primitivesToDelete, Way.class)) {
             for (Node n : way.getNodes()) {
                 if (n.isTagged()) {
@@ -435,10 +436,12 @@
             return null;
 
-        Collection<Way> waysToBeChanged = new HashSet<>(OsmPrimitive.getFilteredSet(OsmPrimitive.getReferrer(primitivesToDelete), Way.class));
+        Collection<Way> waysToBeChanged = primitivesToDelete.stream()
+                .flatMap(p -> p.referrers(Way.class))
+                .collect(Collectors.toSet());
 
         Collection<Command> cmds = new LinkedList<>();
         for (Way w : waysToBeChanged) {
             Way wnew = new Way(w);
-            wnew.removeNodes(OsmPrimitive.getFilteredSet(primitivesToDelete, Node.class));
+            wnew.removeNodes(new HashSet<>(Utils.filteredCollection(primitivesToDelete, Node.class)));
             if (wnew.getNodesCount() < 2) {
                 primitivesToDelete.add(w);
@@ -460,5 +463,8 @@
         // remove the objects from their parent relations
         //
-        for (Relation cur : OsmPrimitive.getFilteredSet(OsmPrimitive.getReferrer(primitivesToDelete), Relation.class)) {
+        final Set<Relation> relationsToBeChanged = primitivesToDelete.stream()
+                .flatMap(p -> p.referrers(Relation.class))
+                .collect(Collectors.toSet());
+        for (Relation cur : relationsToBeChanged) {
             Relation rel = new Relation(cur);
             rel.removeMembersFor(primitivesToDelete);
Index: trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java	(revision 14654)
@@ -8,4 +8,5 @@
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -297,5 +298,5 @@
         // now copy all relations to new way also
 
-        for (Relation r : OsmPrimitive.getFilteredList(way.getReferrers(), Relation.class)) {
+        for (Relation r : OsmPrimitive.getParentRelations(Collections.singleton(way))) {
             if (!r.isUsable()) {
                 continue;
Index: trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 14654)
@@ -9,4 +9,5 @@
 import java.util.TreeSet;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -17,5 +18,4 @@
 import org.openstreetmap.josm.data.projection.ProjectionRegistry;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -370,5 +370,5 @@
         if (hops > 0 && visited != null) {
             visited.add(this);
-            for (final Way w : Utils.filteredCollection(this.getReferrers(), Way.class)) {
+            for (final Way w : getParentWays()) {
                 for (final Node n : w.getNodes()) {
                     final boolean containsN = visited.contains(n);
@@ -401,5 +401,5 @@
      */
     public List<Way> getParentWays() {
-        return getFilteredList(getReferrers(), Way.class);
+        return referrers(Way.class).collect(Collectors.toList());
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 14654)
@@ -6,10 +6,9 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
@@ -18,4 +17,6 @@
 import java.util.Set;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.openstreetmap.josm.data.osm.search.SearchCompiler;
@@ -91,14 +92,12 @@
      * @param type the type to filter for
      * @return the sub-list of OSM primitives of type <code>type</code>
-     */
+     * @deprecated Use {@link Stream} or {@link Utils#filteredCollection(Collection, Class)} instead.
+     */
+    @Deprecated
     public static <T extends OsmPrimitive> List<T> getFilteredList(Collection<OsmPrimitive> list, Class<T> type) {
-        if (list == null) return Collections.emptyList();
-        List<T> ret = new LinkedList<>();
-        for (OsmPrimitive p: list) {
-            if (type.isInstance(p)) {
-                ret.add(type.cast(p));
-            }
-        }
-        return ret;
+        return (list != null ? list.stream() : Stream.empty())
+                .filter(type::isInstance)
+                .map(type::cast)
+                .collect(Collectors.toList());
     }
 
@@ -113,15 +112,12 @@
      * @param type the type to filter for
      * @return the sub-set of OSM primitives of type <code>type</code>
-     */
+     * @deprecated Use {@link Stream} instead
+     */
+    @Deprecated
     public static <T extends OsmPrimitive> Set<T> getFilteredSet(Collection<OsmPrimitive> set, Class<T> type) {
-        Set<T> ret = new LinkedHashSet<>();
-        if (set != null) {
-            for (OsmPrimitive p: set) {
-                if (type.isInstance(p)) {
-                    ret.add(type.cast(p));
-                }
-            }
-        }
-        return ret;
+        return (set != null ? set.stream() : Stream.empty())
+                .filter(type::isInstance)
+                .map(type::cast)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
@@ -134,10 +130,7 @@
      */
     public static Set<OsmPrimitive> getReferrer(Collection<? extends OsmPrimitive> primitives) {
-        Set<OsmPrimitive> ret = new HashSet<>();
-        if (primitives == null || primitives.isEmpty()) return ret;
-        for (OsmPrimitive p: primitives) {
-            ret.addAll(p.getReferrers());
-        }
-        return ret;
+        return (primitives != null ? primitives.stream() : Stream.<OsmPrimitive>empty())
+                .flatMap(p -> p.referrers(OsmPrimitive.class))
+                .collect(Collectors.toSet());
     }
 
@@ -816,30 +809,40 @@
     }
 
-    @Override
-    public final List<OsmPrimitive> getReferrers(boolean allowWithoutDataset) {
+    private <T extends OsmPrimitive> Stream<T> referrers(boolean allowWithoutDataset, Class<T> filter) {
         // Returns only referrers that are members of the same dataset (primitive can have some fake references, for example
         // when way is cloned
 
-        if (dataSet == null && allowWithoutDataset)
-            return Collections.emptyList();
-
+        if (dataSet == null && allowWithoutDataset) {
+            return Stream.empty();
+        }
         checkDataset();
-        Object referrers = this.referrers;
-        List<OsmPrimitive> result = new ArrayList<>();
-        if (referrers != null) {
-            if (referrers instanceof OsmPrimitive) {
-                OsmPrimitive ref = (OsmPrimitive) referrers;
-                if (ref.dataSet == dataSet) {
-                    result.add(ref);
-                }
-            } else {
-                for (OsmPrimitive o:(OsmPrimitive[]) referrers) {
-                    if (dataSet == o.dataSet) {
-                        result.add(o);
-                    }
-                }
-            }
-        }
-        return result;
+        final Object referrers = this.referrers;
+        if (referrers == null) {
+            return Stream.empty();
+        }
+        final Stream<OsmPrimitive> stream = referrers instanceof OsmPrimitive
+                ? Stream.of((OsmPrimitive) referrers)
+                : Arrays.stream((OsmPrimitive[]) referrers);
+        return stream
+                .filter(p -> p.dataSet == dataSet)
+                .filter(filter::isInstance)
+                .map(filter::cast);
+    }
+
+    /**
+     * Gets all primitives in the current dataset that reference this primitive.
+     * @param filter restrict primitives to subclasses
+     * @param <T> type of primitives
+     * @return the referrers as Stream
+     * @since 14654
+     */
+    public final <T extends OsmPrimitive> Stream<T> referrers(Class<T> filter) {
+        return referrers(false, filter);
+    }
+
+    @Override
+    public final List<OsmPrimitive> getReferrers(boolean allowWithoutDataset) {
+        return referrers(allowWithoutDataset, OsmPrimitive.class)
+                .collect(Collectors.toList());
     }
 
@@ -1159,9 +1162,7 @@
      */
     public static Set<Relation> getParentRelations(Collection<? extends OsmPrimitive> primitives) {
-        Set<Relation> ret = new HashSet<>();
-        for (OsmPrimitive w : primitives) {
-            ret.addAll(OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class));
-        }
-        return ret;
+        return primitives.stream()
+                .flatMap(p -> p.referrers(Relation.class))
+                .collect(Collectors.toSet());
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationToChildReference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationToChildReference.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationToChildReference.java	(revision 14654)
@@ -6,4 +6,5 @@
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
@@ -19,5 +20,5 @@
      */
     public static Set<RelationToChildReference> getRelationToChildReferences(OsmPrimitive child) {
-        Set<Relation> parents = OsmPrimitive.getFilteredSet(child.getReferrers(), Relation.class);
+        Set<Relation> parents = child.referrers(Relation.class).collect(Collectors.toSet());
         Set<RelationToChildReference> references = new HashSet<>();
         for (Relation parent: parents) {
Index: trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 14654)
@@ -48,5 +48,4 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
-import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -1473,5 +1472,5 @@
         protected Long getNumber(OsmPrimitive osm) {
             if (osm instanceof Node) {
-                return (long) Utils.filteredCollection(osm.getReferrers(), Way.class).size();
+                return osm.referrers(Way.class).count();
             } else if (osm instanceof Relation) {
                 return (long) ((Relation) osm).getMemberPrimitives(Way.class).size();
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 14654)
@@ -76,6 +76,7 @@
 
     protected List<Relation> getAndCheckAssociatedStreets(OsmPrimitive p) {
-        List<Relation> list = OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class);
-        list.removeIf(r -> !r.hasTag("type", ASSOCIATED_STREET));
+        final List<Relation> list = p.referrers(Relation.class)
+                .filter(r -> r.hasTag("type", ASSOCIATED_STREET))
+                .collect(Collectors.toList());
         if (list.size() > 1) {
             Severity level;
@@ -107,8 +108,6 @@
                 }
             }
-            for (Way w : OsmPrimitive.getFilteredList(p.getReferrers(), Way.class)) {
-                if (w.hasKey(ADDR_INTERPOLATION) && w.hasKey(ADDR_STREET)) {
-                    return;
-                }
+            if (p.referrers(Way.class).anyMatch(w -> w.hasKey(ADDR_INTERPOLATION) && w.hasKey(ADDR_STREET))) {
+                return;
             }
             // No street found
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java	(revision 14654)
@@ -8,5 +8,4 @@
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -14,14 +13,13 @@
 import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.actions.MergeNodesAction;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.AbstractPrimitive;
 import org.openstreetmap.josm.data.osm.Hash;
 import org.openstreetmap.josm.data.osm.Node;
@@ -312,9 +310,10 @@
     @Override
     public Command fixError(TestError testError) {
-        Collection<OsmPrimitive> sel = new LinkedList<>(testError.getPrimitives());
-        Set<Node> nodes = new LinkedHashSet<>(OsmPrimitive.getFilteredList(sel, Node.class));
-
-        // Filter nodes that have already been deleted (see #5764 and #5773)
-        nodes.removeIf(AbstractPrimitive::isDeleted);
+        final Set<Node> nodes = testError.getPrimitives().stream()
+                .filter(Node.class::isInstance)
+                .map(Node.class::cast)
+                // Filter nodes that have already been deleted (see #5764 and #5773)
+                .filter(n -> !n.isDeleted())
+                .collect(Collectors.toCollection(LinkedHashSet::new));
 
         // Merge only if at least 2 nodes remain
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateRelation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateRelation.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateRelation.java	(revision 14654)
@@ -12,4 +12,5 @@
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -261,7 +262,7 @@
         // Find the relation that is member of one or more relations. (If any)
         Relation relationWithRelations = null;
-        List<Relation> relRef = null;
+        Collection<Relation> relRef = null;
         for (Relation w : relFix) {
-            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
+            Collection<Relation> rel = w.referrers(Relation.class).collect(Collectors.toList());
             if (!rel.isEmpty()) {
                 if (relationWithRelations != null)
@@ -318,12 +319,9 @@
             return false;
 
-        int relationsWithRelations = 0;
-        for (Relation w : rels) {
-            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
-            if (!rel.isEmpty()) {
-                ++relationsWithRelations;
-            }
-        }
-        return relationsWithRelations <= 1;
+        // count relations with relations
+        return rels.stream()
+                .filter(x -> x.referrers(Relation.class).anyMatch(y -> true))
+                .limit(2)
+                .count() <= 1;
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java	(revision 14654)
@@ -13,4 +13,5 @@
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -267,5 +268,5 @@
         List<Relation> relations = null;
         for (Way w : wayz) {
-            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
+            List<Relation> rel = w.referrers(Relation.class).collect(Collectors.toList());
             if (!rel.isEmpty()) {
                 if (wayWithRelations != null)
@@ -328,5 +329,5 @@
         int waysWithRelations = 0;
         for (Way w : wayz) {
-            List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
+            List<Relation> rel = w.referrers(Relation.class).collect(Collectors.toList());
             if (!rel.isEmpty()) {
                 ++waysWithRelations;
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java	(revision 14654)
@@ -115,5 +115,5 @@
         // As roundabouts are closed ways, take care of not processing the first/last node twice
         for (Node n : new HashSet<>(w.getNodes())) {
-            for (Way h : Utils.filteredCollection(n.getReferrers(), Way.class)) {
+            for (Way h : (Iterable<Way>) n.referrers(Way.class)::iterator) {
                 String value = h.get(HIGHWAY);
                 if (h != w && value != null) {
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(revision 14654)
@@ -69,10 +69,6 @@
 
     private static boolean parentMultipolygonConcernsArea(OsmPrimitive p) {
-        for (Relation r : OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class)) {
-            if (r.concernsArea()) {
-                return true;
-            }
-        }
-        return false;
+        return p.referrers(Relation.class)
+                .anyMatch(Relation::concernsArea);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesMembershipChoiceDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesMembershipChoiceDialog.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesMembershipChoiceDialog.java	(revision 14654)
@@ -6,4 +6,5 @@
 import java.awt.GridBagLayout;
 import java.util.Collection;
+import java.util.Objects;
 
 import javax.swing.AbstractButton;
@@ -154,5 +155,5 @@
     private static boolean isUsedInRelations(final Collection<Node> existingNodes) {
         return existingNodes.stream().anyMatch(
-                selectedNode -> selectedNode.getReferrers().stream().anyMatch(Relation.class::isInstance));
+                selectedNode -> selectedNode.referrers(Relation.class).anyMatch(Objects::nonNull));
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorter.java	(revision 14654)
@@ -17,5 +17,4 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.tools.AlphanumComparator;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -96,10 +95,11 @@
 
         private static String getStopName(OsmPrimitive p) {
-            for (Relation ref : Utils.filteredCollection(p.getReferrers(), Relation.class)) {
-                if (ref.hasTag("type", "public_transport") && ref.hasTag("public_transport", "stop_area") && ref.getName() != null) {
-                    return ref.getName();
-                }
-            }
-            return p.getName();
+            return p.referrers(Relation.class)
+                    .filter(ref -> ref.hasTag("type", "public_transport")
+                            && ref.hasTag("public_transport", "stop_area")
+                            && ref.getName() != null)
+                    .map(Relation::getName)
+                    .findFirst()
+                    .orElse(p.getName());
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 14654)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
@@ -33,5 +34,4 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
-import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -354,13 +354,13 @@
                     // if right selector also matches relations and if matched primitive is a way which is part of a multipolygon,
                     // use the multipolygon for further analysis
-                    if (!(e.osm instanceof IWay)
+                    if (!(e.osm instanceof Way)
                             || (right instanceof OptimizedGeneralSelector
                             && !((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.RELATION))) {
                         throw new NoSuchElementException();
                     }
-                    final Collection<Relation> multipolygons = Utils.filteredCollection(SubclassFilteredCollection.filter(
-                            e.osm.getReferrers(), p -> p.hasTag("type", "multipolygon")), Relation.class);
-                    final Relation multipolygon = multipolygons.iterator().next();
-                    if (multipolygon == null) throw new NoSuchElementException();
+                    final Relation multipolygon = ((Way) e.osm).referrers(Relation.class)
+                            .filter(p -> p.hasTag("type", "multipolygon"))
+                            .findFirst()
+                            .orElseThrow(NoSuchElementException::new);
                     final Set<OsmPrimitive> members = multipolygon.getMemberPrimitives();
                     containsFinder = new ContainsFinder(new Environment(multipolygon)) {
Index: trunk/src/org/openstreetmap/josm/tools/RotationAngle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/RotationAngle.java	(revision 14653)
+++ trunk/src/org/openstreetmap/josm/tools/RotationAngle.java	(revision 14654)
@@ -2,9 +2,9 @@
 package org.openstreetmap.josm.tools;
 
+import java.util.List;
 import java.util.Locale;
 
 import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
 
@@ -28,5 +28,5 @@
             }
             final Node n = (Node) p;
-            final SubclassFilteredCollection<OsmPrimitive, Way> ways = Utils.filteredCollection(n.getReferrers(), Way.class);
+            final List<Way> ways = n.getParentWays();
             if (ways.isEmpty()) {
                 return 0;
