Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 100)
+++ src/org/openstreetmap/josm/Main.java	(revision 101)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.actions.UndoAction;
 import org.openstreetmap.josm.actions.UploadAction;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.Preferences;
@@ -186,4 +187,5 @@
 			final MapFrame mapFrame = new MapFrame(layer);
 			setMapFrame(mapFrame);
+			mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction());
 			mapFrame.setVisible(true);
 			mapFrame.setVisibleDialogs();
Index: src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 101)
@@ -135,20 +135,4 @@
 
 	public void actionPerformed(ActionEvent e) {
-		String osmDataServer = Main.pref.get("osm-server.url");
-		//TODO: Remove this in later versions (temporary only)
-		if (osmDataServer.endsWith("/0.2") || osmDataServer.endsWith("/0.2/")) {
-			int answer = JOptionPane.showConfirmDialog(Main.parent, 
-					"You seem to have an outdated server entry in your preferences.\n" +
-					"\n" +
-					"As of JOSM Release 1.2, you must no longer specify the API version in\n" +
-					"the osm url. For the OSM standard server, use http://www.openstreetmap.org/api" +
-					"\n" +
-					"Fix settings and continue?", "Outdated server url detected.", JOptionPane.YES_NO_OPTION);
-			if (answer != JOptionPane.YES_OPTION)
-				return;
-			int cutPos = osmDataServer.endsWith("/0.2") ? 4 : 5;
-			Main.pref.put("osm-server.url", osmDataServer.substring(0, osmDataServer.length()-cutPos));
-		}
-
 		JPanel dlg = new JPanel(new GridBagLayout());
 
Index: src/org/openstreetmap/josm/actions/GroupAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/GroupAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/GroupAction.java	(revision 101)
@@ -45,5 +45,5 @@
 
 		this.current = current;
-		putValue(SMALL_ICON, ImageProvider.overlay((Icon)actions.get(current).getValue(SMALL_ICON), "right", OverlayPosition.SOUTHEAST));
+		putValue(SMALL_ICON, ImageProvider.overlay((Icon)actions.get(current).getValue(SMALL_ICON), "overlay/right", OverlayPosition.SOUTHEAST));
 		Object tooltip = actions.get(current).getValue(SHORT_DESCRIPTION);
 		putValue(SHORT_DESCRIPTION, "<html>"+tooltip+" <font size='-2'>"+shortCutName+"</font>&nbsp;</html>");
Index: src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/OpenAction.java	(revision 101)
@@ -75,5 +75,5 @@
 					try {
 						// temporary allow loading of old xml format.
-						dataSet = OsmReader.parseDataSet(new FileReader(filename));
+						dataSet = OsmReader.parseDataSet(new FileReader(filename), null, null);
 					} catch (SAXException x) {
 						if (x.getMessage().equals("Unknown version null")) {
Index: src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/UploadAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/UploadAction.java	(revision 101)
@@ -44,20 +44,4 @@
 		}
 		
-		String osmDataServer = Main.pref.get("osm-server.url");
-		//TODO: Remove this in later versions (temporary only)
-		if (osmDataServer.endsWith("/0.2") || osmDataServer.endsWith("/0.2/")) {
-			int answer = JOptionPane.showConfirmDialog(Main.parent, 
-					"You seem to have an outdated server entry in your preferences.\n" +
-					"\n" +
-					"As of JOSM Release 1.2, you must no longer specify the API version in\n" +
-					"the osm url. For the OSM standard server, use http://www.openstreetmap.org/api" +
-					"\n" +
-					"Fix settings and continue?", "Outdated server url detected.", JOptionPane.YES_NO_OPTION);
-			if (answer != JOptionPane.YES_OPTION)
-				return;
-			int cutPos = osmDataServer.endsWith("/0.2") ? 4 : 5;
-			Main.pref.put("osm-server.url", osmDataServer.substring(0, osmDataServer.length()-cutPos));
-		}
-
 		if (!Main.map.conflictDialog.conflicts.isEmpty()) {
 			JOptionPane.showMessageDialog(Main.parent, "There are unresolved conflicts. You have to resolve these first.");
Index: src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 101)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -47,5 +48,5 @@
 
 	public AddNodeAction(MapFrame mapFrame, String name, Mode mode, String desc) {
-		super(name, "node/"+mode, desc, mapFrame);
+		super(name, "node/"+mode, desc, mapFrame, ImageProvider.getCursor("crosshair", "node"));
 		this.mode = mode;
 	}
Index: src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 101)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -46,5 +47,11 @@
 	 */
 	public AddSegmentAction(MapFrame mapFrame) {
-		super("Add segment", "addsegment", "Add a segment between two nodes.", "G", KeyEvent.VK_G, mapFrame);
+		super("Add segment", 
+				"addsegment", 
+				"Add a segment between two nodes.", 
+				"G", 
+				KeyEvent.VK_G, 
+				mapFrame, 
+				ImageProvider.getCursor("normal", "segment"));
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 101)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -56,5 +57,5 @@
 	 */
 	public AddWayAction(MapFrame mapFrame) {
-		super("Add Way", "addway", "Add a new way to the data.", "W", KeyEvent.VK_W, mapFrame);
+		super("Add Way", "addway", "Add a new way to the data.", "W", KeyEvent.VK_W, mapFrame, ImageProvider.getCursor("normal", "way"));
 		
 		Main.ds.addSelectionChangedListener(this);
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 101)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -50,5 +51,11 @@
 	 */
 	public DeleteAction(MapFrame mapFrame) {
-		super("Delete", "delete", "Delete nodes, streets or segments.", "Delete", KeyEvent.VK_DELETE, mapFrame);
+		super("Delete", 
+				"delete", 
+				"Delete nodes, streets or segments.", 
+				"D", 
+				KeyEvent.VK_D, 
+				mapFrame, 
+				ImageProvider.getCursor("normal", "delete"));
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 101)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.actions.mapmode;
 
+import java.awt.Cursor;
 import java.awt.event.ActionEvent;
 import java.awt.event.MouseEvent;
@@ -23,9 +24,13 @@
 abstract public class MapMode extends JosmAction implements MouseListener, MouseMotionListener {
 
+//	private final Cursor cursor;
+//	private Cursor oldCursor;
+
 	/**
 	 * Constructor for mapmodes without an menu
 	 */
-	public MapMode(String name, String iconName, String tooltip, String keyname, int keystroke, MapFrame mapFrame) {
+	public MapMode(String name, String iconName, String tooltip, String keyname, int keystroke, MapFrame mapFrame, Cursor cursor) {
 		super(name, "mapmode/"+iconName, tooltip, keyname, KeyStroke.getKeyStroke(keystroke, 0));
+//		this.cursor = cursor;
 		putValue("active", false);
 	}
@@ -34,15 +39,20 @@
 	 * Constructor for mapmodes with an menu (no shortcut will be registered)
 	 */
-	public MapMode(String name, String iconName, String tooltip, MapFrame mapFrame) {
+	public MapMode(String name, String iconName, String tooltip, MapFrame mapFrame, Cursor cursor) {
 		putValue(NAME, name);
 		putValue(SMALL_ICON, ImageProvider.get("mapmode", iconName));
 		putValue(SHORT_DESCRIPTION, tooltip);
+//		this.cursor = cursor;
 	}
 
 	public void enterMode() {
 		putValue("active", true);
+//		oldCursor = Main.map.mapView.getCursor();
+//		Main.map.mapView.setCursor(cursor);
+		
 	}
 	public void exitMode() {
 		putValue("active", false);
+//		Main.map.mapView.setCursor(oldCursor);
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 101)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -48,5 +49,11 @@
 	 */
 	public MoveAction(MapFrame mapFrame) {
-		super("Move", "move", "Move selected objects around.", "M", KeyEvent.VK_M, mapFrame);
+		super("Move", 
+				"move", 
+				"Move selected objects around.", 
+				"M", 
+				KeyEvent.VK_M, 
+				mapFrame, 
+				ImageProvider.getCursor("normal", "move"));
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 101)
@@ -11,4 +11,5 @@
 import org.openstreetmap.josm.gui.SelectionManager;
 import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -64,5 +65,11 @@
 	 */
 	public SelectionAction(MapFrame mapFrame) {
-		super("Selection", "selection", "Select objects by dragging or clicking.", "S", KeyEvent.VK_S, mapFrame);
+		super("Selection", 
+				"selection", 
+				"Select objects by dragging or clicking.", 
+				"S", 
+				KeyEvent.VK_S, 
+				mapFrame,
+				ImageProvider.getCursor("normal", "selection"));
 		this.selectionManager = new SelectionManager(this, false, mapFrame.mapView);
 	}
Index: src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 100)
+++ src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 101)
@@ -9,4 +9,5 @@
 import org.openstreetmap.josm.gui.SelectionManager;
 import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -41,5 +42,5 @@
 	 */
 	public ZoomAction(MapFrame mapFrame) {
-		super("Zoom", "zoom", "Zoom in by dragging.", "Z", KeyEvent.VK_Z, mapFrame);
+		super("Zoom", "zoom", "Zoom in by dragging. (Ctrl+up,left,down,right,+,-)", "Z", KeyEvent.VK_Z, mapFrame, ImageProvider.getCursor("normal", "zoom"));
 		mv = mapFrame.mapView;
 		selectionManager = new SelectionManager(this, true, mv);
Index: src/org/openstreetmap/josm/data/ServerSidePreferences.java
===================================================================
--- src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 100)
+++ src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 101)
@@ -1,5 +1,4 @@
 package org.openstreetmap.josm.data;
 
-import java.io.IOException;
 import java.net.URL;
 
@@ -24,5 +23,5 @@
     }
 
