Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 4074)
@@ -17,6 +17,6 @@
 import java.util.Locale;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
-import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -1302,6 +1302,29 @@
             }
         }
-
         return result;
+    }
+
+    /**
+     * <p>Visits {@code visitor} for all referrers.</p>
+     * 
+     * @param visitor the visitor. Ignored, if null.
+     */
+    public void visitReferrers(Visitor visitor){
+        if (visitor == null) return;
+        if (this.referrers == null)
+            return;
+        else if (this.referrers instanceof OsmPrimitive) {
+            OsmPrimitive ref = (OsmPrimitive) this.referrers;
+            if (ref.dataSet == dataSet) {
+                ref.visit(visitor);
+            }
+        } else if (this.referrers instanceof OsmPrimitive[]) {
+            OsmPrimitive[] refs = (OsmPrimitive[]) this.referrers;
+            for (OsmPrimitive ref: refs) {
+                if (ref.dataSet == dataSet) {
+                    ref.visit(visitor);
+                }
+            }
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 4074)
@@ -6,5 +6,4 @@
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
@@ -24,5 +23,4 @@
 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle;
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
-import org.openstreetmap.josm.tools.Pair;
 
 public class MapPaintVisitor implements PaintVisitor {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 4074)
@@ -84,7 +84,5 @@
     private Pair<StyleList, Range> getImpl(OsmPrimitive osm, double scale, NavigatableComponent nc) {
         if (osm instanceof Node)
-        {
             return generateStyles(osm, scale, null, false);
-        }
         else if (osm instanceof Way)
         {
@@ -235,6 +233,7 @@
 
         for (Entry<String, Cascade> e : mc.getLayers()) {
-            if ("*".equals(e.getKey()))
+            if ("*".equals(e.getKey())) {
                 continue;
+            }
             env.layer = e.getKey();
             Cascade c = e.getValue();
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java	(revision 4074)
@@ -114,4 +114,6 @@
      * @param c the style properties
      * @param defaultTextColor the default text color. Must not be null.
+     * @param defaultAnnotate true, if a text label shall be rendered by default, even if the style sheet
+     *   doesn't include respective style declarations
      * @return the text element or null, if the style properties don't include
      * properties for text rendering
@@ -212,10 +214,10 @@
         final TextElement other = (TextElement) obj;
         return  equal(labelCompositionStrategy, other.labelCompositionStrategy) &&
-                equal(font, other.font) &&
-                xOffset == other.xOffset &&
-                yOffset == other.yOffset &&
-                equal(color, other.color) &&
-                equal(haloRadius, other.haloRadius) &&
-                equal(haloColor, other.haloColor);
+        equal(font, other.font) &&
+        xOffset == other.xOffset &&
+        yOffset == other.yOffset &&
+        equal(color, other.color) &&
+        equal(haloRadius, other.haloRadius) &&
+        equal(haloColor, other.haloColor);
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java	(revision 4074)
@@ -4,4 +4,5 @@
 import java.util.List;
 
+import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -16,4 +17,15 @@
     }
 
+    /**
+     * <p>Executes the instructions against the environment {@code env}</p>
+     * 
+     * @param env the environment
+     */
+    public void execute(Environment env) {
+        for (Instruction i : declaration) {
+            i.execute(env);
+        }
+    }
+
     @Override
     public String toString() {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 4074)
@@ -134,12 +134,9 @@
                 if ((s instanceof GeneralSelector)) {
                     GeneralSelector gs = (GeneralSelector) s;
-                    if (gs.base.equals(type)) {
-                        for (Condition cnd : gs.conds) {
-                            if (!cnd.applies(env))
-                                continue NEXT_RULE;
+                    if (gs.getBase().equals(type)) {
+                        if (!gs.matchesConditions(env)) {
+                            continue NEXT_RULE;
                         }
-                        for (Instruction i : r.declaration) {
-                            i.execute(env);
-                        }
+                        r.execute(env);
                     }
                 }
@@ -179,13 +176,9 @@
                                 continue;
                             }
-                            for (Instruction i : r.declaration) {
-                                i.execute(env);
-                            }
+                            r.execute(env);
                         }
                     }
                     env.layer = sub;
-                    for (Instruction i : r.declaration) {
-                        i.execute(env);
-                    }
+                    r.execute(env);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 4073)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 4074)
@@ -10,4 +10,5 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
 import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.gui.mappaint.Range;
@@ -67,4 +68,77 @@
         }
 
