Index: src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java b/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
--- a/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(revision 17702)
+++ b/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(date 1617656878658)
@@ -47,7 +47,7 @@
     /** Bag of all way segments */
     private MultiMap<Pair<Node, Node>, WaySegment> nodePairs;
 
-    private boolean onlyKnwonLinear;
+    private boolean onlyKnownLinear;
     private boolean includeOther;
     private boolean ignoreLayer;
 
@@ -83,7 +83,7 @@
         super.startTest(monitor);
         nodePairs = new MultiMap<>(1000);
         includeOther = isBeforeUpload ? ValidatorPrefHelper.PREF_OTHER_UPLOAD.get() : ValidatorPrefHelper.PREF_OTHER.get();
-        onlyKnwonLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true);
+        onlyKnownLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true);
         ignoreLayer = Config.getPref().getBoolean("overlapping-ways.ignore-layer", false);
     }
 
@@ -192,7 +192,7 @@
                 errortype = tr("Waterway shares segment with linear way");
                 type = OVERLAPPING_WATERWAY_LINEAR_WAY;
                 severity = Severity.WARNING;
-            } else if (!includeOther || onlyKnwonLinear) {
+            } else if (!includeOther || onlyKnownLinear) {
                 return;
             } else if (countHighway > 0) {
                 errortype = tr("Highway shares segment with other way");
@@ -269,7 +269,7 @@
         if (IGNORED.test(w))
             return;
 
-        if (onlyKnwonLinear && (w.concernsArea() || w.getInterestingTags().isEmpty()))
+        if (onlyKnownLinear && (w.concernsArea() || w.getInterestingTags().isEmpty()))
             return;
 
         Node lastN = null;
Index: src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java b/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
--- a/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java	(revision 17702)
+++ b/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java	(date 1617661008249)
@@ -11,6 +11,7 @@
 import java.util.Set;
 
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.NodePair;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -25,19 +26,21 @@
 import org.openstreetmap.josm.tools.Geometry;
 
 /**
- * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole tag.<br>
- * See #7812 for discussions about this test.
+ * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole/portal tag and also for ways where
+ * are unusually long segments without line support feature.<br>
+ * See #7812 and #{FIXME number} for discussions about this test.
  */
 public class PowerLines extends Test {
 
     /** Test identifier */
     protected static final int POWER_LINES = 2501;
     protected static final int POWER_CONNECTION = 2502;
+    protected static final int POWER_SEGMENT_LENGTH = 2503;
 
     /** Values for {@code power} key interpreted as power lines */
     static final Collection<String> POWER_LINE_TAGS = Arrays.asList("line", "minor_line");
     /** Values for {@code power} key interpreted as power towers */
-    static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole");
+    static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole", "portal");
     /** Values for {@code power} key interpreted as power stations */
     static final Collection<String> POWER_STATION_TAGS = Arrays.asList("station", "sub_station", "substation", "plant", "generator");
     /** Values for {@code building} key interpreted as power stations */
@@ -47,7 +50,8 @@
             "portal", "terminal", "insulator");
 
     private final Set<Node> badConnections = new LinkedHashSet<>();
-    private final Set<Node> missingTowerOrPole = new LinkedHashSet<>();
+    private final Set<Node> missingTag = new LinkedHashSet<>();
+    private final Set<NodePair> missingNode = new LinkedHashSet<>();
 
     private final List<OsmPrimitive> powerStations = new ArrayList<>();
 
@@ -58,22 +62,6 @@
         super(tr("Power lines"), tr("Checks for nodes in power lines that do not have a power=tower/pole tag."));
     }
 
-    @Override
-    public void visit(Way w) {
-        if (w.isUsable()) {
-            if (isPowerLine(w) && !w.hasTag("location", "underground")) {
-                for (Node n : w.getNodes()) {
-                    if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)
-                        && (!w.isFirstLastNode(n) || !isPowerStation(n))) {
-                        missingTowerOrPole.add(n);
-                    }
-                }
-            } else if (w.isClosed() && isPowerStation(w)) {
-                powerStations.add(w);
-            }
-        }
-    }
-
     @Override
     public void visit(Node n) {
         boolean nodeInLineOrCable = false;
@@ -89,18 +77,29 @@
             badConnections.add(n);
     }
 
