Index: /src/org/openstreetmap/josm/actions/DebugAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/DebugAction.java	(revision 1)
+++ /src/org/openstreetmap/josm/actions/DebugAction.java	(revision 2)
@@ -25,5 +25,5 @@
 
 	public DebugAction(MapFrame mapFrame) {
-		super("Debug Zones", "images/debug.png", KeyEvent.VK_D, mapFrame);
+		super("Debug Zones", "debug", KeyEvent.VK_D, mapFrame);
 	}
 	
Index: /src/org/openstreetmap/josm/actions/MapMode.java
===================================================================
--- /src/org/openstreetmap/josm/actions/MapMode.java	(revision 1)
+++ /src/org/openstreetmap/josm/actions/MapMode.java	(revision 2)
@@ -31,5 +31,5 @@
 	 */
 	public MapMode(String name, String iconName, int mnemonic, MapFrame mapFrame) {
-		super(name, new ImageIcon(iconName));
+		super(name, new ImageIcon("images/"+iconName+".png"));
 		putValue(MNEMONIC_KEY, mnemonic);
 		this.mapFrame = mapFrame;
Index: /src/org/openstreetmap/josm/actions/OpenGpxAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 1)
+++ /src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 2)
@@ -54,6 +54,4 @@
 		try {
 			DataSet dataSet = new GpxReader().parse(new FileReader(gpxFile));
-			if (dataSet.name == null)
-				dataSet.name = gpxFile.getName();
 			MapFrame map = new MapFrame(dataSet);
 			Main.main.setMapFrame(gpxFile.getName(), map);
Index: /src/org/openstreetmap/josm/actions/ZoomAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/ZoomAction.java	(revision 1)
+++ /src/org/openstreetmap/josm/actions/ZoomAction.java	(revision 2)
@@ -1,19 +1,8 @@
 package org.openstreetmap.josm.actions;
 
-import static java.awt.event.MouseEvent.BUTTON1;
-import static java.awt.event.MouseEvent.BUTTON3;
-
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Graphics;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
 
+import org.openstreetmap.josm.actions.SelectionManager.SelectionEnded;
 import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.gui.MapFrame;
@@ -21,24 +10,15 @@
 
 /**
- * Enable the zoom mode within the MapFrame.
+ * Enable the zoom mode within the MapFrame. 
+ * 
+ * Holding down the left mouse button select a rectangle with the same aspect 
+ * ratio than the current map view.
+ * Holding down left and right let the user move the former selected rectangle.
+ * Releasing the left button zoom to the selection.
  * 
  * @author imi
  */
-public class ZoomAction extends MapMode 
-	implements MouseListener, MouseMotionListener, MouseWheelListener {
+public class ZoomAction extends MapMode implements SelectionEnded {
 
-	/**
-	 * Point, the mouse was when pressing the button.
-	 */
-	private Point mousePosStart;
-	/**
-	 * Point to the actual mouse position.
-	 */
-	private Point mousePos;
-	/**
-	 * The point in the map that was the under the mouse point
-	 * when moving around started.
-	 */
-	private GeoPoint mousePosMove;
 	/**
 	 * Shortcut to the mapview.
@@ -46,17 +26,8 @@
 	private final MapView mv;
 	/**
-	 * Whether currently an zooming rectangle is visible or not
+	 * Manager that manages the selection rectangle with the aspect ratio of the
+	 * MapView.
 	 */
-	private boolean zoomRectVisible = false;
-
-	/**
-	 * For the current state.
-	 */
-	enum State {NOTHING, MOVE, ZOOM, ZOOM_POS};
-	/**
-	 * The current state, the ZoomAction is in.
-	 */
-	State state = State.NOTHING;
-	
+	private final SelectionManager selectionManager;
 	
 	
@@ -66,204 +37,24 @@
 	 */
 	public ZoomAction(MapFrame mapFrame) {
-		super("Zoom", "images/zoom.png", KeyEvent.VK_Z, mapFrame);
+		super("Zoom", "zoom", KeyEvent.VK_Z, mapFrame);
 		mv = mapFrame.mapView;
+		selectionManager = new SelectionManager(this, true, mv);
 	}
 
 	/**
-	 * Just to keep track of mouse movements.
+	 * Zoom to the rectangle on the map.
 	 */
-	public void mouseMoved(MouseEvent e) {
-		mousePos = e.getPoint();
-	}
-
-	/**
-	 * Initializing the mouse moving state.
-	 */
-	public void mousePressed(MouseEvent e) {
-		switch (state) {
-		case NOTHING:
-			switch (e.getButton()) {
-			case BUTTON1:
-				state = State.ZOOM;
-				mousePosStart = e.getPoint();
-				paintZoomRect(true);
-				break;
-			case BUTTON3:
-				state = State.MOVE;
-				mousePosMove = mv.getPoint(e.getX(), e.getY(), false);
-				mv.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
-				break;
-			}
-			break;
-		case ZOOM:
-			if (e.getButton() == BUTTON3)
-				state = State.ZOOM_POS;
-			break;
-		case MOVE:
-			if (e.getButton() == BUTTON1) {
-				state = State.ZOOM_POS;
-				mousePosStart = e.getPoint();
-				mousePos = e.getPoint();
-			}
-		}
-	}
-
-	public void mouseReleased(MouseEvent e) {
-		switch (state) {
-		case ZOOM:
-			if (e.getButton() == BUTTON1) {
-				state = State.NOTHING;
-				paintZoomRect(false);
-				Rectangle r = calculateZoomableRectangle();
-				mousePosStart = null;
-				// zoom to the rectangle
-				if (r != null) {
-					double scale = mv.getScale() * r.getWidth()/mv.getWidth();
-					GeoPoint newCenter = mv.getPoint(r.x+r.width/2, r.y+r.height/2, false);
-					mv.zoomTo(newCenter, scale);
-				}
-			}
-			break;
-		case MOVE:
-			if (e.getButton() == BUTTON3) {
-				state = State.NOTHING;
-				mousePosMove = null;
-				mv.setCursor(Cursor.getDefaultCursor());
-			}
-			break;
-		case ZOOM_POS:
-			switch (e.getButton()) {
-			case BUTTON1:
-				state = State.MOVE;
-				paintZoomRect(false);
-				mousePosStart = null;
-				mousePos = null;
-				mousePosMove = mv.getPoint(e.getX(), e.getY(), false);
-				mv.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
-				break;
-			case BUTTON3:
-				state = State.ZOOM;
-				break;
-			}
-		}
-	}
-
-	public void mouseDragged(MouseEvent e) {
-		switch (state) {
-		case MOVE:
-			if (mousePosMove == null) {
-				mousePosMove = mv.getCenter();
-				mv.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
-			}
-			GeoPoint center = mv.getCenter();
-			GeoPoint mouseCenter = mv.getPoint(e.getX(), e.getY(), false);
-			GeoPoint p = new GeoPoint();
-			p.x = mousePosMove.x + center.x - mouseCenter.x;  
-			p.y = mousePosMove.y + center.y - mouseCenter.y;  
-			mv.zoomTo(p, mv.getScale());
-			break;
-		case ZOOM:
-			if (mousePosStart == null)
-				mousePosStart = e.getPoint();
-			if (mousePos == null)
-				mousePos = e.getPoint();
-			paintZoomRect(false);
-			mousePos = e.getPoint();
-			paintZoomRect(true);
-			break;
-		case ZOOM_POS:
-			if (mousePosStart == null)
-				mousePosStart = e.getPoint();
-			if (mousePos == null)
-				mousePos = e.getPoint();
-			paintZoomRect(false);
-			mousePosStart.x += e.getX()-mousePos.x;
-			mousePosStart.y += e.getY()-mousePos.y;
-			mousePos = e.getPoint();
-			paintZoomRect(true);
-			break;
-		}
-	}
-
-	public void mouseWheelMoved(MouseWheelEvent e) {
-		boolean zoomRect = zoomRectVisible;
-		paintZoomRect(false);
-		double zoom = Math.max(0.1, 1 + e.getWheelRotation()/5.0);
-		mv.zoomTo(mv.getCenter(), mv.getScale()*zoom);
-		paintZoomRect(zoomRect);
-	}
-
-	/**
-	 * Calculate the zoomable rectangle between mousePos and mousePosStart.
-	 * Zoomable is the rectangle with a fix point at mousePosStart and the
-	 * correct aspect ratio that fits into the current mapView's size.
-	 * @return Rectangle which should be used to zoom.
-	 */
-	private Rectangle calculateZoomableRectangle() {
-		if (mousePosStart == null || mousePos == null || mousePosStart == mousePos)
-			return null;
-		Rectangle r = new Rectangle();
-		r.x = mousePosStart.x;
-		r.y = mousePosStart.y;
-		r.width = mousePos.x - mousePosStart.x;
-		r.height = mousePos.y - mousePosStart.y;
-		if (r.width < 0) {
-			r.x += r.width;
-			r.width = -r.width;
-		}
-		if (r.height < 0) {
-			r.y += r.height;
-			r.height = -r.height;
-		}
-		
-		// keep the aspect ration by shrinking the rectangle
-		double aspectRatio = (double)mv.getWidth()/mv.getHeight();
-		if ((double)r.width/r.height > aspectRatio)
-			r.width = (int)(r.height*aspectRatio);
-		else
-			r.height = (int)(r.width/aspectRatio);
-
-		return r;
-	}
-	
-	/**
-	 * Paint the mouse selection rectangle XOR'ed over the display.
-	 *
-	 * @param drawVisible True, to draw the rectangle or false to erase it.
-	 */
-	private void paintZoomRect(boolean drawVisible) {
-		Rectangle r = calculateZoomableRectangle();
-		if (r != null && drawVisible != zoomRectVisible) {
-			Graphics g = mv.getGraphics();
-			g.setColor(Color.BLACK);
-			g.setXORMode(Color.WHITE);
-			g.drawRect(r.x,r.y,r.width,r.height);
-			zoomRectVisible = !zoomRectVisible;
-		}
+	public void selectionEnded(Rectangle r, int modifier) {
+		double scale = mv.getScale() * r.getWidth()/mv.getWidth();
+		GeoPoint newCenter = mv.getPoint(r.x+r.width/2, r.y+r.height/2, false);
+		mv.zoomTo(newCenter, scale);
 	}
 
 	public void registerListener(MapView mapView) {
-		mapView.addMouseListener(this);
-		mapView.addMouseMotionListener(this);
-		mapView.addMouseWheelListener(this);
+		selectionManager.register(mapView);
 	}
 
 	public void unregisterListener(MapView mapView) {
-		mapView.removeMouseListener(this);
-		mapView.removeMouseMotionListener(this);
-		mapView.removeMouseWheelListener(this);
+		selectionManager.unregister(mapView);
 	}
-	
-	/**
-	 * Does nothing. Only to satisfy MouseListener
-	 */
-	public void mouseClicked(MouseEvent e) {}
-	/**
-	 * Does nothing. Only to satisfy MouseListener
-	 */
-	public void mouseEntered(MouseEvent e) {}
-	/**
-	 * Does nothing. Only to satisfy MouseListener
-	 */
-	public void mouseExited(MouseEvent e) {}
 }
Index: /src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 1)
+++ /src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.data.osm;
 
+import java.util.Collection;
 import java.util.List;
 
@@ -16,19 +17,4 @@
  */
 public class DataSet implements Cloneable {
-
-	/**
-	 * human readable name of the data.
-	 */
-	public String name;
-
-	/**
-	 * human readable description of what the data is about. Space for comments.
-	 */
-	public String desc;
-
-	/**
-	 * Who recorded/created it.
-	 */
-	public String author;
 
 	/**
@@ -109,4 +95,28 @@
 	}
 
+	/**
+	 * Remove the selection of the whole dataset.
+	 */
+	public void clearSelection() {
+		clearSelection(allNodes);
+		clearSelection(tracks);
+		for (Track t : tracks)
+			clearSelection(t.segments);
+	}
+	
+	/**
+	 * Remove the selection from every value in the collection.
+	 * @param list The collection to remove the selection from.
+	 */
+	private void clearSelection(Collection<? extends OsmPrimitive> list) {
+		if (list == null)
+			return;
+		for (OsmPrimitive osm : list) {
+			osm.selected = false;
+			if (osm.keys != null)
+				clearSelection(osm.keys.keySet());
+		}
+	}
+	
 	public DataSet clone() {
 		try {return (DataSet)super.clone();} catch (CloneNotSupportedException e) {}
Index: /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 1)
+++ /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2)
@@ -16,3 +16,13 @@
 	 */
 	public Map<Key, String> keys;
+	
+	/**
+	 * If set to true, this object has been modified in the current session.
+	 */
+	public boolean modified = false;
+	
+	/**
+	 * If set to true, this object is currently selected.
+	 */
+	public boolean selected = false;
 }
Index: /src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 1)
+++ /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 2)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.actions.DebugAction;
 import org.openstreetmap.josm.actions.MapMode;