+        /**
+         * <p>Finds the first referrer matching {@link #left}</p>
+         * 
+         * <p>The visitor works on an environment and it saves the matching
+         * referrer in {@code e.parent} and its relative position in the
+         * list referrers "child list" in {@code e.index}.</p>
+         * 
+         * <p>If after execution {@code e.parent} is null, no matching
+         * referrer was found.</p>
+         *
+         */
+        private  class MatchingReferrerFinder extends AbstractVisitor{
+            private Environment e;
+
+            /**
+             * Constructor
+             * @param e the environment against which we match
+             */
+            public MatchingReferrerFinder(Environment e){
+                this.e = e;
+            }
+
+            @Override
+            public void visit(Node n) {
+                // node should never be a referrer
+                throw new AssertionError();
+            }
+
+            @Override
+            public void visit(Way w) {
+                /*
+                 * If e.parent is already set to the first matching referrer. We skip any following
+                 * referrer injected into the visitor.
+                 */
+                if (e.parent != null) return;
+
+                if (!left.matches(e.withPrimitive(w)))
+                    return;
+                for (int i=0; i<w.getNodesCount(); i++) {
+                    Node n = w.getNode(i);
+                    if (n.equals(e.osm)) {
+                        if (link.matches(e.withParent(w).withIndex(i).withLinkContext())) {
+                            e.parent = w;
+                            e.index = i;
+                            return;
+                        }
+                    }
+                }
+            }
+
+            @Override
+            public void visit(Relation r) {
+                /*
+                 * If e.parent is already set to the first matching referrer. We skip any following
+                 * referrer injected into the visitor.
+                 */
+                if (e.parent != null) return;
+
+                if (!left.matches(e.withPrimitive(r)))
+                    return;
+                for (int i=0; i < r.getMembersCount(); i++) {
+                    RelationMember m = r.getMember(i);
+                    if (m.getMember().equals(e.osm)) {
+                        if (link.matches(e.withParent(r).withIndex(i).withLinkContext())) {
+                            e.parent = r;
+                            e.index = i;
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
         @Override
         public boolean matches(Environment e) {
@@ -73,32 +147,8 @@
 
             if (!parentSelector) {
-                for (OsmPrimitive ref : e.osm.getReferrers()) {
-                    if (!left.matches(e.withPrimitive(ref)))
-                        continue;
-                    if (ref instanceof Way) {
-                        List<Node> wayNodes = ((Way) ref).getNodes();
-                        for (int i=0; i<wayNodes.size(); i++) {
-                            if (wayNodes.get(i).equals(e.osm)) {
-                                if (link.matches(e.withParent(ref).withIndex(i).withLinkContext())) {
-                                    e.parent = ref;
-                                    e.index = i;
-                                    return true;
-                                }
-                            }
-                        }
-                    } else if (ref instanceof Relation) {
-                        List<RelationMember> members = ((Relation) ref).getMembers();
-                        for (int i=0; i<members.size(); i++) {
-                            RelationMember m = members.get(i);
-                            if (m.getMember().equals(e.osm)) {
-                                if (link.matches(e.withParent(ref).withIndex(i).withLinkContext())) {
-                                    e.parent = ref;
-                                    e.index = i;
-                                    return true;
-                                }
-                            }
-                        }
-                    }
-                }
+                MatchingReferrerFinder collector = new MatchingReferrerFinder(e);
+                e.osm.visitReferrers(collector);
+                if (e.parent != null)
+                    return true;
             } else {
                 if (e.osm instanceof Way) {
@@ -181,7 +231,7 @@
 
     public static class GeneralSelector implements Selector {
-        public String base;
+        private String base;
         public Range range;
-        protected List<Condition> conds;
+        private List<Condition> conds;
         private String subpart;
 
@@ -198,5 +248,9 @@
                 range = new Range();
             }
-            this.conds = conds;
+            if (conds == null || conds.isEmpty()) {
+                this.conds = null;
+            } else {
+                this.conds = conds;
+            }
             this.subpart = subpart;
         }
@@ -211,8 +265,20 @@
         }
 
-        @Override
-        public boolean matches(Environment e) {
-            if (!baseApplies(e.osm))
-                return false;
+        public boolean matchesBase(Environment e){
+            if (base.equals("*"))
+                return true;
+            if (base.equals("area")) {
+                if (e.osm instanceof Way)
+                    return true;
+                if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())
+                    return true;
+            }
+            if (base.equals(OsmPrimitiveType.from(e.osm).getAPIName()))
+                return true;
+            return false;
+        }
+
+        public boolean matchesConditions(Environment e){
+            if (conds == null) return true;
             for (Condition c : conds) {
                 if (!c.applies(e))
@@ -222,16 +288,12 @@
         }
 
-        private boolean baseApplies(OsmPrimitive osm) {
-            if (base.equals("*"))
-                return true;
-            if (base.equals("area")) {
-                if (osm instanceof Way)
-                    return true;
-                if (osm instanceof Relation && ((Relation) osm).isMultipolygon())
-                    return true;
-            }
-            if (base.equals(OsmPrimitiveType.from(osm).getAPIName()))
-                return true;
-            return false;
+        @Override
+        public boolean matches(Environment e) {
+            if (!matchesBase(e)) return false;
+            return matchesConditions(e);
+        }
+
+        public String getBase() {
+            return base;
         }
 