-	@Override public void load() throws IOException {
+	@Override public void load() {
 		resetToDefault();
     }
Index: src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapFrame.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/MapFrame.java	(revision 101)
@@ -10,4 +10,5 @@
 
 import javax.swing.AbstractButton;
+import javax.swing.Action;
 import javax.swing.BoxLayout;
 import javax.swing.ButtonGroup;
@@ -92,5 +93,4 @@
 			toolGroup.add((AbstractButton)c);
 		toolGroup.setSelected(((AbstractButton)toolBarActions.getComponent(0)).getModel(), true);
-		selectMapMode((MapMode)((AbstractButton)toolBarActions.getComponent(0)).getAction());
 
 		// autoScale
@@ -128,4 +128,8 @@
 		statusLine = new MapStatus(this);
 	}
+
+	public Action getDefaultButtonAction() {
+	    return ((AbstractButton)toolBarActions.getComponent(0)).getAction();
+    }
 
 	/**
Index: src/org/openstreetmap/josm/gui/MapMover.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapMover.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/MapMover.java	(revision 101)
@@ -2,4 +2,6 @@
 
 import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
@@ -8,4 +10,9 @@
 import java.awt.event.MouseWheelListener;
 
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.KeyStroke;
+
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
 
@@ -17,4 +24,28 @@
  */
 class MapMover extends MouseAdapter implements MouseMotionListener, MouseWheelListener {
+
+	private final class ZoomerAction extends AbstractAction {
+		private final String action;
+		public ZoomerAction(String action) {
+			this.action = action;
+        }
+	    public void actionPerformed(ActionEvent e) {
+	    	if (action.equals("+") || action.equals("-")) {
+	    		MouseWheelEvent we = new MouseWheelEvent(nc, e.getID(), e.getWhen(), e.getModifiers(), nc.getMousePosition().x, nc.getMousePosition().y, 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, action.equals("+") ? -1 : 1);
+	    		mouseWheelMoved(we);
+	    	} else {
+	    		EastNorth center = nc.getCenter();
+	    		EastNorth newcenter = nc.getEastNorth(nc.getWidth()/2+nc.getWidth()/5, nc.getHeight()/2+nc.getHeight()/5);
+	    		if (action.equals("left"))
+	    			nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()), nc.getScale());
+	    		else if (action.equals("right"))
+	    			nc.zoomTo(new EastNorth(newcenter.east(), center.north()), nc.getScale());
+	    		else if (action.equals("up"))
+	    			nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()), nc.getScale());
+	    		else if (action.equals("down"))
+	    			nc.zoomTo(new EastNorth(center.east(), newcenter.north()), nc.getScale());
+	    	}
+	    }
+    }
 
 	/**
@@ -33,5 +64,5 @@
 
 	private boolean movementInPlace = false;
-	
+
 	/**
 	 * Create a new MapMover
@@ -42,6 +73,14 @@
 		nc.addMouseMotionListener(this);
 		nc.addMouseWheelListener(this);
+		
+		String[] n = {"+","-","up","right","down","left"};
+		int[] k = {KeyEvent.VK_PLUS, KeyEvent.VK_MINUS, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT};
+
+		for (int i = 0; i < n.length; ++i) {
+			Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK), "MapMover.Zoomer."+n[i]);
+			Main.contentPane.getActionMap().put("MapMover.Zoomer."+n[i], new ZoomerAction(n[i]));
+		}
 	}
-	
+
 	/**
 	 * If the right (and only the right) mouse button is pressed, move the map
@@ -92,5 +131,5 @@
 		nc.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
 	}
-	
+
 	/**
 	 * End the movement. Setting back the cursor and clear the movement variables
@@ -124,5 +163,5 @@
 		double centery = e.getY() - (e.getY()-h/2)*newHalfHeight*2/h;
 		EastNorth newCenter = nc.getEastNorth((int)centerx, (int)centery); 
-		
+
 		nc.zoomTo(newCenter, nc.getScale()*zoom);
 	}
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 101)
@@ -84,5 +84,5 @@
 	private final AutoScaleAction autoScaleAction;
 
-	
+
 	private final class Scaler extends JSlider implements PropertyChangeListener, ChangeListener {
 		boolean clicked = false;
@@ -91,17 +91,17 @@
 			addMouseListener(new MouseAdapter(){
 				@Override public void mousePressed(MouseEvent e) {
-	                clicked = true;
-                }
+					clicked = true;
+				}
 				@Override public void mouseReleased(MouseEvent e) {
-	                clicked = false;
-                }
+					clicked = false;
+				}
 			});
-			MapView.this.addPropertyChangeListener(this);
+			MapView.this.addPropertyChangeListener("scale", this);
 			addChangeListener(this);
-        }
+		}
 		public void propertyChange(PropertyChangeEvent evt) {
-			if (evt.getPropertyName().equals("scale") && !getModel().getValueIsAdjusting())
+			if (!getModel().getValueIsAdjusting())
 				setValue(zoom());
-        }
+		}
 		public void stateChanged(ChangeEvent e) {
 			if (!clicked)
@@ -114,7 +114,7 @@
 			else
 				zoomTo(center, pos.north()*2/(MapView.this.getHeight()-20));
-        }
-	}
-	
+		}
+	}
+
 	public MapView(AutoScaleAction autoScaleAction) {
 		this.autoScaleAction = autoScaleAction;
@@ -154,8 +154,8 @@
 			Main.ds = dataLayer.data;
 			dataLayer.listenerModified.add(new ModifiedChangedListener(){
-            	public void modifiedChanged(boolean value, OsmDataLayer source) {
-            		JOptionPane.getFrameForComponent(Main.parent).setTitle((value?"*":"")+"Java Open Street Map - Editor");
-            	}
-            });
+				public void modifiedChanged(boolean value, OsmDataLayer source) {
+					JOptionPane.getFrameForComponent(Main.parent).setTitle((value?"*":"")+"Java Open Street Map - Editor");
+				}
+			});
 		}
 
Index: src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 101)
@@ -128,5 +128,5 @@
 				Icon icon = layer.getIcon();
 				if (!layer.visible)
-					icon = ImageProvider.overlay(icon, "invisible", OverlayPosition.SOUTHEAST);
+					icon = ImageProvider.overlay(icon, "overlay/invisible", OverlayPosition.SOUTHEAST);
 				label.setIcon(icon);
 				label.setToolTipText(layer.getToolTipText());
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 101)
@@ -32,5 +32,4 @@
 import javax.swing.ListSelectionModel;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.SelectionChangedListener;
@@ -69,10 +68,10 @@
             this.url = u;
         }
-		@Override protected void realRun() throws SAXException, JDOMException, IOException {
+		@Override protected void realRun() {
 			currentAction.setText("Contact "+url.getHost()+"...");
 			sel = mode != SearchMode.remove ? new LinkedList<OsmPrimitive>() : Main.ds.allNonDeletedPrimitives();
 			try {
 		        URLConnection con = url.openConnection();
-		        Reader in = new ProgressReader(con, progress);
+		        Reader in = new ProgressReader(con, progress, currentAction);
 				currentAction.setText("Downloading...");
 				Map<Long, String> ids = idReader.parseIds(in);
Index: src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 100)
+++ src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 101)
@@ -45,5 +45,4 @@
 import javax.swing.filechooser.FileFilter;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -57,5 +56,4 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.xml.sax.SAXException;
 
 /**
@@ -84,5 +82,5 @@
 			this.gpsLayer = gpsLayer;
 		}
-		@Override protected void realRun() throws SAXException, JDOMException, IOException {
+		@Override protected void realRun() throws IOException {
 			currentAction.setText("Read GPS...");
 			LinkedList<TimedPoint> gps = new LinkedList<TimedPoint>();
@@ -103,4 +101,5 @@
 						if (last != null && last.after(d))
 							throw new IOException("Time loop in gps data.");
+						last = d;
 					}
 				}
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 100)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 101)
@@ -6,6 +6,12 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.swing.BoundedRangeModel;
+import javax.swing.JLabel;
 
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -16,4 +22,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -24,7 +31,14 @@
  * Parser for the Osm Api. Read from an input stream and construct a dataset out of it.
  * 
+ * Reading process takes place in three phases. During the first phase (including xml parse),
+ * all nodes are read and stored. Other information than nodes are stored in a raw list
+ * 
+ * The second phase reads from the raw list all segments and create Segment objects.
+ * 
+ * The third phase read all ways out of the remaining objects in the raw list.
+ * 
  * @author Imi
  */
