Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 373)
@@ -83,5 +83,5 @@
 			c = deleteWithReferences(Main.ds.getSelected());
 		} else {
-			c = delete(Main.ds.getSelected());
+			c = delete(Main.ds.getSelected(), false);
 		}
 		if (c != null) {
@@ -100,4 +100,7 @@
 			return;
 		boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
+		boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
+		boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
+		System.out.println("meta="+alt);
 		
 		OsmPrimitive sel = Main.map.mapView.getNearestNode(e.getPoint());
@@ -105,9 +108,17 @@
 		if (sel == null) {
 			WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
-			if (ws != null) c = deleteWaySegment(ws);
+			if (ws != null) {
+				if (shift) {
+					c = deleteWaySegment(ws); 
+				} else if (ctrl) {
+					c = deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
+				} else {
+					c = delete(Collections.singleton((OsmPrimitive)ws.way), alt);
+				}
+			}
 		} else if (ctrl) {
 			c = deleteWithReferences(Collections.singleton(sel));
 		} else {
-			c = delete(Collections.singleton(sel));
+			c = delete(Collections.singleton(sel), alt);
 		}
 		if (c != null) {
@@ -155,12 +166,35 @@
 	 * 
 	 * @param selection The objects to delete.
+	 * @param alsoDeleteNodesInWay true if nodes should be deleted as well
 	 * @return command A command to perform the deletions, or null of there is
 	 * nothing to delete.
 	 */
-	private Command delete(Collection<OsmPrimitive> selection) {
+	private Command delete(Collection<OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {
 		if (selection.isEmpty()) return null;
 
 		Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);
 		Collection<Way> waysToBeChanged = new HashSet<Way>();
+		
+		// nodes belonging to a way will be deleted if
+		// 1. this has been requested (alt modifier)
+		// 2. the node is not tagged
+		// 3. the node is not used by anybody else (i.e. has only one backref)
+		if (alsoDeleteNodesInWay) {
+			for (OsmPrimitive osm : del) {
+				if (osm instanceof Way) {
+					for (Node n : ((Way)osm).nodes) {
+						if (!n.tagged) {
+							CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
+							n.visit(v);
+							if (v.data.size() == 1) {
+								del.add(n);
+							} else System.out.println("size="+v.data.size());
+						}
+						else System.out.println("tagged");
+					}
+				}
+			}
+		}
+		
 		for (OsmPrimitive osm : del) {
 			CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
@@ -217,27 +251,31 @@
 		if (n1.size() < 2 && n2.size() < 2) {
 			return new DeleteCommand(Collections.singleton(ws.way));
-		} else {
-			Way wnew = new Way(ws.way);
-			wnew.nodes.clear();
-
-			if (n1.size() < 2) {
-				wnew.nodes.addAll(n2);
-				return new ChangeCommand(ws.way, wnew);
-			} else if (n2.size() < 2) {
-				wnew.nodes.addAll(n1);
-				return new ChangeCommand(ws.way, wnew);
-			} else {
-				Collection<Command> cmds = new LinkedList<Command>();
-
-				wnew.nodes.addAll(n1);
-				cmds.add(new ChangeCommand(ws.way, wnew));
-
-				Way wnew2 = new Way();
-				wnew2.nodes.addAll(n2);
-				cmds.add(new AddCommand(wnew2));
-
-				return new SequenceCommand(tr("Split way segment"), cmds);
-			}
-		}
+		}
+		
+		Way wnew = new Way(ws.way);
+		wnew.nodes.clear();
+
+		if (n1.size() < 2) {
+			wnew.nodes.addAll(n2);
+			return new ChangeCommand(ws.way, wnew);
+		} else if (n2.size() < 2) {
+			wnew.nodes.addAll(n1);
+			return new ChangeCommand(ws.way, wnew);
+		} else {
+			Collection<Command> cmds = new LinkedList<Command>();
+
+			wnew.nodes.addAll(n1);
+			cmds.add(new ChangeCommand(ws.way, wnew));
+
+			Way wnew2 = new Way();
+			wnew2.nodes.addAll(n2);
+			cmds.add(new AddCommand(wnew2));
+
+			return new SequenceCommand(tr("Split way segment"), cmds);
+		}
+	}
+	
+	@Override public String getModeHelpText() {
+		return "Click to delete. Shift: delete way segment. Alt: delete way+nodes. Ctrl: delete referring objects.";
 	}
 }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 373)
@@ -5,4 +5,5 @@
 
 import java.awt.Cursor;
+import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -20,4 +21,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.GroupAction;
+import org.openstreetmap.josm.actions.mapmode.SelectAction.Mode;
 import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -33,13 +35,4 @@
 
 /**
- * This mode adds a new node to the dataset. The user clicks on a place to add
- * and there is it. Nothing more, nothing less.
- *
- * FIXME: "nothing more, nothing less" is a bit out-of-date
- *
- * Newly created nodes are selected. Shift modifier does not cancel the old
- * selection as usual.
- *
- * @author imi
  *
  */
@@ -80,4 +73,8 @@
 			return;
 
+		boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
+		boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
+		boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
+		
 		Collection<OsmPrimitive> selection = Main.ds.getSelected();
 		Collection<Command> cmds = new LinkedList<Command>();
@@ -86,5 +83,6 @@
 			replacedWays = new ArrayList<Way>();
 		boolean newNode = false;
-		Node n = Main.map.mapView.getNearestNode(e.getPoint());
+		Node n = null;
+		if (!ctrl) n = Main.map.mapView.getNearestNode(e.getPoint());
 		if (n == null) {
 			n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
@@ -98,35 +96,37 @@
 			cmds.add(new AddCommand(n));
 
-			// Insert the node into all the nearby way segments
-			List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint());
-			Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
-			for (WaySegment ws : wss) {
-				List<Integer> is;
-				if (insertPoints.containsKey(ws.way)) {
-					is = insertPoints.get(ws.way);
-				} else {
-					is = new ArrayList<Integer>();
-					insertPoints.put(ws.way, is);
+			if (!ctrl) {
+				// Insert the node into all the nearby way segments
+				List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint());
+				Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
+				for (WaySegment ws : wss) {
+					List<Integer> is;
+					if (insertPoints.containsKey(ws.way)) {
+						is = insertPoints.get(ws.way);
+					} else {
+						is = new ArrayList<Integer>();
+						insertPoints.put(ws.way, is);
+					}
+
+					is.add(ws.lowerIndex);
 				}
-
-				is.add(ws.lowerIndex);
-			}
-			for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
-				Way w = insertPoint.getKey();
-				List<Integer> is = insertPoint.getValue();
-
-				Way wnew = new Way(w);
-
-				pruneSuccsAndReverse(is);
-				for (int i : is) wnew.nodes.add(i + 1, n);
-
-				cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
-				replacedWays.add(insertPoint.getKey());
-				reuseWays.add(wnew);
-			}
-		}
-
+			
+				for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
+					Way w = insertPoint.getKey();
+					List<Integer> is = insertPoint.getValue();
+
+					Way wnew = new Way(w);
+
+					pruneSuccsAndReverse(is);
+					for (int i : is) wnew.nodes.add(i + 1, n);
+
+					cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
+					replacedWays.add(insertPoint.getKey());
+					reuseWays.add(wnew);
+				}
+			}
+		}
 		boolean extendedWay = false;
