Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 11135)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 11136)
@@ -105,4 +105,5 @@
         CrossingWays.Boundaries.class, // ID  601 ..  699
         CrossingWays.Barrier.class, // ID  601 ..  699
+        CrossingWays.SelfCrossing.class, // ID  601 ..  699
         SimilarNamedWays.class, // ID  701 ..  799
         Coastlines.class, // ID  901 ..  999
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 11135)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 11136)
@@ -6,5 +6,4 @@
 import java.awt.geom.Point2D;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -67,4 +66,6 @@
         @Override
         boolean ignoreWaySegmentCombination(Way w1, Way w2) {
+            if (w1 == w2)
+                return false;
             if (!Objects.equals(getLayer(w1), getLayer(w2))) {
                 return true;
@@ -172,4 +173,36 @@
 
     /**
+     * Self crossing ways test (for all the rest)
+     */
+    public static class SelfCrossing extends CrossingWays {
+        CrossingWays.Ways normalTest = new Ways();
+        CrossingWays.Barrier barrierTest = new Barrier();
+        CrossingWays.Boundaries boundariesTest = new Boundaries();
+
+        /**
+         * Constructs a new SelfIntersection test.
+         */
+        public SelfCrossing() {
+            super(tr("Self crossing"));
+        }
+
+        @Override
+        public boolean isPrimitiveUsable(OsmPrimitive p) {
+            return super.isPrimitiveUsable(p) && !(normalTest.isPrimitiveUsable(p) || barrierTest.isPrimitiveUsable(p)
+                    || boundariesTest.isPrimitiveUsable(p));
+        }
+
+        @Override
+        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
+            return (w1 != w2); // should not happen
+        }
+
+        @Override
+        String createMessage(Way w1, Way w2) {
+            return tr("Self-crossing ways");
+        }
+    }
+
+    /**
      * Constructs a new {@code CrossingWays} test.
      * @param title The test title
@@ -221,4 +254,9 @@
     @Override
     public void visit(Way w) {
+        if (this instanceof SelfCrossing) {
+            // free memory, we are not interested in previous ways
+            cellSegments.clear();
+            seenWays.clear();
+        }
 
         int nodesSize = w.getNodesCount();
@@ -231,5 +269,5 @@
                 continue;
             }
-            for (List<WaySegment> segments : getSegments(en1, en2)) {
+            for (List<WaySegment> segments : getSegments(cellSegments, en1, en2)) {
                 for (WaySegment es2 : segments) {
                     List<Way> prims;
@@ -240,5 +278,8 @@
                     }
 
-                    prims = Arrays.asList(es1.way, es2.way);
+                    prims = new ArrayList<>();
+                    prims.add(es1.way);
+                    if (es1.way != es2.way)
+                        prims.add(es2.way);
                     if ((highlight = seenWays.get(prims)) == null) {
                         highlight = new ArrayList<>();
@@ -266,10 +307,10 @@
      * Returns all the cells this segment crosses.  Each cell contains the list
      * of segments already processed
-     *
+     * @param cellSegments map with already collected way segments
      * @param n1 The first EastNorth
      * @param n2 The second EastNorth
      * @return A list with all the cells the segment crosses
      */
-    private List<List<WaySegment>> getSegments(EastNorth n1, EastNorth n2) {
+    public static List<List<WaySegment>> getSegments(Map<Point2D, List<WaySegment>> cellSegments, EastNorth n1, EastNorth n2) {
 
         List<List<WaySegment>> cells = new ArrayList<>();
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/SelfIntersectingWay.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/SelfIntersectingWay.java	(revision 11135)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/SelfIntersectingWay.java	(revision 11136)
@@ -32,6 +32,11 @@
     public void visit(Way w) {
         Set<Node> nodes = new HashSet<>();
-
-        for (int i = 1; i < w.getNodesCount() - 1; i++) {
+        int last = w.getNodesCount();
+        if (last < 2)
+            return;
+        if (w.firstNode() == w.lastNode())
+            last--; // closed way, ignore last node
+        nodes.add(w.firstNode());
+        for (int i = 1; i < last; i++) {
             Node n = w.getNode(i);
             if (nodes.contains(n)) {