+import org.openstreetmap.josm.actions.SelectionAction;
 import org.openstreetmap.josm.actions.ZoomAction;
 import org.openstreetmap.josm.data.Preferences;
@@ -125,4 +126,5 @@
 		toolBarActions.setFloatable(false);
 		toolBarActions.add(new IconToggleButton(new ZoomAction(this)));
+		toolBarActions.add(new IconToggleButton(new SelectionAction(this)));
 		toolBarActions.add(new IconToggleButton(new DebugAction(this)));
 
Index: /src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapView.java	(revision 1)
+++ /src/org/openstreetmap/josm/gui/MapView.java	(revision 2)
@@ -4,4 +4,5 @@
 import java.awt.Component;
 import java.awt.Graphics;
+import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ComponentEvent;
@@ -126,4 +127,7 @@
 		addComponentListener(this);
 		
+		// initialize the movement listener
+		new MapMover(this);
+		
 		// initialize the projection
 		setProjection(Main.pref.projection.clone());
@@ -152,4 +156,23 @@
 			getProjection().xy2latlon(p);
 		return p;
+	}
+	
+	/**
+	 * Return the point on the screen where this GeoPoint would be.
+	 * @param point The point, where this geopoint would be drawn.
+	 * @return The point on screen where "point" would be drawn, relative
+	 * 		to the own top/left.
+	 */
+	public Point getScreenPoint(GeoPoint point) {
+		GeoPoint p;
+		if (!Double.isNaN(point.x) && !Double.isNaN(point.y))
+			p = point;
+		else {
+			if (Double.isNaN(point.lat) || Double.isNaN(point.lon))
+				throw new IllegalArgumentException("point: Either lat/lon or x/y must be set.");
+			p = point.clone();
+			projection.latlon2xy(p);
+		}
+		return new Point(toScreenX(p.x), toScreenY(p.y));
 	}
 	
