diff --git a/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java b/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
index f09724b..cf84939 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
@@ -87,6 +87,7 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
     private Color selectedColor;
 
     private Node currentBaseNode;
+    private Node currentMouseNode;
     private EastNorth currentMouseEastNorth;
 
     public DrawAction(MapFrame mapFrame) {
@@ -331,6 +332,7 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         ArrayList<Way> reuseWays = new ArrayList<Way>(),
         replacedWays = new ArrayList<Way>();
         boolean newNode = false;
+        int numNodes = 0; // only for shift click on a node
         Node n = null;
 
         if (!ctrl) {
@@ -432,8 +434,8 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         boolean wayIsFinishedTemp = wayIsFinished;
         wayIsFinished = false;
 
-        // don't draw lines if shift is held
-        if (selection.size() > 0 && !shift) {
+        // don't draw lines if shift is held, except when a node was clicked
+        if (selection.size() > 0 && (!shift || !newNode)) {
             Node selectedNode = null;
             Way selectedWay = null;
 
@@ -515,10 +517,22 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
                 }
 
                 // Add new node to way
-                if (way.getNode(way.getNodesCount() - 1) == n0) {
-                    way.addNode(n);
+                if (shift) {
+                    boolean end = (way.getNode(way.getNodesCount() - 1) == n0);
+                    for (Node node : getFollowWayNodes(n0, n)) {
+                        if (end) {
+                            way.addNode(node);
+                        } else {
+                            way.addNode(0, node);
+                        }
+                        numNodes++;
+                    }
                 } else {
-                    way.addNode(0, n);
+                    if (way.getNode(way.getNodesCount() - 1) == n0) {
+                        way.addNode(n);
+                    } else {
+                        way.addNode(0, n);
+                    }
                 }
 
                 extendedWay = true;
@@ -542,7 +556,11 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
             newSelection.clear();
             newSelection.add(n);
         } else if (!newNode) {
-            title = tr("Connect existing way to node");
+            if (numNodes <= 1) {
+                title = tr("Connect existing way to node");
+            } else {
+                title = tr("Connect existing way to {0} nodes", numNodes);
+            }
         } else if (reuseWays.isEmpty()) {
             title = tr("Add a new node to an existing way");
         } else {
@@ -671,7 +689,6 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
 
         Node selectedNode = null;
         Way selectedWay = null;
-        Node currentMouseNode = null;
         mouseOnExistingNode = null;
         mouseOnExistingWays = new HashSet<Way>();
 
@@ -681,6 +698,8 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
 
         if (!ctrl && mousePos != null) {
             currentMouseNode = mv.getNearestNode(mousePos);
+        } else {
+            currentMouseNode = null;
         }
 
         // We need this for highlighting and we'll only do so if we actually want to re-use
@@ -786,6 +805,71 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         return way;
     }
 
+    private List<Node> getFollowWayNodes(Node startNode, Node endNode) {
+        // get list of ways that have both the start node and the end node
+        Collection<Way> allWays = getCurrentDataSet().getWays();
+        Collection<Way> sourceWays = new LinkedList<Way>();
+        for (Way way : allWays) {
+                Collection<Node> wayNodes = way.getNodes();
+                if(wayNodes.contains(startNode) && wayNodes.contains(endNode))
+                        sourceWays.add(way);
+        }
+
+        // if no ways are found, we'll just link directly to the end node
+        if (sourceWays.size() == 0) {
+            List<Node> nodes = new LinkedList<Node>();
+            nodes.add(endNode);
+            return nodes;
+        }
+
+        // create a list of possible routes between the nodes
+        Collection<List<Node>> routes = new LinkedList<List<Node>>();
+
+        for (Way way : sourceWays) {
+            // find the node indexes in the way
+            List<Node> wayNodes = way.getNodes();
+            int startIndex = wayNodes.indexOf(startNode);
+            int endIndex = wayNodes.indexOf(endNode);
+
+            if (startIndex > endIndex) {
+                int tmp = startIndex;
+                startIndex = endIndex;
+                endIndex = tmp;
+            }
+
+            routes.add(wayNodes.subList(startIndex, endIndex + 1));
+
+            if (way.isClosed()) {
+                List<Node> route = new LinkedList<Node>();
+                route.addAll(wayNodes.subList(endIndex, wayNodes.size()));
+                route.addAll(wayNodes.subList(1, startIndex + 1));
+                routes.add(route);
+            }
+        }
+
+        // find the shortest route
+        List<Node> bestRoute = null;
+        double shortestDistance = -1;
+
+        for (List<Node> route : routes) {
+                double distance = 0;
+                Node previous = route.get(0);
+                for (Node node : route) {
+                        distance += previous.getEastNorth().distance(node.getEastNorth());
+                        previous = node;
+                }
+                if (bestRoute == null || distance < shortestDistance) {
+                        bestRoute = route;
+                        shortestDistance = distance;
+                }
+        }
+
+        if (bestRoute.get(0) != startNode)
+            Collections.reverse(bestRoute);
+
+        return bestRoute.subList(1, bestRoute.size());
+    }
+
     private static void pruneSuccsAndReverse(List<Integer> is) {
         //if (is.size() < 2) return;
 
@@ -877,32 +961,18 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         return a * d - b * c;
     }
 
-    public void paint(Graphics2D g, MapView mv, Bounds box) {
-        if (!drawHelperLine || wayIsFinished || shift) return;
-
-        // sanity checks
-        if (Main.map.mapView == null) return;
-        if (mousePos == null) return;
-
-        // don't draw line if we don't know where from or where to
-        if (currentBaseNode == null || currentMouseEastNorth == null) return;
-
-        // don't draw line if mouse is outside window
-        if (!Main.map.mapView.getBounds().contains(mousePos)) return;
-
+    private void drawHelperLine(Graphics2D g, MapView mv, Point p1, Point p2, boolean startline) {
         Graphics2D g2 = g;
         g2.setColor(selectedColor);
         g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
         GeneralPath b = new GeneralPath();
-        Point p1=mv.getPoint(currentBaseNode);
-        Point p2=mv.getPoint(currentMouseEastNorth);
 
         double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
 
         b.moveTo(p1.x,p1.y); b.lineTo(p2.x, p2.y);
 
         // if alt key is held ("start new way"), draw a little perpendicular line
-        if (alt) {
+        if (startline) {
             b.moveTo((int)(p1.x + 8*Math.cos(t+PHI)), (int)(p1.y + 8*Math.sin(t+PHI)));
             b.lineTo((int)(p1.x + 8*Math.cos(t-PHI)), (int)(p1.y + 8*Math.sin(t-PHI)));
         }
@@ -911,6 +981,34 @@ public class DrawAction extends MapMode implements MapViewPaintable, SelectionCh
         g2.setStroke(new BasicStroke(1));
     }
 
+    public void paint(Graphics2D g, MapView mv, Bounds box) {
+        if (!drawHelperLine || wayIsFinished || (shift && (ctrl || Main.map.mapView.getNearestNode(mousePos) == null))) return;
+
+        // sanity checks
+        if (Main.map.mapView == null) return;
+        if (mousePos == null) return;
+
+        // don't draw line if we don't know where from or where to
+        if (currentBaseNode == null || currentMouseEastNorth == null) return;
+
+        // don't draw line if mouse is outside window
+        if (!Main.map.mapView.getBounds().contains(mousePos)) return;
+
+        if (shift && currentBaseNode != currentMouseNode) {
+            List<Node> nodes = getFollowWayNodes(currentBaseNode, currentMouseNode);
+            drawHelperLine(g, mv, mv.getPoint(currentBaseNode), mv.getPoint(nodes.get(0)), alt);
+
+            Node previousNode = null;
+            for (Node node : nodes) {
+                if (previousNode != null)
+                    drawHelperLine(g, mv, mv.getPoint(previousNode), mv.getPoint(node), false);
+                previousNode = node;
+            }
+        } else {
+            drawHelperLine(g, mv, mv.getPoint(currentBaseNode), mv.getPoint(currentMouseEastNorth), alt);
+        }
+    }
+
     @Override public String getModeHelpText() {
         String rv = "";
         /*