-public class OsmReader extends MinML2 {
+public class OsmReader {
 
 	/**
@@ -37,89 +51,81 @@
 	 */
 	private AddVisitor adder = new AddVisitor(ds);
+
+	/**
+	 * All read nodes after phase 1.
+	 */
+	private Map<Long, Node> nodes = new HashMap<Long, Node>();
 	
-	/**
-	 * The current processed primitive.
-	 */
-	private OsmPrimitive current;
-
-	/**
-	 * All read nodes so far.
-	 */
-	private Map<Long, Node> nodes = new HashMap<Long, Node>();
-	/**
-	 * All read segents so far.
-	 */
-	private Map<Long, Segment> segments = new HashMap<Long, Segment>();
+	private static class OsmPrimitiveData extends OsmPrimitive {
+		@Override public void visit(Visitor visitor) {}
+		public int compareTo(OsmPrimitive o) {return 0;}
+
+		public void copyTo(OsmPrimitive osm) {
+			osm.id = id;
+			osm.keys = keys;
+			osm.modified = modified;
+			osm.selected = selected;
+			osm.deleted = deleted;
+			osm.timestamp = timestamp;
+        }
+	}
 	
 	/**
-	 * Parse the given input source and return the dataset.
-	 */
-	public static DataSet parseDataSet(Reader source) throws SAXException, IOException {
-		OsmReader osm = new OsmReader(source);
-
-		// clear all negative ids (new to this file)
-		for (OsmPrimitive o : osm.ds.allPrimitives())
-			if (o.id < 0)
-				o.id = 0;
-		
-		return osm.ds;
-	}
-
-	private OsmReader(Reader source) throws SAXException, IOException {
-		parse(source);
-	}
-
-	@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
-		try {
-			if (qName.equals("osm")) {
-				if (atts == null)
-					throw new SAXException("Unknown version.");
-				if (!"0.3".equals(atts.getValue("version")))
-					throw new SAXException("Unknown version "+atts.getValue("version"));
-			} else if (qName.equals("node")) {
-				Node n = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
-				current = n;
-				readCommon(atts);
-				current.id = getLong(atts, "id");
-				nodes.put(n.id, n);
-			} else if (qName.equals("segment")) {
-				Node from = nodes.get(getLong(atts, "from"));
-				Node to = nodes.get(getLong(atts, "to"));
-				if (from == null || to == null)
-					throw new SAXException("Segment "+atts.getValue("id")+" is missing its nodes.");
-				current = new Segment(from, to);
-				readCommon(atts);
-				segments.put(current.id, (Segment)current);
-			} else if (qName.equals("way")) {
-				current = new Way();
-				readCommon(atts);
-			} else if (qName.equals("seg")) {
-				if (current instanceof Way) {
+	 * Data structure for the remaining segment objects
+	 * Maps the raw attributes to key/value pairs.
+	 */
+	private Map<OsmPrimitiveData, long[]> segs = new HashMap<OsmPrimitiveData, long[]>();
+	/**
+	 * Data structure for the remaining way objects
+	 */
+	private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>();
+
+
+	private class Parser extends MinML2 {
+		/**
+		 * The current osm primitive to be read.
+		 */
+		private OsmPrimitive current;
+
+		@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+			try {
+				if (qName.equals("osm")) {
+					if (atts == null)
+						throw new SAXException("Unknown version.");
+					if (!"0.3".equals(atts.getValue("version")))
+						throw new SAXException("Unknown version "+atts.getValue("version"));
+				} else if (qName.equals("node")) {
+					current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
+					readCommon(atts, current);
+					nodes.put(current.id, (Node)current);
+				} else if (qName.equals("segment")) {
+					current = new OsmPrimitiveData();
+					readCommon(atts, current);
+					segs.put((OsmPrimitiveData)current, new long[]{getLong(atts, "from"), getLong(atts, "to")});
+				} else if (qName.equals("way")) {
+					current = new OsmPrimitiveData();
+					readCommon(atts, current);
+					ways.put((OsmPrimitiveData)current, new LinkedList<Long>());
+				} else if (qName.equals("seg")) {
+					Collection<Long> list = ways.get(current);
+					if (list == null)
+						throw new SAXException("Found <seg> tag on non-way.");
 					long id = getLong(atts, "id");
 					if (id == 0)
 						throw new SAXException("Incomplete segment with id=0");
-					Segment ls = segments.get(id);
-					if (ls == null) {
-						ls = new Segment(id); // incomplete segment
-						segments.put(id, ls);
-						adder.visit(ls);
-					}
-					((Way)current).segments.add(ls);
-				}
-			} else if (qName.equals("tag"))
-				current.put(atts.getValue("k"), atts.getValue("v"));
-		} catch (NumberFormatException x) {
-            x.printStackTrace(); // SAXException does not chain correctly
-			throw new SAXException(x.getMessage(), x);
-		} catch (NullPointerException x) {
-			x.printStackTrace(); // SAXException does not chain correctly
-			throw new SAXException("NullPointerException. Possible some missing tags.", x);
-		}
-	}
-
-	
-	@Override public void endElement(String namespaceURI, String localName, String qName) {
-		if (qName.equals("node") || qName.equals("segment") || qName.equals("way") || qName.equals("area")) {
-			current.visit(adder);
+					list.add(id);
+				} else if (qName.equals("tag"))
+					current.put(atts.getValue("k"), atts.getValue("v"));
+			} catch (NumberFormatException x) {
+				x.printStackTrace(); // SAXException does not chain correctly
+				throw new SAXException(x.getMessage(), x);
+			} catch (NullPointerException x) {
+				x.printStackTrace(); // SAXException does not chain correctly
+				throw new SAXException("NullPointerException. Possible some missing tags.", x);
+			}
+		}
+
+		private double getDouble(Attributes atts, String value) {
+			return Double.parseDouble(atts.getValue(value));
 		}
 	}
@@ -128,20 +134,20 @@
 	 * Read out the common attributes from atts and put them into this.current.
 	 */
-	private void readCommon(Attributes atts) throws SAXException {
+	void readCommon(Attributes atts, OsmPrimitive current) throws SAXException {
 		current.id = getLong(atts, "id");
 		if (current.id == 0)
 			throw new SAXException("Illegal object with id=0");
-		
+
 		String time = atts.getValue("timestamp");
 		if (time != null && time.length() != 0) {
 			try {
 				DateFormat df = new SimpleDateFormat("y-M-d H:m:s");
-	            current.timestamp = df.parse(time);
-            } catch (ParseException e) {
-	            e.printStackTrace();
-	            throw new SAXException("Couldn't read time format '"+time+"'.");
-            }
-		}
-		
+				current.timestamp = df.parse(time);
+			} catch (ParseException e) {
+				e.printStackTrace();
+				throw new SAXException("Couldn't read time format '"+time+"'.");
+			}
+		}
+
 		String action = atts.getValue("action");
 		if (action == null)
@@ -152,10 +158,72 @@
 			current.modified = true;
 	}
-
-	private double getDouble(Attributes atts, String value) {
-		return Double.parseDouble(atts.getValue(value));
-	}
-	private long getLong(Attributes atts, String value) {
-		return Long.parseLong(atts.getValue(value));
+	private long getLong(Attributes atts, String value) throws SAXException {
+		String s = atts.getValue(value);
+		if (s == null)
+			throw new SAXException("Missing required attirbute '"+value+"'");
+		return Long.parseLong(s);
+	}
+
+	private void createSegments() {
+		for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) {
+			Node from = nodes.get(e.getValue()[0]);
+			Node to = nodes.get(e.getValue()[1]);
+			if (from == null || to == null)
+				continue; //TODO: implement support for incomplete nodes.
+			Segment s = new Segment(from, to);
+			e.getKey().copyTo(s);
+			segments.put(s.id, s);
+			adder.visit(s);
+		}
+	}
+
+	private void createWays() {
+		for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) {
+			Way w = new Way();
+			for (long id : e.getValue()) {
+				Segment s = segments.get(id);
+				if (s == null)
+					s = new Segment(id); // incomplete line segment
+				w.segments.add(s);
+			}
+			e.getKey().copyTo(w);
+			adder.visit(w);
+		}
+	}
+
+	/**
+	 * All read segments after phase 2.
+	 */
+	private Map<Long, Segment> segments = new HashMap<Long, Segment>();
+
+	/**
+	 * Parse the given input source and return the dataset.
+	 */
+	public static DataSet parseDataSet(Reader source, JLabel currentAction, BoundedRangeModel progress) throws SAXException, IOException {
+		OsmReader osm = new OsmReader();
+
+		// phase 1: Parse nodes and read in raw segments and ways
+		osm.new Parser().parse(source);
+		if (progress != null)
+			progress.setValue(0);
+		if (currentAction != null)
+			currentAction.setText("Preparing data...");
+		for (Node n : osm.nodes.values())
+			osm.adder.visit(n);
+
+		try {
+			osm.createSegments();
+			osm.createWays();
+		} catch (NumberFormatException e) {
+			e.printStackTrace();
+			throw new SAXException("Illformed Node id");
+		}
+
+		// clear all negative ids (new to this file)
+		for (OsmPrimitive o : osm.ds.allPrimitives())
+			if (o.id < 0)
+				o.id = 0;
+
+		return osm.ds;
 	}
 }
