Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 10039)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 10040)
@@ -48,4 +48,5 @@
 import org.openstreetmap.josm.tools.FilteredCollection;
 import org.openstreetmap.josm.tools.Predicate;
+import org.openstreetmap.josm.tools.Predicates;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
@@ -264,5 +265,5 @@
     private final QuadBuckets<Node> nodes = new QuadBuckets<>();
 
-    private <T extends OsmPrimitive> Collection<T> getPrimitives(Predicate<OsmPrimitive> predicate) {
+    private <T extends OsmPrimitive> Collection<T> getPrimitives(Predicate<? super OsmPrimitive> predicate) {
         return new SubclassFilteredCollection<>(allPrimitives, predicate);
     }
@@ -402,5 +403,5 @@
      */
     public Collection<OsmPrimitive> allPrimitives() {
-        return getPrimitives(OsmPrimitive.allPredicate);
+        return getPrimitives(Predicates.alwaysTrue());
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 10039)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 10040)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Predicate;
+import org.openstreetmap.josm.tools.Predicates;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
@@ -171,5 +172,6 @@
 
     /**
-     * Some predicates, that describe conditions on primitives.
+     * A predicate that filters primitives that are usable.
+     * @see OsmPrimitive#isUsable()
      */
     public static final Predicate<OsmPrimitive> isUsablePredicate = new Predicate<OsmPrimitive>() {
@@ -180,4 +182,7 @@
     };
 
+    /**
+     * A predicate filtering primitives that are selectable.
+     */
     public static final Predicate<OsmPrimitive> isSelectablePredicate = new Predicate<OsmPrimitive>() {
         @Override
@@ -187,4 +192,7 @@
     };
 
