Index: trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java	(revision 5422)
+++ trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java	(revision 5423)
@@ -6,10 +6,41 @@
 import java.util.List;
 
+import org.openstreetmap.josm.actions.search.SearchAction.SearchMode;
 import org.openstreetmap.josm.actions.search.SearchCompiler;
-import org.openstreetmap.josm.actions.search.SearchAction.SearchMode;
 import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
 import org.openstreetmap.josm.actions.search.SearchCompiler.Not;
 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
 
+/**
+ * Class that encapsulates the filter logic, i.e.&nbsp;applies a list of
+ * filters to a primitive.
+ *
+ * Uses {@link SearchCompiler.Match#match} to see if the filter expression matches,
+ * cares for "inverted-flag" of the filters and combines the results of all active
+ * filters.
+ *
+ * There are two major use cases:
+ *
+ * (1) Hide features that you don't like to edit but get in the way, e.g.
+ * <code>landuse</code> or power lines. It is expected, that the inverted flag
+ * if false for these kind of filters.
+ *
+ * (2) Highlight certain features, that are currently interesting and hide everything
+ * else. This can be thought of as an improved search (Ctrl-F), where you can
+ * continue editing and don't loose the current selection. It is expected that
+ * the inverted flag of the filter is true in this case.
+ *
+ * In addition to the formal application of filter rules, some magic is applied
+ * to (hopefully) match the expectations of the user:
+ *
+ * (1) non-inverted: When hiding a way, all its untagged nodes are hidden as well.
+ * This avoids a "cloud of nodes", that normally isn't useful without the
+ * corresponding way.
+ *
+ * (2) inverted: When displaying a way, we show all its nodes, although the
+ * individual nodes do not match the filter expression. The reason is, that a
+ * way without its nodes cannot be edited properly.
+ *
+ */
 public class FilterMatcher {
 
@@ -106,20 +137,34 @@
 
         boolean selected = false;
-        boolean onlyInvertedFilters = true;
+        // If the primitive is "explicitly" hidden by a non-inverted filter.
+        // Only interesting for nodes.
+        boolean explicitlyHidden = false;
 
         for (FilterInfo fi: filters) {
-            if (fi.isDelete && selected && fi.match.match(primitive)) {
-                selected = false;
-            } else if (!fi.isDelete && (!selected || (onlyInvertedFilters && !fi.isInverted)) && fi.match.match(primitive)) {
-                selected = true;
-                onlyInvertedFilters = onlyInvertedFilters && fi.isInverted;
+            if (fi.isDelete) {
+                if (selected && fi.match.match(primitive)) {
+                    selected = false;
+                }
+            } else {
+                if ((!selected || (!explicitlyHidden && !fi.isInverted)) && fi.match.match(primitive)) {
+                    selected = true;
+                    if (!fi.isInverted) {
+                        explicitlyHidden = true;
+                    }
+                }
             }
         }
 
         if (primitive instanceof Node) {
+            // Technically not hidden by any filter, but we hide it anyway, if
+            // it is untagged and all parent ways are hidden.
             if (!selected)
                 return !primitive.isTagged() && allParentWaysFiltered(primitive, hidden);
-            if (onlyInvertedFilters)
-                return selected && !oneParentWayNotFiltered(primitive, hidden);
+            // At this point, selected == true, so the node is hidden.
+            // However, if there is a parent way, that is not hidden, we ignore
+            // this and show the node anyway, unless there is no non-inverted
+            // filter that applies to the node directly.
+            if (!explicitlyHidden)
+                return !oneParentWayNotFiltered(primitive, hidden);
             return true;
         } else
Index: trunk/src/org/openstreetmap/josm/data/osm/FilterWorker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/FilterWorker.java	(revision 5422)
+++ trunk/src/org/openstreetmap/josm/data/osm/FilterWorker.java	(revision 5423)
@@ -12,24 +12,8 @@
      * Apply the filters to the primitives of the data set.
      *
-     * There are certain rules to ensure that a way is not displayed "naked"
-     * without its nodes (1) and on the other hand to avoid hiding a way but
-     * leaving its nodes visible as a cloud of points (2).
-     *
-     * In normal (non-inverted) mode only problem (2) is relevant.
-     * Untagged child nodes of filtered ways that are not used by other
-     * unfiltered ways are filtered as well.
-     *
-     * If a filter applies explicitly to a node, (2) is ignored and it
-     * is filtered in any case.
-     *
-     * In inverted mode usually only problem (1) is relevant.
-     * If the inverted filter applies explicitly to a node, this no longer
-     * means it is filtered in any case:
-     * E.g. the filter [searchtext="highway=footway", inverted=true] displays
-     * the footways only. But that does not mean, the nodes of the footway
-     * (which do not have the highway tag) should be filtered as well.
-     *
-     * So first the Filter is applied for ways and relations. Then to nodes
-     * (but hides them only if they are not used by any unfiltered way).
+     * @param all the collection of primitives for that the filter state should
+     * be updated
+     * @param filterMatcher the FilterMatcher
+     * @return true, if the filter state of any primitive has changed in the process
      */
     public static boolean executeFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 5422)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 5423)
@@ -428,8 +428,11 @@
 
     /**
-     * Make the primitive disabled (e.g. if a filter applies).
+     * Make the primitive disabled (e.g.&nbsp;if a filter applies).
+     *
      * To enable the primitive again, use unsetDisabledState.
      * @param hide if the primitive should be completely hidden from view or
      *             just shown in gray color.
+     * @return true, any flag has changed; false if you try to set the disabled
+     * state to the value that is already preset
      */
     public boolean setDisabledState(boolean hide) {