-		if (selection.size() == 1 && selection.iterator().next() instanceof Node) {
+		if (!shift && selection.size() == 1 && selection.iterator().next() instanceof Node) {
 			Node n0 = (Node) selection.iterator().next();
 
@@ -213,3 +213,7 @@
 		Collections.reverse(is);
 	}
+	
+	@Override public String getModeHelpText() {
+		return "Click to add a new node. Ctrl to disable node re-use/auto-insert. Shift to disable auto-connect.";
+	}
 }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 373)
@@ -48,5 +48,5 @@
 		oldCursor = Main.map.mapView.getCursor();
 		Main.map.mapView.setCursor(cursor);
-		
+		updateStatusLine();
 	}
 	public void exitMode() {
@@ -55,4 +55,11 @@
 	}
 
+	protected void updateStatusLine() {
+		Main.map.statusLine.setHelpText(getModeHelpText());
+	}
+	
+	public String getModeHelpText() {
+		return "";
+	}
 	/**
 	 * Call selectMapMode(this) on the parent mapFrame.
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 373)
@@ -199,4 +199,5 @@
 		}
 
+		updateStatusLine();
 		Main.map.mapView.repaint();
 
@@ -212,5 +213,7 @@
 		}
 		restoreCursor();
+		updateStatusLine();
 		mode = null;
+		updateStatusLine();
 	}
 
@@ -237,3 +240,15 @@
 		Main.map.mapView.repaint();
     }
+	
+	@Override public String getModeHelpText() {
+		if (mode == Mode.select) {
+			return "Release the mouse button to select the objects in the rectangle.";
+		} else if (mode == Mode.move) {
+			return "Release the mouse button to stop moving.";
+		} else if (mode == Mode.rotate) {
+			return "Release the mouse button to stop rotating.";
+		} else {
+			return "Move objects by dragging; Shift to add to selection; Shift-Ctrl to rotate selected; or change selection";
+		}
+	}
 }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 373)
@@ -70,3 +70,7 @@
 		selectionManager.unregister(mv);
 	}
+	
+	@Override public String getModeHelpText() {
+		return "Zoom in by dragging.";
+	}
 }
Index: trunk/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 373)
@@ -54,5 +54,5 @@
 	 * The status line below the map
 	 */
