Index: /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java
===================================================================
--- /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java	(revision 18452)
+++ /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java	(revision 18453)
@@ -4,5 +4,4 @@
 
 import java.awt.geom.Area;
-import java.awt.geom.Point2D;
 import java.util.*;
 
@@ -14,4 +13,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.plugins.validator.Severity;
 import org.openstreetmap.josm.plugins.validator.Test;
@@ -22,4 +22,5 @@
  *
  * @author frsantos
+ * @author Teemu Koskinen
  */
 public class Coastlines extends Test
@@ -29,5 +30,7 @@
     protected static int UNCONNECTED_COASTLINE = 903;
 
-    private boolean fixable = false;
+    private List<Way> coastlines;
+
+    private Area downloadedArea = null;
 
     /**
@@ -41,78 +44,134 @@
 
     @Override
-    public void visit(Way way)
-    {
-        if(!way.isUsable() || way.isClosed())
-            return;
-
-        String natural = way.get("natural");
-        if(natural == null || !natural.equals("coastline"))
-            return;
-
-        Node firstNode = way.firstNode();
-        Node lastNode = way.lastNode();
-        Way previousWay = null;
-        Way nextWay = null;
-
-        for (OsmPrimitive parent: this.backreferenceDataSet.getParents(firstNode)) {
-            natural = parent.get("natural");
-            if (parent instanceof Way && !way.equals(parent) && (natural != null && "coastline".equals(natural))) {
-                previousWay = (Way)parent;
-                break;
-            }
-        }
-        for (OsmPrimitive parent: this.backreferenceDataSet.getParents(lastNode)) {
-            natural = parent.get("natural");
-            if (parent instanceof Way && !way.equals(parent) && (natural != null && "coastline".equals(natural))) {
-                nextWay = (Way)parent;
-                break;
-            }
-        }
-
-        List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
-        List<OsmPrimitive> highlight = new ArrayList<OsmPrimitive>();
-        primitives.add(way);
+    public void startTest(ProgressMonitor monitor)
+    {
+    	super.startTest(monitor);
 
         OsmDataLayer layer = Main.map.mapView.getEditLayer();
-        Area downloadedArea = null;
+
         if (layer != null)
             downloadedArea = layer.data.getDataSourceArea();
 
-        if (previousWay == null || nextWay == null) {
-            boolean firstNodeUnconnected = false;
-            boolean lastNodeUnconnected = false;
-
-            if (previousWay == null && (downloadedArea == null || downloadedArea.contains(firstNode.getCoor()))) {
-                firstNodeUnconnected = true;
-                highlight.add(firstNode);
-            }
-            if (nextWay == null && (downloadedArea == null || downloadedArea.contains(lastNode.getCoor()))) {
-                lastNodeUnconnected = true;
-                highlight.add(lastNode);
-            }
-
-            if (firstNodeUnconnected || lastNodeUnconnected)
-                errors.add(new TestError(this, Severity.ERROR, tr("Unconnected coastline"),
-                                         UNCONNECTED_COASTLINE, primitives, highlight));
-        }
-
-        boolean firstNodeUnordered = (previousWay != null && !firstNode.equals(previousWay.lastNode()));
-        boolean lastNodeUnordered = (nextWay != null && !lastNode.equals(nextWay.firstNode()));
-
-        if (firstNodeUnordered || lastNodeUnordered) {
-            if (firstNodeUnordered && lastNodeUnordered && !previousWay.equals(nextWay)) {
+        coastlines = new LinkedList<Way>();
+    }
+
+    @Override
+    public void endTest()
+    {
+        for (Way c1 : coastlines) {
+            Node head = c1.firstNode();
+            Node tail = c1.lastNode();
+
+            if (head.equals(tail))
+                continue;
+
+            int headWays = 0;
+            int tailWays = 0;
+            boolean headReversed = false;
+            boolean tailReversed = false;
+            boolean headUnordered = false;
+            boolean tailUnordered = false;
+            Way next = null;
+            Way prev = null;
+
+            for (Way c2 : coastlines) {
+                if (c1 == c2)
+                    continue;
+
+                if (c2.containsNode(head)) {
+                    headWays++;
+                    next = c2;
+
+                    if (head.equals(c2.firstNode()))
+                        headReversed = true;
+                    else if (!head.equals(c2.lastNode()))
+                        headUnordered = true;
+                }
+
+                if (c2.containsNode(tail)) {
+                    tailWays++;
+                    prev = c2;
+
+                    if (tail.equals(c2.lastNode()))
+                        tailReversed = true;
+                    else if (!tail.equals(c2.firstNode()))
+                        tailUnordered = true;
+                }
+            }
+
+
+            List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
+            primitives.add(c1);
+
+            if (headWays == 0 || tailWays == 0) {
+                List<OsmPrimitive> highlight = new ArrayList<OsmPrimitive>();
+
+                System.out.println("Unconnected coastline: " + c1.getId());
+                if (headWays == 0 && (downloadedArea == null || downloadedArea.contains(head.getCoor()))) {
+                    System.out.println("headways: " +headWays+ " node: " + head.toString());
+                    highlight.add(head);
+                }
+                if (tailWays == 0 && (downloadedArea == null || downloadedArea.contains(tail.getCoor()))) {
+                    System.out.println("tailways: " +tailWays+ " tail: " + tail.toString());
+                    highlight.add(tail);
+                }
+
+                if (highlight.size() > 0)
+                    errors.add(new TestError(this, Severity.ERROR, tr("Unconnceted coastline"),
+                                             UNCONNECTED_COASTLINE, primitives, highlight));
+            }
+
+            boolean unordered = false;
+            boolean reversed = false;
+
+            if (headWays == 1 && headReversed && tailWays == 1 && tailReversed)
+                reversed = true;
+
+            if (headWays > 1 || tailWays > 1)
+                unordered = true;
+            else if (headUnordered || tailUnordered)
+                unordered = true;
+            else if (reversed && next == prev)
+                unordered = true;
+
+            if (unordered) {
+                List<OsmPrimitive> highlight = new ArrayList<OsmPrimitive>();
+
+                System.out.println("Unordered coastline: " + c1.toString());
+                if (headWays > 1 || headUnordered || reversed) {
+                    System.out.println("head: " + head.toString());
+                    highlight.add(head);
+                }
+                if (tailWays > 1 || tailUnordered || reversed) {
+                    System.out.println("tail: " + tail.toString());
+                    highlight.add(tail);
+                }
+
+                errors.add(new TestError(this, Severity.ERROR, tr("Unordered coastline"),
+                                         UNORDERED_COASTLINE, primitives, highlight));
+            }
+            else if (reversed) {
                 errors.add(new TestError(this, Severity.ERROR, tr("Reversed coastline"),
                                          REVERSED_COASTLINE, primitives));
-
-            } else {
-                if (firstNodeUnordered)
-                    highlight.add(firstNode);
-                if (lastNodeUnordered)
-                    highlight.add(lastNode);
-
-                errors.add(new TestError(this, Severity.ERROR, tr("Unordered coastline"),
-                                         UNORDERED_COASTLINE, primitives, highlight));
             }
         }
+
+        coastlines = null;
+        downloadedArea = null;
+
+        super.endTest();
+    }
+
+    @Override
+    public void visit(Way way)
+    {
+        if (!way.isUsable())
+            return;
+
+        String natural = way.get("natural");
+        if (natural == null || !natural.equals("coastline"))
+            return;
+
+        coastlines.add(way);
     }
 
