Index: /trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java	(revision 4670)
+++ /trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java	(revision 4671)
@@ -9,4 +9,5 @@
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import org.openstreetmap.josm.Main;
@@ -72,4 +73,6 @@
             return;
         Way follower = selectedLines.iterator().next();
+        if (follower.isClosed())    /* Don't loop until OOM */
+            return;
         Node prev = follower.getNode(1);
         boolean reversed = true;
@@ -81,4 +84,5 @@
         if (referrers.size() < 2) return; // There's nothing to follow
         
+        Node newPoint = null;        
         Iterator<OsmPrimitive> i = referrers.iterator();
         while (i.hasNext()) {
@@ -91,41 +95,33 @@
                 continue;
             }
-            List<Node> points = toFollow.getNodes();
-            int indexOfLast = points.indexOf(last);
-            int indexOfPrev = points.indexOf(prev);
-            if ((indexOfLast == -1) || (indexOfPrev == -1)) { // Both points must belong to both lines
+            Set<Node> points = toFollow.getNeighbours(last);
+            if (!points.remove(prev) || (points.size() == 0))
                 continue;
+            if (points.size() > 1)    // Ambiguous junction?
+                return;
+
+            Node newPointCandidate = points.iterator().next();
+
+            if ((newPoint != null) && (newPoint != newPointCandidate))
+                return;         // Ambiguous junction, force to select next
+
+            newPoint = newPointCandidate;
+        }
+        if (newPoint != null) {
+            Way newFollower = new Way(follower);
+            if (reversed) {
+                newFollower.addNode(0, newPoint);
+            } else {
+                newFollower.addNode(newPoint);
             }
-            if (Math.abs(indexOfPrev - indexOfLast) != 1) {  // ...and be consecutive
-                continue;
-            }
-            Node newPoint = null;
-            if (indexOfPrev == (indexOfLast - 1)) {
-                if ((indexOfLast + 1) < points.size()) {
-                    newPoint = points.get(indexOfLast + 1);
-                }
-            } else {
-                if ((indexOfLast - 1) >= 0) {
-                    newPoint = points.get(indexOfLast - 1);
-                }
-            }
-            if (newPoint != null) {
-                Way newFollower = new Way(follower);
-                if (reversed) {
-                    newFollower.addNode(0, newPoint);
-                } else {
-                    newFollower.addNode(newPoint);
-                }
-                Main.main.undoRedo.add(new ChangeCommand(follower, newFollower));
-                osmLayer.data.clearSelection();
-                osmLayer.data.addSelected(newFollower);
-                osmLayer.data.addSelected(newPoint);
-                // "viewport following" mode for tracing long features 
-                // from aerial imagery or GPS tracks. 
-                if (Main.map.mapView.viewportFollowing) {
-                    Main.map.mapView.smoothScrollTo(newPoint.getEastNorth());
-                };
-                return;
-            }
+            Main.main.undoRedo.add(new ChangeCommand(follower, newFollower));
+            osmLayer.data.clearSelection();
+            osmLayer.data.addSelected(newFollower);
+            osmLayer.data.addSelected(newPoint);
+            // "viewport following" mode for tracing long features 
+            // from aerial imagery or GPS tracks. 
+            if (Main.map.mapView.viewportFollowing) {
+                Main.map.mapView.smoothScrollTo(newPoint.getEastNorth());
+            };
         }
     }
Index: /trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 4670)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 4671)
@@ -8,4 +8,5 @@
 import java.util.List;
 import java.util.Set;
+import java.util.HashSet;
 
 import org.openstreetmap.josm.Main;
@@ -139,4 +140,28 @@
     }
 
+    /**
+     * Return nodes adjacent to <code>node</code>
+     *
+     * @param node the node. May be null.
+     * @return Set of nodes adjacent to <code>node</code>
+     * @since 4666
+     */
+    public Set<Node> getNeighbours(Node node) {
+        HashSet<Node> neigh = new HashSet<Node>();
+
+        if (node == null) return neigh;
+
+        Node[] nodes = this.nodes;
+        for (int i=0; i<nodes.length; i++) {
+            if (nodes[i].equals(node)) {
+                if (i > 0)
+                    neigh.add(nodes[i-1]);
+                if (i < nodes.length-1)
+                    neigh.add(nodes[i+1]);
+            }
+        }
+        return neigh;
+    }
+
     public List<Pair<Node,Node>> getNodePairs(boolean sort) {
         List<Pair<Node,Node>> chunkSet = new ArrayList<Pair<Node,Node>>();
