Index: src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 10957)
+++ src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(working copy)
@@ -577,16 +577,22 @@
                 final String description1 = group == null ? description : group;
                 final String description2 = group == null ? null : description;
                 final List<OsmPrimitive> primitives;
+                final Collection<OsmPrimitive> hilite;
                 if (env.child != null) {
                     primitives = Arrays.asList(p, env.child);
                 } else {
                     primitives = Collections.singletonList(p);
                 }
+                if (env.hilite != null && !env.hilite.isEmpty()) {
+                    hilite = env.hilite;
+                } else
+                    hilite = primitives;
+
                 if (fix != null) {
                     return new FixableTestError(null, getSeverity(), description1, description2, matchingSelector.toString(), 3000,
-                            primitives, fix);
+                            primitives, hilite, fix);
                 } else {
-                    return new TestError(null, getSeverity(), description1, description2, matchingSelector.toString(), 3000, primitives);
+                    return new TestError(null, getSeverity(), description1, description2, matchingSelector.toString(), 3000, primitives, hilite);
                 }
             } else {
                 return null;
Index: src/org/openstreetmap/josm/gui/mappaint/Environment.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/Environment.java	(revision 10957)
+++ src/org/openstreetmap/josm/gui/mappaint/Environment.java	(working copy)
@@ -1,6 +1,8 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.mappaint;
 
+import java.util.Collection;
+
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context;
@@ -21,6 +23,7 @@
     public StyleSource source;
     private Context context = Context.PRIMITIVE;
     public static final String DEFAULT_LAYER = "default";
+    public Collection<OsmPrimitive> hilite;
 
     /**
      * If not null, this is the matching parent object if a condition or an expression
@@ -90,6 +93,7 @@
         this.index = other.index;
         this.count = other.count;
         this.context = other.getContext();
+        this.hilite = other.hilite;
     }
 
     /**
@@ -243,6 +247,7 @@
         child = null;
         index = null;
         count = null;
+        hilite = null;
     }
 
     public Cascade getCascade(String layer) {
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 10957)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(working copy)
@@ -3,8 +3,12 @@
 
 import static org.openstreetmap.josm.data.projection.Ellipsoid.WGS84;
 
+import java.awt.Rectangle;
+import java.awt.geom.Area;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.function.IntFunction;
@@ -12,19 +16,27 @@
 import java.util.regex.PatternSyntaxException;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.BBox;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.Relation;
 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.data.osm.visitor.paint.relations.Multipolygon;
+import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
+import org.openstreetmap.josm.data.projection.Ellipsoid;
 import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.gui.mappaint.Range;
 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.OpenEndPseudoClassCondition;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Geometry.PolygonIntersection;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
@@ -241,18 +253,153 @@
         }
 
         private final class CrossingFinder extends AbstractFinder {
+            HashSet<PrimitiveId> checkedPrimitives = new HashSet<>();
+
             private CrossingFinder(Environment e) {
                 super(e);
                 CheckParameterUtil.ensureThat(e.osm instanceof Way, "Only ways are supported");
             }
 
+            /**
+             * Check two areas for intersection, if found, find elements to highlight
+             * @param a1 1st area
+             * @param a2 2nd area
+             * @param p2 primitive that is or contains area a2
+             * @param nodes1 List of nodes used to calculate 1st area
+             * @param nodes2 List of nodes used to calculate 2nd area
+             */
+            void checkIntersection (Area a1, Area a2, OsmPrimitive p2, List<Node> nodes1, List<Node> nodes2 ) {
+                if (!a1.getBounds2D().intersects(a2.getBounds2D()))
+                    return;
+                Area inter = new Area (a1);
+                inter.intersect(a2);
+                Rectangle bounds = inter.getBounds();
+                PolygonIntersection is;
+                if (inter.isEmpty() || bounds.getHeight()*bounds.getWidth() <= 1.0) {
+                    is = PolygonIntersection.OUTSIDE;
+                } else if (a2.getBounds2D().contains(a1.getBounds2D()) && inter.equals(a1)) {
+                    is = PolygonIntersection.FIRST_INSIDE_SECOND;
+                } else if (a1.getBounds2D().contains(a2.getBounds2D()) && inter.equals(a2)) {
+                    is = PolygonIntersection.SECOND_INSIDE_FIRST;
+                } else {
+                    is = PolygonIntersection.CROSSING;
+                }
+
+                if (is == PolygonIntersection.CROSSING) {
+                    e.child = p2;
+                    // either one area is contained in the other or they are crossing
+                    if (e.parent.isMultipolygon() || p2.isMultipolygon() || (nodes1.size() > 10 && nodes2.size() > 10)) {
+                        // calculate bounding box of intersection plus 0.1 m to catch nodes for better highlighting
+                        EastNorth en1 = new EastNorth(bounds.getMinX(), bounds.getMinY());
+                        EastNorth en2 = new EastNorth(bounds.getMaxX(), bounds.getMaxY());
+                        LatLon ll1 = Main.getProjection().getBaseProjection().eastNorth2latlon(en1);
+                        LatLon ll2 = Main.getProjection().getBaseProjection().eastNorth2latlon(en2);
+                        double inc = 0.1 * (360.0d / (Ellipsoid.WGS84.a * 2 * Math.PI));
+                        BBox searchBox = new BBox (ll1.getX() - inc, ll1.getY() - inc ,ll2.getX() + inc, ll2.getY() + inc);
+                        List<Node> nearNodes = e.osm.getDataSet().searchNodes(searchBox);
+                        HashSet<Node> nodes = new HashSet<>();
+                        nodes.addAll(nodes1);
+                        nodes.addAll(nodes2);
+                        nearNodes.retainAll(nodes);
+                        e.hilite = new ArrayList<>(nearNodes);
+                        if (p2.isMultipolygon() || e.parent.isMultipolygon()) {
+                            // try to find ways which are involved
+                            List<Way> nearWays = e.osm.getDataSet().searchWays(new BBox(ll1.getX(), ll1.getY(), ll2.getX(), ll2.getY()));
+                            for (Way w1 : nearWays) {
+                                if (w1.getNodesCount() > 100)
+                                    continue;
+                                for (OsmPrimitive ref : w1.getReferrers()) {
+                                    if (ref == p2 || ref == e.parent)
+                                        e.hilite.add(w1);
+                                }
+                            }
+                        }
+                    }
+                }
+
+            }
             @Override
             public void visit(Way w) {
                 if (e.child == null && left.matches(new Environment(w).withParent(e.osm))) {
-                    if (e.osm instanceof Way && Geometry.PolygonIntersection.CROSSING.equals(
-                            Geometry.polygonIntersection(w.getNodes(), ((Way) e.osm).getNodes()))) {
-                        e.child = w;
+                    // check way-way intersection
+                    Area a = Geometry.getArea(w.getNodes());
+                    Area b = Geometry.getArea(((Way) e.osm).getNodes());
+                    checkIntersection(a, b, w, w.getNodes(), ((Way) e.osm).getNodes());
+                    return;
+                }
+                if (e.parent.isMultipolygon()) {
+                    // check mp-way intersection
+                    if (e.child == null && left.matches(new Environment(w).withParent(e.parent))) {
+                        if (checkedPrimitives.contains(w))
+                            return;
+                        checkedPrimitives.add(w);
+                        for (OsmPrimitive p : w.getReferrers()) {
+                            if (p == e.parent)
+                                return;
+                        }
+                        Multipolygon polygon = MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.parent);
+                        if (polygon == null)
+                            return;
+                        Area a1 = Geometry.getArea(w.getNodes());
+                        for (PolyData pd : polygon.getCombinedPolygons()) {
+                            Area a2 = new Area(pd.get());
+                            checkIntersection(a1, a2, w, w.getNodes(), pd.getNodes());
+                            if (e.child != null)
+                                return;
+                        }
                     }
+                    if (e.child == null) {
+                        // is way member of a matching mp relation ?
+                        for (OsmPrimitive otherParent : w.getReferrers()) {
+                            if (otherParent.isMultipolygon() && !otherParent.isIncomplete() && e.parent != otherParent) {
+                                if (left.matches(new Environment(otherParent).withParent(otherParent))) {
+                                    if (checkedPrimitives.contains(otherParent))
+                                        return;
+                                    checkedPrimitives.add(otherParent);
+                                    if (((Relation) otherParent).hasIncompleteMembers() )
+                                        return;
+                                    // okay, we have two different complete multipolygons, check if they are overlapping
+                                    Multipolygon p1 = MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.parent);
+                                    if (p1 == null)
+                                        return;
+                                    Multipolygon p2 = MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) otherParent);
+                                    if (p2 == null)
+                                        return;
+                                    for (PolyData pd1 : p1.getCombinedPolygons()) {
+                                        Area a1 = new Area(pd1.get());
+                                        for (PolyData pd2 : p2.getCombinedPolygons()) {
+                                            Area a2 = new Area(pd2.get());
+                                            checkIntersection(a1, a2, otherParent, pd1.getNodes(), pd2.getNodes());
+                                            if (e.child != null)
+                                                return;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+//                } else {
+//                    for (OsmPrimitive otherParent : w.getReferrers()) {
+//                        if (otherParent.isMultipolygon() && ((Relation) otherParent).hasIncompleteMembers() == false) {
+//                            if (left.matches(new Environment(otherParent).withParent(otherParent))) {
+//                                checkedPrimitives.add(otherParent);
+//                                if (e.parent == otherParent || ((Relation) otherParent).hasIncompleteMembers() )
+//                                    return;
+//                                // we have a matching way that might cross a multipolygon, check if they are overlapping
+//                                Area a1 = Geometry.getArea(((Way) e.osm).getNodes());
+//
+//                                Multipolygon p2 = MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) otherParent);
+//                                if (p2 == null)
+//                                    return;
+//                                for (PolyData pd2 : p2.getCombinedPolygons()) {
+//                                    Area a2 = new Area(pd2.get());
+//                                    checkIntersection(a1, a2, otherParent, ((Way) e.osm).getNodes(), pd2.getNodes());
+//                                    if (e.child != null)
+//                                        return;
+//                                }
+//                            }
+//                        }
+//                    }
                 }
             }
         }
@@ -348,6 +495,30 @@
                     crossingFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
                 }
                 return e.child != null;
+            } else if (ChildOrParentSelectorType.CROSSING.equals(type) && e.osm.isMultipolygon()) {
+                Relation r = (Relation) e.osm;
+                if (r.hasIncompleteMembers())
+                    return false;
+                List<RelationMember> members = r.getMembers();
+                for (int i = 0; i < members.size(); i++) {
+                    OsmPrimitive member = members.get(i).getMember();
+                    if (member instanceof Way) {
+                        Environment ew = new Environment(member);
+                        ew.parent = e.osm;
+                        final CrossingFinder crossingFinder = new CrossingFinder(ew);
+                        if (right instanceof OptimizedGeneralSelector
+                                && ((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.WAY)) {
+                            List<Way> nearWays = ew.osm.getDataSet().searchWays(ew.osm.getBBox());
+                            crossingFinder.visit(nearWays);
+                            if (ew.child != null) {
+                                e.child = ew.child;
+                                e.hilite = ew.hilite;
+                                return true;
+                            }
+                        }
+                    }
+                }
+                return e.child != null;
             } else if (ChildOrParentSelectorType.SIBLING.equals(type)) {
                 if (e.osm instanceof Node) {
                     for (Way w : Utils.filteredCollection(e.osm.getReferrers(true), Way.class)) {
