Index: /trunk/data/validator/addresses.mapcss
===================================================================
--- /trunk/data/validator/addresses.mapcss	(revision 6927)
+++ /trunk/data/validator/addresses.mapcss	(revision 6927)
@@ -0,0 +1,6 @@
+/* see #9667 - Verify interpolation range/values
+   Matches nodes with a decrease of addr:housenumber within addr:interpolation=even/odd.
+*/
+*[tag("addr:housenumber") > child_tag("addr:housenumber")][regexp_test("even|odd", parent_tag("addr:interpolation"))] + *[addr:housenumber] {
+  throwWarning: tr("Decreasing house numbers in addresses interpolation");
+}
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6926)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6927)
@@ -341,4 +341,8 @@
         }
 
+        public String child_tag(String key) {
+            return env.child == null ? null : env.child.get(key);
+        }
+
         /**
          * Determines whether the object has a tag with the given key.
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 6926)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 6927)
@@ -368,5 +368,11 @@
     (
         (
-            ( <GREATER> { type = Selector.ChildOrParentSelectorType.CHILD; } | <LESS> { type = Selector.ChildOrParentSelectorType.PARENT; } )
+            (
+                <GREATER> { type = Selector.ChildOrParentSelectorType.CHILD; }
+            |
+                <LESS> { type = Selector.ChildOrParentSelectorType.PARENT; }
+            |
+                <PLUS> { type = Selector.ChildOrParentSelectorType.SIBLING; }
+            )
             ( ( c=condition(Context.LINK) | c=class_or_pseudoclass(Context.LINK) ) { conditions.add(c); } )*
         |
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 6926)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 6927)
@@ -39,5 +39,5 @@
 
     public static enum ChildOrParentSelectorType {
-        CHILD, PARENT, ELEMENT_OF, CROSSING
+        CHILD, PARENT, ELEMENT_OF, CROSSING, SIBLING
     }
 
@@ -258,4 +258,22 @@
                 }
                 return e.child != null;
+            } else if (ChildOrParentSelectorType.SIBLING.equals(type)) {
+                if (e.osm instanceof Node) {
+                    for (Way w : Utils.filteredCollection(e.osm.getReferrers(), Way.class)) {
+                        final int i = w.getNodes().indexOf(e.osm);
+                        if (i - 1 >= 0) {
+                            final Node n = w.getNode(i - 1);
+                            final Environment e2 = e.withPrimitive(n).withParent(w).withChild(e.osm);
+                            if (left.matches(e2)) {
+                                if (link.matches(e2.withLinkContext())) {
+                                    e.child = n;
+                                    e.index = i;
+                                    e.parent = w;
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
             } else if (ChildOrParentSelectorType.CHILD.equals(type)) {
                 MatchingReferrerFinder collector = new MatchingReferrerFinder(e);
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorTagCheckerRulesPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorTagCheckerRulesPreference.java	(revision 6926)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/validator/ValidatorTagCheckerRulesPreference.java	(revision 6927)
@@ -137,4 +137,5 @@
             List<ExtendedSourceEntry> def = new ArrayList<ExtendedSourceEntry>();
             
+            addDefault(def, "addresses",    tr("Addresses"),           tr("Checks for errors on addresses"));
             addDefault(def, "combinations", tr("Tag combinations"),    tr("Checks for missing tag or suspicious combinations"));
             addDefault(def, "deprecated",   tr("Deprecated features"), tr("Checks for deprecated features"));
Index: /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 6926)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 6927)
@@ -5,12 +5,13 @@
 import org.openstreetmap.TestUtils
 import org.openstreetmap.josm.Main
-import org.openstreetmap.josm.data.Preferences
+import org.openstreetmap.josm.data.coor.LatLon
+import org.openstreetmap.josm.data.osm.DataSet
 import org.openstreetmap.josm.data.osm.OsmPrimitive
 import org.openstreetmap.josm.data.osm.Way
+import org.openstreetmap.josm.data.projection.Projections
 import org.openstreetmap.josm.gui.mappaint.Environment
 import org.openstreetmap.josm.gui.mappaint.MultiCascade
 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
 import org.openstreetmap.josm.tools.ColorHelper
-import org.openstreetmap.josm.tools.Utils
 
 import java.awt.Color
@@ -34,5 +35,6 @@
     @Before
     public void setUp() throws Exception {
-        Main.pref = new Preferences()
+        Main.initApplicationPreferences()
+        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
     }
 
@@ -252,3 +254,58 @@
         assert ColorHelper.html2color("#12345678") == new Color(0x12, 0x34, 0x56, 0x78)
     }
+
+    @Test
+    public void testSiblingSelector() throws Exception {
+        def s1 = (Selector.ChildOrParentSelector) getParser("*[a?][parent_tag(\"highway\")=\"unclassified\"] + *[b?]").child_selector()
+        def ds = new DataSet()
+        def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
+        n1.put("a", "true")
+        def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
+        n2.put("b", "true")
+        def w = new Way()
+        w.put("highway", "unclassified")
+        ds.addPrimitive(n1)
+        ds.addPrimitive(n2)
+        ds.addPrimitive(w)
+        w.addNode(n1)
+        w.addNode(n2)
+
+        def e = new Environment().withPrimitive(n2)
+        assert s1.matches(e)
+        assert e.osm == n2
+        assert e.child == n1
+        assert e.parent == w
+        assert !s1.matches(new Environment().withPrimitive(n1))
+        assert !s1.matches(new Environment().withPrimitive(w))
+    }
+
+    @Test
+    public void testSiblingSelectorInterpolation() throws Exception {
+        def s1 = (Selector.ChildOrParentSelector) getParser(
+                "*[tag(\"addr:housenumber\") > child_tag(\"addr:housenumber\")][regexp_test(\"even|odd\", parent_tag(\"addr:interpolation\"))]" +
+                        " + *[addr:housenumber]").child_selector()
+        def ds = new DataSet()
+        def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
+        n1.put("addr:housenumber", "10")
+        def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
+        n2.put("addr:housenumber", "100")
+        def n3 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.2, 2.3))
+        n3.put("addr:housenumber", "20")
+        def w = new Way()
+        w.put("addr:interpolation", "even")
+        ds.addPrimitive(n1)
+        ds.addPrimitive(n2)
+        ds.addPrimitive(n3)
+        ds.addPrimitive(w)
+        w.addNode(n1)
+        w.addNode(n2)
+        w.addNode(n3)
+
+        assert s1.right.matches(new Environment().withPrimitive(n3))
+        assert s1.left.matches(new Environment().withPrimitive(n2).withChild(n3).withParent(w))
+        assert s1.matches(new Environment().withPrimitive(n3))
+        assert !s1.matches(new Environment().withPrimitive(n1))
+        assert !s1.matches(new Environment().withPrimitive(n2))
+        assert !s1.matches(new Environment().withPrimitive(w))
+    }
 }