Index: src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 100)
+++ src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 101)
@@ -100,5 +100,5 @@
 				return null;
 			currentAction.setText("Downloading OSM data...");
-			final DataSet data = OsmReader.parseDataSet(r);
+			final DataSet data = OsmReader.parseDataSet(r, currentAction, progress);
 			r.close();
 			activeConnection = null;
@@ -134,5 +134,5 @@
 		if (isAuthCancelled() && activeConnection.getResponseCode() == 401)
 			return null;
-		return new ProgressReader(activeConnection, progress);
+		return new ProgressReader(activeConnection, progress, currentAction);
 	}
 }
Index: src/org/openstreetmap/josm/io/ProgressReader.java
===================================================================
--- src/org/openstreetmap/josm/io/ProgressReader.java	(revision 100)
+++ src/org/openstreetmap/josm/io/ProgressReader.java	(revision 101)
@@ -7,4 +7,5 @@
 
 import javax.swing.BoundedRangeModel;
+import javax.swing.JLabel;
 
 /**
@@ -16,11 +17,16 @@
 	private final Reader in;
 	private final BoundedRangeModel progress;
+	private final JLabel currentAction;
+	private int readSoFar = 0;
 
-	public ProgressReader(URLConnection con, BoundedRangeModel progress) throws IOException {
+	public ProgressReader(URLConnection con, BoundedRangeModel progress, JLabel currentAction) throws IOException {
 		this.in = new InputStreamReader(con.getInputStream());
 		this.progress = progress;
+		this.currentAction = currentAction;
 		int contentLength = con.getContentLength();
 		if (contentLength > 0)
 			progress.setMaximum(contentLength);
+		else
+			progress.setMaximum(0);
 		progress.setValue(0);
     }
@@ -32,5 +38,20 @@
 	@Override public int read(char[] cbuf, int off, int len) throws IOException {
 		int read = in.read(cbuf, off, len);
-		progress.setValue(progress.getValue()+read);
+		readSoFar += read;
+
+		String progStr = " ("+readSoFar+"/";
+		if (progress.getMaximum() == 0)
+			progStr += "???)";
+		else
+			progStr += progress.getMaximum()+")";
+		
+		String cur = currentAction.getText();
+		int i = cur.indexOf(' ');
+		if (i != -1)
+			cur = cur.substring(0, i) + progStr;
+		else
+			cur += progStr;
+		currentAction.setText(cur);
+		progress.setValue(readSoFar);
 		return read;
 	}
Index: src/org/openstreetmap/josm/test/GpxWriterTest.java
===================================================================
--- src/org/openstreetmap/josm/test/GpxWriterTest.java	(revision 100)
+++ src/org/openstreetmap/josm/test/GpxWriterTest.java	(revision 101)
@@ -36,5 +36,5 @@
 	}
 
-	
+
 	/**
 	 * Verify, that new created elements, if and only if they occoure more than once in
@@ -55,5 +55,5 @@
 		}
 		assertNotNull("way not found in GPX file", realWay);
-		
+
 		// the second point of the first segment of the ways has an id
 		Element trkseg = (Element)realWay.getChildren("trkseg", GPX).get(0);
Index: src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 100)
+++ src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 101)
@@ -1,8 +1,10 @@
 package org.openstreetmap.josm.tools;
 
+import java.awt.Cursor;
 import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsEnvironment;
 import java.awt.Image;
+import java.awt.Point;
 import java.awt.Toolkit;
 import java.awt.Transparency;
@@ -63,13 +65,20 @@
 	}
 
+	public static Cursor getCursor(String name, String overlay) {
+		ImageIcon img = overlay(get("cursor/"+name), "cursor/modifier/"+overlay, OverlayPosition.SOUTHEAST);
+		Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(img.getImage(),
+				name.equals("crosshair") ? new Point(10,10) : new Point(3,2), "Cursor");
+		return c;
+	}
+
 	/**
 	 * @return an icon that represent the overlay of the two given icons. The
 	 * second icon is layed on the first relative to the given position.
 	 */
-	public static Icon overlay(Icon ground, String overlayImage, OverlayPosition pos) {
+	public static ImageIcon overlay(Icon ground, String overlayImage, OverlayPosition pos) {
 		GraphicsConfiguration conf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
 		int w = ground.getIconWidth();
 		int h = ground.getIconHeight();
-		ImageIcon overlay = ImageProvider.get("overlay",overlayImage);
+		ImageIcon overlay = ImageProvider.get(overlayImage);
 		int wo = overlay.getIconWidth();
 		int ho = overlay.getIconHeight();