@@ -225,14 +248,15 @@
 		
 		// draw tracks
-		g.setColor(Color.RED);
 		if (dataSet.tracks != null)
 			for (Track track : dataSet.tracks)
-				for (LineSegment ls : track.segments)
+				for (LineSegment ls : track.segments) {
+					g.setColor(ls.selected ? Color.WHITE : Color.GRAY);
 					g.drawLine(toScreenX(ls.start.coor.x), toScreenY(ls.start.coor.y),
 							toScreenX(ls.end.coor.x), toScreenY(ls.end.coor.y));
+				}
 
 		// draw nodes
-		g.setColor(Color.YELLOW);
 		for (Node w : dataSet.allNodes) {
+			g.setColor(w.selected ? Color.WHITE : Color.RED);
 			g.drawArc(toScreenX(w.coor.x), toScreenY(w.coor.y), 3, 3, 0, 360);
 		}
Index: /src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/GpxReader.java	(revision 1)
+++ /src/org/openstreetmap/josm/io/GpxReader.java	(revision 2)
@@ -67,13 +67,4 @@
 	private DataSet parseDataSet(Element e) {
 		DataSet data = new DataSet();
-		// read global information
-		data.author = e.getAttributeValue("creator");
-		Element metadata = e.getChild("metadata");
-		if (metadata != null)
-		{
-			data.desc = metadata.getChildText("desc", XSD);
-			data.name = metadata.getChildText("name", XSD);
-		}
-		
 		// read waypoints not contained in tracks or areas
 		data.allNodes = new LinkedList<Node>(); 
