Index: trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java	(revision 3177)
@@ -41,5 +41,5 @@
 
         List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(
-                Main.map.mapView.getPoint(node));
+                Main.map.mapView.getPoint(node), OsmPrimitive.isSelectablePredicate);
         HashMap<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
         for (WaySegment ws : wss) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 3177)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.command.DeleteCommand;
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.WaySegment;
@@ -286,7 +287,7 @@
         DeleteParameters result = new DeleteParameters();
 
-        result.nearestNode = Main.map.mapView.getNearestNode(e.getPoint());
+        result.nearestNode = Main.map.mapView.getNearestNode(e.getPoint(), OsmPrimitive.isSelectablePredicate);
         if (result.nearestNode == null) {
-            result.nearestSegment = Main.map.mapView.getNearestWaySegment(e.getPoint());
+            result.nearestSegment = Main.map.mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive.isSelectablePredicate);
             if (result.nearestSegment != null) {
                 if (shift) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 3177)
@@ -164,5 +164,5 @@
         if (mouseOnExistingNode == null && getCurrentDataSet().getSelected().size() == 0
                 && mousePos != null) {
-            mouseOnExistingNode = Main.map.mapView.getNearestNode(mousePos);
+            mouseOnExistingNode = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
         }
 
@@ -332,5 +332,5 @@
 
         if (!ctrl) {
-            n = Main.map.mapView.getNearestNode(mousePos);
+            n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
         }
 
@@ -366,5 +366,5 @@
             if (!ctrl) {
                 // Insert the node into all the nearby way segments
-                List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint());
+                List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint(), OsmPrimitive.isSelectablePredicate);
                 Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
                 for (WaySegment ws : wss) {
@@ -681,5 +681,5 @@
 
         if (!ctrl && mousePos != null) {
-            currentMouseNode = mv.getNearestNode(mousePos);
+            currentMouseNode = mv.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
         }
 
@@ -687,5 +687,5 @@
         // *and* there is no node nearby (because nodes beat ways when re-using)
         if(!ctrl && currentMouseNode == null) {
-            List<WaySegment> wss = mv.getNearestWaySegments(mousePos);
+            List<WaySegment> wss = mv.getNearestWaySegments(mousePos, OsmPrimitive.isSelectablePredicate);
             for(WaySegment ws : wss) {
                 mouseOnExistingWays.add(ws.way);
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 3177)
@@ -308,5 +308,5 @@
         // boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
 
-        selectedSegment = Main.map.mapView.getNearestWaySegment(e.getPoint());
+        selectedSegment = Main.map.mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive.isSelectablePredicate);
 
         if (selectedSegment == null) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 3177)
@@ -285,5 +285,5 @@
         int snapDistance = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8);
         snapDistance *= snapDistance;
-        OsmPrimitive osm = c.getNearestNode(p);
+        OsmPrimitive osm = c.getNearestNode(p, OsmPrimitive.isSelectablePredicate);
         virtualWays.clear();
         virtualNode = null;
