Index: src/org/openstreetmap/josm/gui/mappaint/Environment.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/Environment.java	(revision 4009)
+++ src/org/openstreetmap/josm/gui/mappaint/Environment.java	(working copy)
@@ -1,14 +1,26 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.mappaint;
 
+import java.util.List;
+
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
+import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
 
+
 public class Environment {
-    
+
     public OsmPrimitive osm;
     public MultiCascade mc;
     public String layer;
     public StyleSource source;
+    /**
+     * <p>after the selectors of a MapCSS rule have been applied to {@code osm}, the matching
+     * parent objects of {@code osm} are remembered in this field. It can be accessed in
+     * {@link Instruction#execute(Environment)} to access tags from parent objects.</p>
+     * 
+     */
+    public List<OsmPrimitive> matchingReferrers = null;
 
     public Environment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) {
         this.osm = osm;
@@ -17,4 +29,20 @@
         this.source = source;
     }
 
+    /**
+     * <p>Remembers the referrers to {@link #osm} matching the selector {@code selector}.</p>
+     * 
+     * @param selector the selector
+     */
+    public void rememberMatchingReferrers(Selector selector) {
+        if (selector == null) {
+            this.matchingReferrers = null;
+        } else {
+            this.matchingReferrers = selector.getMatchingReferrers(this);
+        }
+    }
+
+    public void forgetMatchingReferrers() {
+        this.matchingReferrers = null;
+    }
 }
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(revision 4009)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java	(working copy)
@@ -16,7 +16,6 @@
 import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.mappaint.Cascade;
 import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -173,9 +172,9 @@
                 return env.osm.get(key);
             }
 
-            // FIXME: respect parent selector chain
             public String parent_tag(String key) {
-                for (Relation parent: OsmPrimitive.getFilteredList(env.osm.getReferrers(), Relation.class)) {
+                if (env.matchingReferrers == null) return null;
+                for (OsmPrimitive parent: env.matchingReferrers) {
                     String value = parent.get(key);
                     if (value != null) return value;
                 }
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 4009)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(working copy)
@@ -109,23 +109,24 @@
         Environment env = new Environment(n, mc, "default", this);
 
         NEXT_RULE:
-        for (MapCSSRule r : rules) {
-            for (Selector s : r.selectors) {
-                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;
+            for (MapCSSRule r : rules) {
+                for (Selector s : r.selectors) {
+                    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;
+                                }
+                            }
+                            for (Instruction i : r.declaration) {
+                                i.execute(env);
+                            }
                         }
-                        for (Instruction i : r.declaration) {
-                            i.execute(env);
-                        }
                     }
                 }
             }
-        }
         return mc.getCascade("default");
     }
 
@@ -138,6 +139,7 @@
     public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
         Environment env = new Environment(osm, mc, null, this);
         for (MapCSSRule r : rules) {
+            env.forgetMatchingReferrers();
             for (Selector s : r.selectors) {
                 if (s.applies(env)) {
                     if (s.getRange().contains(scale)) {
@@ -152,6 +154,7 @@
                         sub = "default";
                     }
 
+                    env.rememberMatchingReferrers(s);
                     if (sub.equals("*")) {
                         for (Entry<String, Cascade> entry : mc.getLayers()) {
                             env.layer = entry.getKey();
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 4009)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(working copy)
@@ -1,6 +1,7 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.mappaint.mapcss;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.openstreetmap.josm.data.osm.Node;
@@ -14,20 +15,55 @@
 import org.openstreetmap.josm.tools.Utils;
 
 public interface Selector {
-    
+
     public boolean applies(Environment e);
 
     public String getSubpart();
     public Range getRange();
 
+    /**
+     * <p>Replies the list of referrers to the primitive {@code env.osm} which
+     * are matched by this selector.
+     * 
+     * @param env the environment
+     * @return the list of referrers, or the empty list if there are no matching referrers
+     */
+    public List<OsmPrimitive> getMatchingReferrers(Environment env);
+
+
+    /**
+     * <p>Despite its name represents a <em>child selector</em>. JOSM doesn't support
+     * descendant selectors yet.</p>
+     * 
+     * <p>In addition to the standard CSS notation for child selectors, JOSM also supports
+     * an "inverse" notation:</p>
+     * <pre>
+     *    // the standard notation:
+     *    parentselector > childselector { ... }
+     * 
+     *    // the inverse notation:
+     *    childselector < parentselector { ... }
+     * </pre>
+     *
+     */
     public static class DescendentSelector implements Selector {
         Selector a, b;
-        boolean child;
+        /** true, if this represents a child selector in inverse notation
+         * {@code childselector < parentselector}
+         */
+        boolean inverseNotation;
 
+        /**
+         * 
+         * @param a the first selector
+         * @param b the second selector
+         * @param child if true {@code a} is the child selector; otherwise, {@code a}
+         * is the parent selector
+         */
         public DescendentSelector(Selector a, Selector b, boolean child) {
             this.a = a;
             this.b = b;
-            this.child = child;
+            this.inverseNotation = !child;
         }
 
         @Override
@@ -36,7 +72,7 @@
                 return false;
 
             Environment e2 = new Environment(null, e.mc, e.layer, e.source);
-            if (child) {
+            if (!inverseNotation) {
                 for (OsmPrimitive osm : e.osm.getReferrers()) {
                     e2.osm = osm;
                     if (a.applies(e2))
@@ -69,6 +105,31 @@
         public Range getRange() {
             return b.getRange();
         }
+
+        /**
+         * <p>For a child selector in standard notation {@code parentselector > childselector},
+         * replies the list of matching referrers, if the {@code childselector} matches
+         * {@code env.osm}.</p>
+         * 
+         * <p>Otherwise replies an empty list</p>
+         * 
+         * @param env the environment
+         * @return the referrers or the empty list if there are not matching referrers
+         */
+        public List<OsmPrimitive> getMatchingReferrers(Environment env){
+            List<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();
+            if (!b.applies(env)) return ret;
+            Environment e2 = new Environment(null, env.mc, env.layer, env.source);
+            if (!inverseNotation) {
+                for (OsmPrimitive osm : env.osm.getReferrers()) {
+                    e2.osm = osm;
+                    if (a.applies(e2)) {
+                        ret.add(osm);
+                    }
+                }
+            }
+            return ret;
+        }
     }
 
     public static class GeneralSelector implements Selector {
@@ -155,5 +216,14 @@
         public String toString() {
             return base + (range == null ? "" : range) + Utils.join("", conds) + (subpart != null ? ("::" + subpart) : "");
         }
+
+        @Override
+        public List<OsmPrimitive> getMatchingReferrers(Environment env) {
+            /*
+             * a general selector doesn't apply filter conditions to the parent
+             * objects. Reply the unfiltered list of referrers.
+             */
+            return new ArrayList<OsmPrimitive>(env.osm.getReferrers());
+        }
     }
 }