+    /**
+     * A predicate filtering primitives that are not deleted.
+     */
     public static final Predicate<OsmPrimitive> nonDeletedPredicate = new Predicate<OsmPrimitive>() {
         @Override public boolean evaluate(OsmPrimitive primitive) {
@@ -193,4 +201,7 @@
     };
 
+    /**
+     * A predicate filtering primitives that are not deleted and not incomplete.
+     */
     public static final Predicate<OsmPrimitive> nonDeletedCompletePredicate = new Predicate<OsmPrimitive>() {
         @Override public boolean evaluate(OsmPrimitive primitive) {
@@ -199,4 +210,7 @@
     };
 
+    /**
+     * A predicate filtering primitives that are not deleted and not incomplete and that are not a relation.
+     */
     public static final Predicate<OsmPrimitive> nonDeletedPhysicalPredicate = new Predicate<OsmPrimitive>() {
         @Override public boolean evaluate(OsmPrimitive primitive) {
@@ -205,4 +219,7 @@
     };
 
+    /**
+     * A predicate filtering primitives that are modified
+     */
     public static final Predicate<OsmPrimitive> modifiedPredicate = new Predicate<OsmPrimitive>() {
         @Override public boolean evaluate(OsmPrimitive primitive) {
@@ -211,22 +228,22 @@
     };
 
-    public static final Predicate<OsmPrimitive> nodePredicate = new Predicate<OsmPrimitive>() {
-        @Override public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.getClass() == Node.class;
-        }
-    };
-
-    public static final Predicate<OsmPrimitive> wayPredicate = new Predicate<OsmPrimitive>() {
-        @Override public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.getClass() == Way.class;
-        }
-    };
-
-    public static final Predicate<OsmPrimitive> relationPredicate = new Predicate<OsmPrimitive>() {
-        @Override public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.getClass() == Relation.class;
-        }
-    };
-
+    /**
+     * A predicate filtering nodes.
+     */
+    public static final Predicate<OsmPrimitive> nodePredicate = Predicates.<OsmPrimitive>isOfClass(Node.class);
+
+    /**
+     * A predicate filtering ways.
+     */
+    public static final Predicate<OsmPrimitive> wayPredicate = Predicates.<OsmPrimitive>isOfClass(Way.class);
+
+    /**
+     * A predicate filtering relations.
+     */
+    public static final Predicate<OsmPrimitive> relationPredicate = Predicates.<OsmPrimitive>isOfClass(Relation.class);
+
+    /**
+     * A predicate filtering multipolygon relations.
+     */
     public static final Predicate<OsmPrimitive> multipolygonPredicate = new Predicate<OsmPrimitive>() {
         @Override public boolean evaluate(OsmPrimitive primitive) {
@@ -235,10 +252,9 @@
     };
 
-    public static final Predicate<OsmPrimitive> allPredicate = new Predicate<OsmPrimitive>() {
-        @Override public boolean evaluate(OsmPrimitive primitive) {
-            return true;
-        }
-    };
-
+    /**
+     * This matches all ways that have a direction
+     *
+     * @see #FLAG_HAS_DIRECTIONS
+     */
     public static final Predicate<Tag> directionalKeyPredicate = new Predicate<Tag>() {
         @Override
@@ -677,4 +693,8 @@
     }
 
+    /**
+     * Updates the highlight flag for this primitive.
+     * @param highlighted The new highlight flag.
+     */
     public void setHighlighted(boolean highlighted) {
         if (isHighlighted() != highlighted) {
@@ -686,4 +706,8 @@
     }
 
+    /**
+     * Checks if the highlight flag for this primitive was set
+     * @return The highlight flag.
+     */
     public boolean isHighlighted() {
         return (flags & FLAG_HIGHLIGHTED) != 0;
@@ -820,12 +844,18 @@
     }
 
+    /**
+     * A tagged way that matches this pattern has a direction.
+     * @see #FLAG_HAS_DIRECTIONS
+     */
     private static volatile Match directionKeys;
+
+    /**
+     * A tagged way that matches this pattern has a direction that is reversed.
+     * <p>
+     * This pattern should be a subset of {@link #directionKeys}
+     * @see #FLAG_DIRECTION_REVERSED
+     */
     private static volatile Match reversedDirectionKeys;
 
-    /**
-     * Contains a list of direction-dependent keys that make an object
-     * direction dependent.
-     * Initialized by checkDirectionTagged()
-     */
     static {
         String reversedDirectionDefault = "oneway=\"-1\"";
@@ -837,25 +867,19 @@
                 "(highway=motorway_link & -oneway=no & -oneway=reversible)";
 
-        try {
-            reversedDirectionKeys = SearchCompiler.compile(Main.pref.get("tags.reversed_direction", reversedDirectionDefault));
+        reversedDirectionKeys = compileDirectionKeys("tags.reversed_direction", reversedDirectionDefault);
+        directionKeys = compileDirectionKeys("tags.direction", directionDefault);
+    }
+
+    private static Match compileDirectionKeys(String prefName, String defaultValue) throws AssertionError {
+        try {
+            return SearchCompiler.compile(Main.pref.get(prefName, defaultValue));
         } catch (ParseError e) {
-            Main.error("Unable to compile pattern for tags.reversed_direction, trying default pattern: " + e.getMessage());
-
-            try {
-                reversedDirectionKeys = SearchCompiler.compile(reversedDirectionDefault);
-            } catch (ParseError e2) {
-                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage(), e2);
-            }
-        }
-        try {
-            directionKeys = SearchCompiler.compile(Main.pref.get("tags.direction", directionDefault));
-        } catch (ParseError e) {
-            Main.error("Unable to compile pattern for tags.direction, trying default pattern: " + e.getMessage());
-
-            try {
-                directionKeys = SearchCompiler.compile(directionDefault);
-            } catch (ParseError e2) {
-                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage(), e2);
-            }
+            Main.error("Unable to compile pattern for " + prefName + ", trying default pattern: " + e.getMessage());
+        }
+
+        try {
+            return SearchCompiler.compile(defaultValue);
+        } catch (ParseError e2) {
+            throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage(), e2);
         }
     }
Index: trunk/src/org/openstreetmap/josm/tools/Predicates.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Predicates.java	(revision 10039)
+++ trunk/src/org/openstreetmap/josm/tools/Predicates.java	(revision 10040)
@@ -14,4 +14,34 @@
 
     private Predicates() {
+    }
+
+    /**
+     * Creates a predicate that returns true every time.
+     * @param <T> The type of the predicate.
+     * @return A predicate returning <code>true</code>
+     * @since 10040
+     */
+    public static <T> Predicate<T> alwaysTrue() {
+        return new Predicate<T>() {
+            @Override
+            public boolean evaluate(T object) {
+                return true;
+            }
+        };
+    }
+
+    /**
+     * Creates a predicate that returns false every time.
+     * @param <T> The type of the predicate.
+     * @return A predicate returning <code>false</code>
+     * @since 10040
+     */
+    public static <T> Predicate<T> alwaysFalse() {
+        return new Predicate<T>() {
+            @Override
+            public boolean evaluate(T object) {
+                return false;
+            }
+        };
     }
 
@@ -42,4 +72,19 @@
             public boolean evaluate(T obj) {
                 return Objects.equals(obj, ref);
+            }
+        };
+    }
+
+    /**
+     * Creates a new predicate that checks if elements are exactly of that class.
+     * @param <T> The predicate type.
+     * @param clazz The class the elements must have.
+     * @return A predicate.
+     */
+    public static <T> Predicate<T> isOfClass(final Class<? extends T> clazz) {
+        return new Predicate<T>() {
+            @Override
+            public boolean evaluate(T obj) {
+                return obj != null && obj.getClass() == clazz;
             }
         };