@@ -293,6 +293,6 @@
         {
             Collection<WaySegment> nearestWaySegs = allSegements
-            ? c.getNearestWaySegments(p)
-                    : Collections.singleton(c.getNearestWaySegment(p));
+            ? c.getNearestWaySegments(p, OsmPrimitive.isSelectablePredicate)
+                    : Collections.singleton(c.getNearestWaySegment(p, OsmPrimitive.isSelectablePredicate));
 
             for(WaySegment nearestWS : nearestWaySegs) {
@@ -435,5 +435,5 @@
             if (!didMove) {
                 selectPrims(
-                        Main.map.mapView.getNearestCollection(e.getPoint()),
+                        Main.map.mapView.getNearestCollection(e.getPoint(), OsmPrimitive.isSelectablePredicate),
                         shift, ctrl, true, false);
 
@@ -485,5 +485,5 @@
                 if (ctrl) {
                     Collection<Node> affectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
-                    Collection<Node> nn = Main.map.mapView.getNearestNodes(e.getPoint(), affectedNodes);
+                    Collection<Node> nn = Main.map.mapView.getNearestNodes(e.getPoint(), affectedNodes, OsmPrimitive.isSelectablePredicate);
                     if (nn != null) {
                         Node targetNode = nn.iterator().next();
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 3177)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.ChangesetIdChangedEvent;
@@ -174,20 +175,17 @@
      */
     public Collection<OsmPrimitive> allNonDeletedPrimitives() {
-        return new DatasetCollection.AllNonDeleted(allPrimitives);
+        return new DatasetCollection(allPrimitives, OsmPrimitive.nonDeletedPredicate);
     }
 
     public Collection<OsmPrimitive> allNonDeletedCompletePrimitives() {
-        return new DatasetCollection.AllNonDeletedComplete(allPrimitives);
+        return new DatasetCollection(allPrimitives, OsmPrimitive.nonDeletedCompletePredicate);
     }
 
     public Collection<OsmPrimitive> allNonDeletedPhysicalPrimitives() {
-        return new DatasetCollection.AllNonDeletedPhysical(allPrimitives);
-    }
-
-    /**
-     * @return A collection containing all modified primitives
-     */
+        return new DatasetCollection(allPrimitives, OsmPrimitive.nonDeletedPhysicalPredicate);
+    }
+
     public Collection<OsmPrimitive> allModifiedPrimitives() {
-        return new DatasetCollection.AllModified(allPrimitives);
+        return new DatasetCollection(allPrimitives, OsmPrimitive.modifiedPredicate);
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/data/osm/DatasetCollection.java	(revision 3177)
@@ -6,5 +6,7 @@
 import java.util.Iterator;
 
-abstract class DatasetCollection extends AbstractCollection<OsmPrimitive> {
+import org.openstreetmap.josm.tools.Predicate;
+
+class DatasetCollection extends AbstractCollection<OsmPrimitive> {
 
     private class FilterIterator implements Iterator<OsmPrimitive> {
@@ -21,5 +23,5 @@
                 while (iterator.hasNext()) {
                     current = iterator.next();
-                    if (filter(current))
+                    if (predicate.evaluate(current))
                         return;
                 }
@@ -46,10 +48,10 @@
 
     private final Collection<OsmPrimitive> primitives;
+    private final Predicate<OsmPrimitive> predicate;
 
-    public DatasetCollection(Collection<OsmPrimitive> primitives) {
+    public DatasetCollection(Collection<OsmPrimitive> primitives, Predicate<OsmPrimitive> predicate) {
         this.primitives = primitives;
+        this.predicate = predicate;
     }
-
-    protected abstract boolean filter(OsmPrimitive primitive);
 
     @Override
@@ -73,56 +75,3 @@
         return !iterator().hasNext();
     }
-
-    public static class AllNonDeleted extends DatasetCollection {
-
-        public AllNonDeleted(Collection<OsmPrimitive> primitives) {
-            super(primitives);
-        }
-
-        @Override
-        protected boolean filter(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted();
-        }
-
-    }
-
-    public static class AllNonDeletedComplete extends DatasetCollection {
-
-        public AllNonDeletedComplete(Collection<OsmPrimitive> primitives) {
-            super(primitives);
-        }
-
-        @Override
-        protected boolean filter(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete();
-        }
-
-    }
-
-    public static class AllNonDeletedPhysical extends DatasetCollection {
-
-        public AllNonDeletedPhysical(Collection<OsmPrimitive> primitives) {
-            super(primitives);
-        }
-
-        @Override
-        protected boolean filter(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof Relation);
-        }
-
-    }
-
-    public static class AllModified extends DatasetCollection {
-
-        public AllModified(Collection<OsmPrimitive> primitives) {
-            super(primitives);
-        }
-
-        @Override
-        protected boolean filter(OsmPrimitive primitive) {
-            return primitive.isVisible() && primitive.isModified();
-        }
-
-    }
-
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3177)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Predicate;
 
 /**
@@ -47,13 +48,72 @@
     }
 
+    /**
+     * This flag shows, that the properties have been changed by the user
+     * and on upload the object will be send to the server
+     */
     private static final int FLAG_MODIFIED = 1 << 0;
+
+    /**
+     * The visible flag indicates, that an object is marked
+     * as deleted on the server.
+     */
     private static final int FLAG_VISIBLE  = 1 << 1;
+
+    /**
+     * An object can be disabled by the filter mechanism.
+     * Then it will show in a shade of grey on the map.
+     * Disabled objects usually cannot be selected or modified
+     * while the filter is active.
+     */
     private static final int FLAG_DISABLED = 1 << 2;
+
+    /**
+     * An object that was deleted by the user.
+     * Deleted objects are usually hidden on the map and a request
+     * for deletion will be send to the server on upload.
+     * An object usually cannot be deleted if it has non-deleted
+     * objects still referring to it.
+     */
     private static final int FLAG_DELETED  = 1 << 3;
+
+    /**
+     * An object can be filtered by the filter mechanism.
+     * Then it will be hidden on the map and usually
+     * cannot be selected or modified while the filter is active.
+     */
     private static final int FLAG_FILTERED = 1 << 4;
+
+    /**
+     * This flag is set if the primitive is a way and
+     * according to the tags, the direction of the way is important.
+     * (e.g. one way street.)
+     */
     private static final int FLAG_HAS_DIRECTIONS = 1 << 5;
+
+    /**
+     * If the primitive is tagged.
+     * Some trivial tags like source=* are ignored here.
+     */
     private static final int FLAG_TAGGED = 1 << 6;
+
+    /**
+     * This flag is only relevant if FLAG_HAS_DIRECTIONS is set.
+     * It shows, that direction of the arrows should be reversed.
+     * (E.g. oneway=-1.)
+     */
     private static final int FLAG_DIRECTION_REVERSED = 1 << 7;
+
+    /**
+     * When hovering over ways and nodes in add mode, the
+     * "target" objects are visually highlighted. This flag indicates
+     * that the primitive is currently highlighted.
+     */
     private static final int FLAG_HIGHLIGHTED = 1 << 8;
+
+    /**
+     * A primitive is incomplete if we know its id and type, but nothing more.
+     * Typically some members of a relation are incomplete until they are
+     * fetched from the server.
+     */
     private static final int FLAG_INCOMPLETE = 1 << 9;
 
@@ -329,5 +389,9 @@
      */
     public boolean isUsable() {
-        return (flags & (FLAG_DELETED + FLAG_INCOMPLETE + FLAG_DISABLED)) == 0;
+        return (flags & (FLAG_DELETED + FLAG_INCOMPLETE)) == 0;
+    }
+
+    public boolean isSelectable() {
+        return (flags & (FLAG_DELETED + FLAG_INCOMPLETE + FLAG_DISABLED + FLAG_FILTERED)) == 0;
     }
 
@@ -335,4 +399,43 @@
         return (flags & (FLAG_DELETED + FLAG_INCOMPLETE + FLAG_FILTERED)) == 0;
     }
+
+    /**
+     * Some predicates, that describe conditions on primitives.
+     */
+    public static Predicate<OsmPrimitive> isUsablePredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isUsable();
+        }
+    };
+
+    public static Predicate<OsmPrimitive> isSelectablePredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isSelectable();
+        }
+    };
+
+    public static Predicate<OsmPrimitive> nonDeletedPredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted();
+        }
+    };
+
+    public static Predicate<OsmPrimitive> nonDeletedCompletePredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete();
+        }
+    };
+
+    public static Predicate<OsmPrimitive> nonDeletedPhysicalPredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof Relation);
+        }
+    };
+
+    public static Predicate<OsmPrimitive> modifiedPredicate = new Predicate<OsmPrimitive>() {
+        public boolean evaluate(OsmPrimitive primitive) {
+            return primitive.isVisible() && primitive.isModified();
+        }
+    };
 
     /**
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 3177)
@@ -193,5 +193,5 @@
                         if (middleMouseDown || isAtOldPosition)
                         {
-                            Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
+                            Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive.isUsablePredicate);
 
                             if (osms == null) {
@@ -292,5 +292,5 @@
          */
         private final void statusBarElementUpdate(MouseState ms) {
-            final OsmPrimitive osmNearest = mv.getNearest(ms.mousePos);
+            final OsmPrimitive osmNearest = mv.getNearest(ms.mousePos, OsmPrimitive.isUsablePredicate);
             if (osmNearest != null) {
                 nameText.setText(osmNearest.getDisplayName(DefaultNameFormatter.getInstance()));
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 3177)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.help.Helpful;
+import org.openstreetmap.josm.tools.Predicate;
 
 /**
@@ -426,9 +427,18 @@
     }
 
-    /**
-     * Return the nearest point to the screen point given.
-     * If a node within snapDistance pixel is found, the nearest node is returned.
-     */
+    @Deprecated
     public final Node getNearestNode(Point p) {
+        return getNearestNode(p, OsmPrimitive.isUsablePredicate);
+    }
+
+    /**
+     * Return the nearest node to the screen point given.
+     * If more then one node within snapDistance pixel is found,
+     * the nearest node is returned.
+     * @param p the screen point
+     * @param predicate this parameter imposes a condition on the returned object, e.g.
+     *        give the nearest node that is tagged.
+     */
+    public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate) {
         DataSet ds = getCurrentDataSet();
         if (ds == null)
@@ -438,7 +448,6 @@
         Node minPrimitive = null;
         for (Node n : ds.searchNodes(getSnapDistanceBBox(p))) {
-            if (!n.isUsable()) {
+            if (! predicate.evaluate(n))
                 continue;
-            }
             Point sp = getPoint(n);
             double dist = p.distanceSq(sp);
@@ -462,6 +471,7 @@
      *
      * @param p the point for which to search the nearest segment.
-     */
-    public final List<WaySegment> getNearestWaySegments(Point p) {
+     * @param predicate the returned objects have to fulfill certain properties.
+     */
+    public final List<WaySegment> getNearestWaySegments(Point p, Predicate<OsmPrimitive> predicate) {
         TreeMap<Double, List<WaySegment>> nearest = new TreeMap<Double, List<WaySegment>>();
         DataSet ds = getCurrentDataSet();
@@ -470,12 +480,11 @@
 
         for (Way w : ds.searchWays(getSnapDistanceBBox(p))) {
-            if (!w.isUsable()) {
+            if (!predicate.evaluate(w))
                 continue;
-            }
             Node lastN = null;
             int i = -2;
             for (Node n : w.getNodes()) {
                 i++;
-                if (n.isDeleted() || n.isIncomplete()) {
+                if (n.isDeleted() || n.isIncomplete()) {//FIXME: This shouldn't happen, raise exception?
                     continue;
                 }
@@ -521,8 +530,10 @@
      * @param p the point for which to search the nearest segment.
      * @param ignore a collection of segments which are not to be returned.
+     * @param predicate the returned object has to fulfill certain properties.
      * May be null.
      */
-    public final WaySegment getNearestWaySegment(Point p, Collection<WaySegment> ignore) {
-        List<WaySegment> nearest = getNearestWaySegments(p);
+    public final WaySegment getNearestWaySegment
+                                    (Point p, Collection<WaySegment> ignore, Predicate<OsmPrimitive> predicate) {
+        List<WaySegment> nearest = getNearestWaySegments(p, predicate);
         if(nearest == null)
             return null;
@@ -536,6 +547,11 @@
      * @return the nearest way segment to the screen point given.
      */
-    public final WaySegment getNearestWaySegment(Point p) {
-        return getNearestWaySegment(p, null);
+    public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate) {
+        return getNearestWaySegment(p, null, predicate);
+    }
+
+    @Deprecated
+    public final Way getNearestWay(Point p) {
+        return getNearestWay(p, OsmPrimitive.isUsablePredicate);
     }
 
@@ -543,6 +559,6 @@
      * @return the nearest way to the screen point given.
      */
-    public final Way getNearestWay(Point p) {
-        WaySegment nearestWaySeg = getNearestWaySegment(p);
+    public final Way getNearestWay(Point p, Predicate<OsmPrimitive> predicate) {
+        WaySegment nearestWaySeg = getNearestWaySegment(p, predicate);
         return nearestWaySeg == null ? null : nearestWaySeg.way;
     }
@@ -559,11 +575,12 @@
      *
      * @param p The point on screen.
+     * @param predicate the returned object has to fulfill certain properties.
      * @return  The primitive that is nearest to the point p.
      */
-    public OsmPrimitive getNearest(Point p) {
-        OsmPrimitive osm = getNearestNode(p);
+    public OsmPrimitive getNearest(Point p, Predicate<OsmPrimitive> predicate) {
+        OsmPrimitive osm = getNearestNode(p, predicate);
         if (osm == null)
         {
-            osm = getNearestWay(p);
+            osm = getNearestWay(p, predicate);
         }
         return osm;
@@ -573,6 +590,6 @@
      * Returns a singleton of the nearest object, or else an empty collection.
      */
-    public Collection<OsmPrimitive> getNearestCollection(Point p) {
-        OsmPrimitive osm = getNearest(p);
+    public Collection<OsmPrimitive> getNearestCollection(Point p, Predicate<OsmPrimitive> predicate) {
+        OsmPrimitive osm = getNearest(p, predicate);
         if (osm == null)
             return Collections.emptySet();
@@ -588,5 +605,5 @@
      *      list is never empty.
      */
-    public Collection<OsmPrimitive> getAllNearest(Point p) {
+    public Collection<OsmPrimitive> getAllNearest(Point p, Predicate<OsmPrimitive> predicate) {
         Collection<OsmPrimitive> nearest = new HashSet<OsmPrimitive>();
         DataSet ds = getCurrentDataSet();
@@ -594,12 +611,10 @@
             return null;
         for (Way w : ds.searchWays(getSnapDistanceBBox(p))) {
-            if (!w.isUsable()) {
+            if (!predicate.evaluate(w))
                 continue;
-            }
             Node lastN = null;
             for (Node n : w.getNodes()) {
-                if (!n.isUsable()) {
+                if (!predicate.evaluate(n))
                     continue;
-                }
                 if (lastN == null) {
                     lastN = n;
@@ -636,5 +651,5 @@
      *      list is never empty.
      */
-    public Collection<Node> getNearestNodes(Point p) {
+    public Collection<Node> getNearestNodes(Point p, Predicate<OsmPrimitive> predicate) {
         Collection<Node> nearest = new HashSet<Node>();
         DataSet ds = getCurrentDataSet();
@@ -643,6 +658,7 @@
 
         for (Node n : ds.searchNodes(getSnapDistanceBBox(p))) {
-            if (n.isUsable()
-                    && getPoint(n).distanceSq(p) < snapDistanceSq) {
+            if (!predicate.evaluate(n))
+                continue;
+            if (getPoint(n).distanceSq(p) < snapDistanceSq) {
                 nearest.add(n);
             }
@@ -657,8 +673,9 @@
      * @param p the point for which to search the nearest segment.
      * @param ignore a collection of nodes which are not to be returned.
+     * @param predicate the returned objects have to fulfill certain properties.
      * May be null.
      */
-    public final Collection<Node> getNearestNodes(Point p, Collection<Node> ignore) {
-        Collection<Node> nearest = getNearestNodes(p);
+    public final Collection<Node> getNearestNodes(Point p, Collection<Node> ignore, Predicate<OsmPrimitive> predicate) {
+        Collection<Node> nearest = getNearestNodes(p, predicate);
         if (nearest == null) return null;
         if (ignore != null) {
Index: trunk/src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 3176)
+++ trunk/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 3177)
@@ -277,5 +277,5 @@
 
         if (clicked) {
-            OsmPrimitive osm = nc.getNearest(center);
+            OsmPrimitive osm = nc.getNearest(center, OsmPrimitive.isSelectablePredicate);
             if (osm != null) {
                 selection.add(osm);
Index: trunk/src/org/openstreetmap/josm/tools/Predicate.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Predicate.java	(revision 3177)
+++ trunk/src/org/openstreetmap/josm/tools/Predicate.java	(revision 3177)
@@ -0,0 +1,8 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+// Used to identify objects that fulfill a certain condition, e.g. when filtering a collection
+public interface Predicate<T> {
+    // @return whether the object passes the test or not
+    public boolean evaluate(T object);
+}