-    private static boolean isRelatedToPower(Way way) {
-        if (way.hasTag("power") || way.hasTag("building"))
-            return true;
-        for (OsmPrimitive ref : way.getReferrers()) {
-            if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) {
-                for (RelationMember rm : ((Relation) ref).getMembers()) {
-                    if (way == rm.getMember())
-                        return true;
+    @Override
+    public void visit(Way w) {
+        if (w.isUsable()) {
+            if (isPowerLine(w) && !w.hasTag("location", "underground")) {
+                float avgWayLength = (float) (w.getLength() / w.getRealNodesCount());
+                Node prevNode = w.firstNode();
+
+                for (Node n : w.getNodes()) {
+                    if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)
+                            && (!w.isFirstLastNode(n) || !isPowerStation(n))) {
+                        missingTag.add(n);
+                    }
+
+                    double distance = n.getCoor().greatCircleDistance(prevNode.getCoor());
+                    if (w.getRealNodesCount() > 4 && distance > avgWayLength * 2.0f && !isPowerAllowed(n)) {
+                        missingNode.add(new NodePair(prevNode, n));
+                    }
+                    prevNode = n;
                 }
+            } else if (w.isClosed() && isPowerStation(w)) {
+                powerStations.add(w);
             }
         }
-        return false;
     }
 
     @Override
@@ -118,10 +117,10 @@
 
     @Override
     public void endTest() {
-        for (Node n : missingTowerOrPole) {
+        for (Node n : missingTag) {
             if (!isInPowerStation(n)) {
                 errors.add(TestError.builder(this, Severity.WARNING, POWER_LINES)
-                        .message(tr("Missing power tower/pole within power line"))
+                        .message(tr("Missing power line support tag from node"))
                         .primitives(n)
                         .build());
             }
@@ -130,13 +129,36 @@
         for (Node n : badConnections) {
             errors.add(TestError.builder(this, Severity.WARNING, POWER_CONNECTION)
                     .message(tr("Node connects a power line or cable with an object "
-                            + "which is not related to the power infrastructure."))
-                    .primitives(n).build());
+                            + "which is not related to the power infrastructure"))
+                    .primitives(n)
+                    .build());
         }
+
+        for (NodePair pair : missingNode) {
+            errors.add(TestError.builder(this, Severity.WARNING, POWER_SEGMENT_LENGTH)
+                    .message(tr("Missing line support node within power line"))
+                    .primitives(pair.getA(), pair.getB())
+                    .build());
+        }
+
         clearCollections();
         super.endTest();
     }
 
+    private static boolean isRelatedToPower(Way way) {
+        if (way.hasTag("power") || way.hasTag("building"))
+            return true;
+        for (OsmPrimitive ref : way.getReferrers()) {
+            if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) {
+                for (RelationMember rm : ((Relation) ref).getMembers()) {
+                    if (way == rm.getMember())
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
+
     protected final boolean isInPowerStation(Node n) {
         for (OsmPrimitive station : powerStations) {
             List<List<Node>> nodesLists = new ArrayList<>();
@@ -189,7 +211,7 @@
     /**
      * Determines if the specified node denotes a power infrastructure allowed on a power line.
      * @param n The node to be tested
-     * @return True if power key is set and equal to switch/tranformer/busbar/generator
+     * @return True if power key is set and equal to switch/transformer/busbar/generator
      */
     protected static final boolean isPowerAllowed(Node n) {
         return isPowerIn(n, POWER_ALLOWED_TAGS);
@@ -218,6 +240,7 @@
     private void clearCollections() {
         powerStations.clear();
         badConnections.clear();
-        missingTowerOrPole.clear();
+        missingTag.clear();
+        missingNode.clear();
     }
 }