-	private MapStatus statusLine;
+	public MapStatus statusLine;
 
 	public ConflictDialog conflictDialog;
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 372)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 373)
@@ -6,4 +6,5 @@
 import java.awt.AWTEvent;
 import java.awt.Cursor;
+import java.awt.Dimension;
 import java.awt.EventQueue;
 import java.awt.Font;
@@ -17,4 +18,6 @@
 import java.awt.event.MouseMotionListener;
 import java.lang.reflect.InvocationTargetException;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
 import java.util.Collection;
 import java.util.ConcurrentModificationException;
@@ -58,5 +61,7 @@
 	 * The position of the mouse cursor.
 	 */
-	JTextField positionText = new JTextField("-000.00000000000000 -000.00000000000000".length());
+	DecimalFormat latlon = new DecimalFormat("###0.0000000");
+	JTextField positionText = new JTextField(25);
+	
 	/**
 	 * The field holding the name of the object under the mouse.
@@ -64,4 +69,9 @@
 	JTextField nameText = new JTextField(30);
 
+	/**
+	 * The field holding information about what the user can do.
+	 */
+	JTextField helpText = new JTextField();
+	
 	/**
 	 * The collector class that waits for notification and then update
@@ -114,11 +124,13 @@
 				// the data.
 				try {
-					Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
-
-					if (osms == null && osmStatus == null && ms.modifiers == oldModifiers)
-						continue;
-					if (osms != null && osms.equals(osmStatus) && ms.modifiers == oldModifiers)
-						continue;
-
+					// Popup Information
+					if ((ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0 ) {
+						Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
+
+						if (osms == null)
+							continue;
+						if (osms != null && osms.equals(osmStatus) && ms.modifiers == oldModifiers)
+							continue;
+					/*
 					osmStatus = osms;
 					oldModifiers = ms.modifiers;
@@ -133,7 +145,7 @@
 					} else
 						nameText.setText("");
-
-					// Popup Information
-					if ((ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0 && osms != null) {
+					*/
+					
+
 						if (popup != null) {
 							try {
@@ -235,5 +247,5 @@
 				if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == 0) {
 					LatLon p = mv.getLatLon(e.getX(),e.getY());
-					positionText.setText(p.lat()+" "+p.lon());
+					positionText.setText(latlon.format(p.lat())+" "+latlon.format(p.lon()));
 				}
 			}
@@ -242,11 +254,14 @@
 		positionText.setEditable(false);
 		nameText.setEditable(false);
-		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+		helpText.setEditable(false);
+		setLayout(new GridBagLayout());
 		setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-		add(new JLabel(tr("Lat/Lon")+" "));
-		add(positionText);
-		add(new JLabel(" "+tr("Object")+" "));
-		add(nameText);
-
+		add(new JLabel(tr("Lat/Lon")+" "), GBC.std());
+		add(positionText, GBC.std());
+		//add(new JLabel(" "+tr("Object")+" "));
+		//add(nameText);
+		add(helpText, GBC.eol().fill(GBC.HORIZONTAL));
+		positionText.setMinimumSize(new Dimension(positionText.getMinimumSize().height, 200));
+		
 		// The background thread
 		final Collector collector = new Collector(mapFrame);
@@ -270,3 +285,7 @@
 	    return "Statusline";
     }
+	
+	public void setHelpText(String t) {
+		helpText.setText(t);
+	}
 }
