Index: src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java
===================================================================
--- src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java	(revision 17329)
+++ src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java	(working copy)
@@ -4,7 +4,10 @@
 import static org.openstreetmap.josm.data.validation.tests.CrossingWays.HIGHWAY;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -13,10 +16,9 @@
 import org.openstreetmap.josm.data.validation.Severity;
 import org.openstreetmap.josm.data.validation.Test;
 import org.openstreetmap.josm.data.validation.TestError;
-import org.openstreetmap.josm.gui.mappaint.ElemStyles;
 
 /**
- * Checks for ways connected to areas.
+ * Checks for highways connected to areas.
  * @since 4682
  */
 public class WayConnectedToArea extends Test {
@@ -34,53 +36,48 @@
             return;
         }
 
-        List<OsmPrimitive> r = w.firstNode().getReferrers();
-        boolean hasway = r.stream().anyMatch(p -> p != w && p.hasKey(HIGHWAY));
-        if (!hasway) {
-            for (OsmPrimitive p : r) {
-                testForError(w, w.firstNode(), p);
+        for (Node node : Arrays.asList(w.firstNode(), w.lastNode())) {
+            if (node.isOutsideDownloadArea()) {
+                continue;
             }
-        }
-        r = w.lastNode().getReferrers();
-        hasway = r.stream().anyMatch(p -> p != w && p.hasKey(HIGHWAY));
-        if (!hasway) {
-            for (OsmPrimitive p : r) {
-                testForError(w, w.lastNode(), p);
+            if (node.hasTag("noexit", "yes")) {
+                // Avoid "legal" case (see #17036)
+                continue;
             }
-        }
-    }
 
-    private void testForError(Way w, Node wayNode, OsmPrimitive p) {
-        if (wayNode.isOutsideDownloadArea()
-                || wayNode.getReferrers().stream().anyMatch(p1 -> p1.hasTag("route", "ferry"))) {
-            return;
-        } else if (isArea(p)) {
-            addPossibleError(w, wayNode, p, p);
-        } else {
-            p.referrers(Relation.class)
-                    .filter(r -> r.isMultipolygon() && isArea(r))
-                    .findFirst()
-                    .ifPresent(r -> addPossibleError(w, wayNode, p, r));
+            // get other parent ways
+            List<Way> parentWays = node.referrers(Way.class).filter(p -> w != p).collect(Collectors.toList());
+            List<OsmPrimitive> badAreas = new ArrayList<>();
+            boolean hasValidTarget = false;
+            for (Way other : parentWays) {
+                hasValidTarget |= wayIsHighwayTarget(other) || isSlipway(w, node);
+                if (hasValidTarget)
+                    break;
+                else if (other.concernsArea()) {
+                    badAreas.add(other);
+                }
+            }
+            if (!hasValidTarget && !badAreas.isEmpty()) {
+                List<OsmPrimitive> primitives = new ArrayList<>();
+                primitives.add(w);
+                primitives.addAll(badAreas);
+                errors.add(TestError.builder(this, Severity.WARNING, 2301)
+                        .message(tr("Way terminates on Area"))
+                        .primitives(primitives)
+                        .highlight(node)
+                        .build());
+            }
         }
     }
 
-    private static boolean isArea(OsmPrimitive p) {
-        return p.hasKey("landuse", "natural") && ElemStyles.hasAreaElemStyle(p, false);
+    private static boolean wayIsHighwayTarget(Way w) {
+        return w.hasKey(HIGHWAY) || isBuilding(w) || w.hasTag("route", "ferry") || w.hasTag("railway", "platform");
     }
 
-    private void addPossibleError(Way w, Node wayNode, OsmPrimitive p, OsmPrimitive area) {
-        // Avoid "legal" cases (see #10655)
-        if (w.hasKey(HIGHWAY) && wayNode.hasTag("leisure", "slipway") && area.hasTag("natural", "water")) {
-            return;
-        }
-        if (wayNode.hasTag("noexit", "yes")) {
-            // Avoid "legal" case (see #17036)
-            return;
-        }
-        errors.add(TestError.builder(this, Severity.WARNING, 2301)
-                .message(tr("Way terminates on Area"))
-                .primitives(w, p)
-                .highlight(wayNode)
-                .build());
+    // Avoid "legal" cases (see #10655)
+    private static boolean isSlipway(Way w, Node node) {
+        return node.hasTag("leisure", "slipway") && (w.hasTag("natural", "water") ||
+                w.referrers(Relation.class)
+                .anyMatch(r -> r.isMultipolygon() && r.hasTag("natural", "water")));
     }
 }
