Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 70)
+++ src/org/openstreetmap/josm/Main.java	(revision 71)
@@ -35,10 +35,10 @@
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.gui.BugReportExceptionHandler;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.ShowModifiers;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.BugReportExceptionHandler;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -294,11 +294,6 @@
 	}
 
-	/**
-	 * Set the main's mapframe. If a changed old mapFrame is already set, 
-	 * ask the user whether he want to save, discard or abort. If the user
-	 * aborts, nothing happens. 
-	 */
+	//TODO: should be solved better.
 	public void setMapFrame(MapFrame mapFrame) {
-		//TODO: Check for changes and ask user
 		if (this.mapFrame != null)
 			this.mapFrame.setVisible(false);
Index: src/org/openstreetmap/josm/actions/AboutAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AboutAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/AboutAction.java	(revision 71)
@@ -21,6 +21,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.GBC;
-import org.openstreetmap.josm.gui.ImageProvider;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.UrlLabel;
 
Index: src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 71)
@@ -31,9 +31,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.BookmarkList;
-import org.openstreetmap.josm.gui.GBC;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -44,4 +43,5 @@
 import org.openstreetmap.josm.gui.layer.RawGpsDataLayer;
 import org.openstreetmap.josm.io.OsmServerReader;
+import org.openstreetmap.josm.tools.GBC;
 import org.xml.sax.SAXException;
 
@@ -114,6 +114,6 @@
 			MapView mv = Main.main.getMapFrame().mapView;
 			setEditBounds(new Bounds(
-					mv.getPoint(0, mv.getHeight(), true),
-					mv.getPoint(mv.getWidth(), 0, true)));
+					mv.getLatLon(0, mv.getHeight()),
+					mv.getLatLon(mv.getWidth(), 0)));
 			rawGps.setSelected(mv.getActiveLayer() instanceof RawGpsDataLayer);
 		}
@@ -168,6 +168,6 @@
 							double size = 180.0 / Math.pow(2, map.get("zoom"));
 							Bounds b = new Bounds(
-									new GeoPoint(map.get("lat") - size/2, map.get("lon") - size), 
-									new GeoPoint(map.get("lat") + size/2, map.get("lon") + size));
+									new LatLon(map.get("lat") - size/2, map.get("lon") - size),
+									new LatLon(map.get("lat") + size/2, map.get("lon") + size));
 							setEditBounds(b);
 						} catch (Exception x) { // NPE or IAE
@@ -310,14 +310,14 @@
 	 */
 	private void setEditBounds(Bounds b) {
-		GeoPoint bottomLeft = b.min;
-		GeoPoint topRight = b.max;
+		LatLon bottomLeft = b.min;
+		LatLon topRight = b.max;
 		if (bottomLeft.isOutSideWorld())
-			bottomLeft = new GeoPoint(-89.999, -179.999); // do not use the Projection constants, since this looks better.
+			bottomLeft = new LatLon(-89.999, -179.999); // do not use the Projection constants, since this looks better.
 		if (topRight.isOutSideWorld())
-			topRight = new GeoPoint(89.999, 179.999);
-		latlon[0].setText(""+bottomLeft.lat);
-		latlon[1].setText(""+bottomLeft.lon);
-		latlon[2].setText(""+topRight.lat);
-		latlon[3].setText(""+topRight.lon);
+			topRight = new LatLon(89.999, 179.999);
+		latlon[0].setText(""+bottomLeft.lat());
+		latlon[1].setText(""+bottomLeft.lon());
+		latlon[2].setText(""+topRight.lat());
+		latlon[3].setText(""+topRight.lon());
 		for (JTextField f : latlon)
 			f.setCaretPosition(0);
Index: src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/JosmAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/JosmAction.java	(revision 71)
@@ -10,5 +10,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.ImageProvider;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
Index: src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/OpenAction.java	(revision 71)
@@ -16,5 +16,5 @@
 import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.MapFrame;
@@ -71,9 +71,9 @@
 
 			if (asRawData(fn)) {
-				Collection<Collection<GeoPoint>> data;
+				Collection<Collection<LatLon>> data;
 				if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
 					data = new RawGpsReader(new FileReader(filename)).parse();
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
-					data = new LinkedList<Collection<GeoPoint>>();
+					data = new LinkedList<Collection<LatLon>>();
 					data.add(new RawCsvReader(new FileReader(filename)).parse());
 				} else
Index: src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/SaveAction.java	(revision 71)
@@ -22,6 +22,4 @@
  * Export the data  as OSM intern xml file.
  * 
- * TODO: This is very redundant with SaveGpxAction. Merge both actions into one!
- *  
  * @author imi
  */
Index: src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/UploadAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/UploadAction.java	(revision 71)
@@ -19,7 +19,7 @@
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.GBC;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.io.OsmServerWriter;
+import org.openstreetmap.josm.tools.GBC;
 
 /**
Index: src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 71)
@@ -162,6 +162,6 @@
 		g.setColor(Color.BLACK);
 		g.setXORMode(Color.WHITE);
-		Point firstDrawn = mv.getScreenPoint(first.coor);
-		Point secondDrawn = mv.getScreenPoint(second.coor);
+		Point firstDrawn = mv.getPoint(first.eastNorth);
+		Point secondDrawn = mv.getPoint(second.eastNorth);
 		g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
 		hintDrawn = !hintDrawn;
Index: src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 71)
@@ -23,8 +23,4 @@
 public class AddNodeAction extends MapMode {
 
-	/**
-	 * Create an AddNodeAction. Mnemonic is 'a'
-	 * @param mapFrame
-	 */
 	public AddNodeAction(MapFrame mapFrame) {
 		super("Add nodes", "addnode", "Add nodes to the map.", "N", KeyEvent.VK_N, mapFrame);
@@ -50,5 +46,5 @@
 	public void mouseClicked(MouseEvent e) {
 		if (e.getButton() == MouseEvent.BUTTON1) {
-			Node node = new Node(mv.getPoint(e.getX(), e.getY(), true));
+			Node node = new Node(mv.getLatLon(e.getX(), e.getY()));
 			if (node.coor.isOutSideWorld()) {
 				JOptionPane.showMessageDialog(Main.main, "Can not add a node outside of the world.");
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 71)
@@ -94,8 +94,8 @@
 	 * Delete the primitives and everything they references.
 	 * 
-	 * If a node is deleted, the node and all line segments, waies and areas
+	 * If a node is deleted, the node and all line segments, ways and areas
 	 * the node is part of are deleted as well.
 	 * 
-	 * If a line segment is deleted, all waies the line segment is part of 
+	 * If a line segment is deleted, all ways the line segment is part of 
 	 * are deleted as well. No nodes are deleted.
 	 * 
Index: src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 71)
@@ -12,7 +12,8 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.MoveCommand;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
 
@@ -79,13 +80,13 @@
 		}
 
-		GeoPoint mouseGeo = mv.getPoint(e.getX(), e.getY(), false);
-		GeoPoint mouseStartGeo = mv.getPoint(mousePos.x, mousePos.y, false);
-		double dx = mouseGeo.x - mouseStartGeo.x;
-		double dy = mouseGeo.y - mouseStartGeo.y;
+		EastNorth mouseGeo = mv.getEastNorth(e.getX(), e.getY());
+		EastNorth mouseStartGeo = mv.getEastNorth(mousePos.x, mousePos.y);
+		double dx = mouseGeo.east() - mouseStartGeo.east();
+		double dy = mouseGeo.north() - mouseStartGeo.north();
 		if (dx == 0 && dy == 0)
 			return;
 
 		Collection<OsmPrimitive> selection = Main.main.ds.getSelected();
-		Collection<Node> affectedNodes = MoveCommand.getAffectedNodes(selection);
+		Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
 		
 		// check if any coordinate would be outside the world
Index: src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 71)
@@ -27,5 +27,5 @@
  * If Alt key was hold, select all objects that are touched by the 
  * selection rectangle. If the Alt key was not hold, select only those objects 
- * completly within (e.g. for waies mean: only if all nodes of the way are 
+ * completly within (e.g. for ways mean: only if all nodes of the way are 
  * within).  
  *
Index: src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 70)
+++ src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 71)
@@ -4,5 +4,5 @@
 import java.awt.event.KeyEvent;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -52,5 +52,5 @@
 		if (r.width >= 3 && r.height >= 3) {
 			double scale = mv.getScale() * r.getWidth()/mv.getWidth();
-			GeoPoint newCenter = mv.getPoint(r.x+r.width/2, r.y+r.height/2, false);
+			EastNorth newCenter = mv.getEastNorth(r.x+r.width/2, r.y+r.height/2);
 			mv.zoomTo(newCenter, scale);
 		}
Index: src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/MoveCommand.java	(revision 70)
+++ src/org/openstreetmap/josm/command/MoveCommand.java	(revision 71)
@@ -7,4 +7,6 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -22,5 +24,5 @@
 	 * The objects that should be moved.
 	 */
-	public List<Node> objects = new LinkedList<Node>();
+	public Collection<Node> objects = new LinkedList<Node>();
 	/**
 	 * x difference movement. Coordinates are in northern/eastern 
@@ -53,11 +55,11 @@
 		this.x = x;
 		this.y = y;
-		this.objects = getAffectedNodes(objects);
+		this.objects = AllNodesVisitor.getAllNodes(objects);
 		for (Node n : this.objects) {
 			OldState os = new OldState();
-			os.x = n.coor.x;
-			os.y = n.coor.y;
-			os.lat = n.coor.lat;
-			os.lon = n.coor.lon;
+			os.x = n.eastNorth.east();
+			os.y = n.eastNorth.north();
+			os.lat = n.coor.lat();
+			os.lon = n.coor.lon();
 			os.modified = n.modified;
 			oldState.add(os);
@@ -65,15 +67,4 @@
 	}
 
-	/**
-	 * @return a list of all nodes that will be moved if using the given set of
-	 * objects.
-	 */
-	public static List<Node> getAffectedNodes(Collection<OsmPrimitive> objects) {
-		AllNodesVisitor visitor = new AllNodesVisitor();
-		for (OsmPrimitive osm : objects)
-			osm.visit(visitor);
-		return new LinkedList<Node>(visitor.nodes);
-	}
-	
 	/**
 	 * Move the same set of objects again by the specified vector. The vectors
@@ -86,7 +77,6 @@
 	public void moveAgain(double x, double y) {
 		for (Node n : objects) {
-			n.coor.x += x;
-			n.coor.y += y;
-			Main.pref.getProjection().xy2latlon(n.coor);
+			n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);
+			n.coor = Main.pref.getProjection().eastNorth2latlon(n.eastNorth);
 		}
 		this.x += x;
@@ -96,7 +86,6 @@
 	public void executeCommand() {
 		for (Node n : objects) {
-			n.coor.x += x;
-			n.coor.y += y;
-			Main.pref.getProjection().xy2latlon(n.coor);
+			n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);
+			n.coor = Main.pref.getProjection().eastNorth2latlon(n.eastNorth);
 			n.modified = true;
 		}
@@ -107,8 +96,6 @@
 		for (Node n : objects) {
 			OldState os = it.next();
-			n.coor.x = os.x;
-			n.coor.y = os.y;
-			n.coor.lat = os.lat;
-			n.coor.lon = os.lon;
+			n.eastNorth = new EastNorth(os.x, os.y);
+			n.coor = new LatLon(os.lat, os.lon);
 			n.modified = os.modified;
 		}
Index: src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- src/org/openstreetmap/josm/data/Bounds.java	(revision 70)
+++ src/org/openstreetmap/josm/data/Bounds.java	(revision 71)
@@ -1,10 +1,10 @@
 package org.openstreetmap.josm.data;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.projection.Projection;
 
 /**
- * This is a simple data class for "rectangular" areas of the world, given in lat/lon/min/max
- * values.
+ * This is a simple data class for "rectangular" areas of the world, given in 
+ * lat/lon min/max values.
  * 
  * Do not confuse this with "Area", which is an OSM-primitive for a vector of nodes, 
@@ -17,32 +17,10 @@
 	 * The minimum and maximum coordinates.
 	 */
-	public GeoPoint min, max;
+	public LatLon min, max;
 
 	/**
-	 * Return the center point based on the lat/lon values.
-	 *
-	 * @return The center of these bounds.
+	 * Construct bounds out of two points
 	 */
-	public GeoPoint centerLatLon() {
-		GeoPoint p = new GeoPoint((min.lat+max.lat) / 2, (min.lon+max.lon) / 2);
-		return p;
-	}
-
-	/**
-	 * Return the center point based on the x/y values.
-	 *
-	 * @return The center of these bounds.
-	 */
-	public GeoPoint centerXY() {
-		GeoPoint p = new GeoPoint();
-		p.x = (min.x+max.x) / 2;
-		p.y = (min.y+max.y) / 2;
-		return p;
-	}
-	
-	/**
-	 * Construct bounds out of two geopoints
-	 */
-	public Bounds(GeoPoint min, GeoPoint max) {
+	public Bounds(LatLon min, LatLon max) {
 		this.min = min;
 		this.max = max;
@@ -53,36 +31,6 @@
 	 */
 	public Bounds() {
-		min = new GeoPoint(-Projection.MAX_LAT, -Projection.MAX_LON);
-		Main.pref.getProjection().latlon2xy(min);
-		max = new GeoPoint(Projection.MAX_LAT, Projection.MAX_LON);
-		Main.pref.getProjection().latlon2xy(max);
-	}
-
-	/**
-	 * @return The bounding rectangle that covers <code>this</code> and 
-	 * 		the <code>other</code> bounds, regarding the x/y values.
-	 */
-	public Bounds mergeXY(Bounds other) {
-		GeoPoint nmin = new GeoPoint();
-		nmin.x = Math.min(min.x, other.min.x);
-		nmin.y = Math.min(min.y, other.min.y);
-		GeoPoint nmax = new GeoPoint();
-		nmax.x = Math.max(max.x, other.max.x);
-		nmax.y = Math.max(max.y, other.max.y);
-		return new Bounds(nmin, nmax);
-	}
-
-	/**
-	 * @return The bounding rectangle that covers <code>this</code> and 
-	 * 		the <code>other</code> bounds, regarding the lat/lon values.
-	 */
-	public Bounds mergeLatLon(Bounds other) {
-		GeoPoint nmin = new GeoPoint(
-				Math.min(min.lat, other.min.lat),
-				Math.min(min.lon, other.min.lon));
-		GeoPoint nmax = new GeoPoint(
-				Math.max(max.lat, other.max.lat),
-				Math.max(max.lon, other.max.lon));
-		return new Bounds(nmin, nmax);
+		min = new LatLon(-Projection.MAX_LAT, -Projection.MAX_LON);
+		max = new LatLon(Projection.MAX_LAT, Projection.MAX_LON);
 	}
 }
Index: src/org/openstreetmap/josm/data/GeoPoint.java
===================================================================
--- src/org/openstreetmap/josm/data/GeoPoint.java	(revision 70)
+++ 	(revision )
@@ -1,99 +1,0 @@
-package org.openstreetmap.josm.data;
-
-import org.openstreetmap.josm.data.projection.Projection;
-
-
-
-/**
- * An point holding latitude/longitude and their corresponding north/east values, 
- * which may not be initialized.
- *
- * if x or y is "NaN", these are not initialized yet.
- *
- * @author imi
- */
-public class GeoPoint implements Cloneable {
-
-	/**
-	 * Latitude/Longitude coordinates.
-	 */
-	public double lat = Double.NaN, lon = Double.NaN;
-
-	/**
-	 * East/North coordinates;
-	 */
-	public double x = Double.NaN, y = Double.NaN;
-
-	/**
-	 * Construct the point with latitude / longitude values.
-	 * The x/y values are left uninitialized.
-	 * 
-	 * @param lat Latitude of the point.
-	 * @param lon Longitude of the point.
-	 */
-	public GeoPoint(double lat, double lon) {
-		this.lat = lat;
-		this.lon = lon;
-	}
-
-	/**
-	 * Construct the point with all values available.
-	 */
-	public GeoPoint(double lat, double lon, double x, double y) {
-		this.lat = lat;
-		this.lon = lon;
-		this.x = x;
-		this.y = y;
-	}
-
-	/**
-	 * Construct the point with all values unset (set to NaN)
-	 */
-	public GeoPoint() {
-	}
-
-	@Override
-	public GeoPoint clone() {
-		try {return (GeoPoint)super.clone();} catch (CloneNotSupportedException e) {}
-		return null;
-	}
-
-	/**
-	 * Return the squared distance of the northing/easting values between 
-	 * this and the argument.
-	 *
-	 * @param other The other point to calculate the distance to.
-	 * @return The square of the distance between this and the other point,
-	 * 		regarding to the x/y values.
-	 */
-	public double distanceXY(GeoPoint other) {
-		return (x-other.x)*(x-other.x)+(y-other.y)*(y-other.y);
-	}
-
-	/**
-	 * @return <code>true</code>, if the other GeoPoint has the same lat/lon values.
-	 */
-	public boolean equalsLatLon(GeoPoint other) {
-		return lat == other.lat && lon == other.lon && 
-				!Double.isNaN(lat) && !Double.isNaN(lon);
-	}
-
-	/**
-	 * @return <code>true</code>, if the other GeoPoint has almost the same lat/lon
-	 * values, only differ by no more than 1/Projection.MAX_SERVER_PRECISION.
-	 */
-	public boolean equalsLatLonEpsilon(GeoPoint other) {
-		final double p = 1/Projection.MAX_SERVER_PRECISION;
-		return Math.abs(lat-other.lat) <= p && Math.abs(lon-other.lon) <= p && 
-				!Double.isNaN(lat) && !Double.isNaN(lon);
-	}
-
-	/**
-	 * @return <code>true</code>, if the coordinate is outside the world, compared
-	 * by using lat/lon.
-	 */
-	public boolean isOutSideWorld() {
-		return lat < -Projection.MAX_LAT || lat > Projection.MAX_LAT || 
-			lon < -Projection.MAX_LON || lon > Projection.MAX_LON;
-	}
-}
Index: src/org/openstreetmap/josm/data/coor/Coordinate.java
===================================================================
--- src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 71)
+++ src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 71)
@@ -0,0 +1,61 @@
+package org.openstreetmap.josm.data.coor;
+
+
+
+
+/**
+ * Base class of points of both coordinate system.
+ * 
+ * The variables are default package protected to allow routines in the data package
+ * to access them directly.
+ * 
+ * As the class itself is package protected too, it is not visible outside of the data
+ * package. Routines there should only use LatLon or EastNorth
+ *
+ * @author imi
+ */ 
+abstract class Coordinate {
+
+	/**
+	 * Either easting or latitude
+	 */
+	double x;
+	/**
+	 * Either northing or longitude
+	 */
+	double y;
+
+	/**
+	 * Construct the point with latitude / longitude values.
+	 * The x/y values are left uninitialized.
+	 * 
+	 * @param lat Latitude of the point.
+	 * @param lon Longitude of the point.
+	 */
+	Coordinate(double x, double y) {
+		this.x = x;
+		this.y = y;
+	}
+
+	/**
+	 * Return the squared distance of the northing/easting values between 
+	 * this and the argument.
+	 *
+	 * @param other The other point to calculate the distance to.
+	 * @return The square of the distance between this and the other point,
+	 * 		regarding to the x/y values.
+	 */
+	public double distance(Coordinate other) {
+		return (x-other.x)*(x-other.x)+(y-other.y)*(y-other.y);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		return obj instanceof EastNorth ? x == ((EastNorth)obj).x && ((EastNorth)obj).y == y : false;
+	}
+
+	@Override
+	public int hashCode() {
+		return (int)(x*65536+y*4096);
+	}
+}
Index: src/org/openstreetmap/josm/data/coor/EastNorth.java
===================================================================
--- src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 71)
+++ src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 71)
@@ -0,0 +1,23 @@
+package org.openstreetmap.josm.data.coor;
+
+/**
+ * Northern, Easting of the projected coordinates.
+ * 
+ * This class is immutable.
+ * 
+ * @author Imi
+ */
+public class EastNorth extends Coordinate {
+
+	public EastNorth(double east, double north) {
+		super(east,north);
+	}
+	
+	public double east() {
+		return x;
+	}
+
+	public double north() {
+		return y;
+	}
+}
Index: src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 71)
+++ src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 71)
@@ -0,0 +1,43 @@
+package org.openstreetmap.josm.data.coor;
+
+import org.openstreetmap.josm.data.projection.Projection;
+
+/**
+ * LatLon are unprojected latitude / longitude coordinates.
+ * 
+ * This class is immutable.
+ * 
+ * @author Imi
+ */
+public class LatLon extends Coordinate {
+
+	public LatLon(double lat, double lon) {
+		super(lon, lat);
+	}
+
+	public double lat() {
+		return y;
+	}
+
+	public double lon() {
+		return x;
+	}
+
+	/**
+	 * @return <code>true</code>, if the other point has almost the same lat/lon
+	 * values, only differ by no more than 1/Projection.MAX_SERVER_PRECISION.
+	 */
+	public boolean equalsEpsilon(LatLon other) {
+		final double p = 1/Projection.MAX_SERVER_PRECISION;
+		return Math.abs(lat()-other.lat()) <= p && Math.abs(lon()-other.lon()) <= p;
+	}
+
+	/**
+	 * @return <code>true</code>, if the coordinate is outside the world, compared
+	 * by using lat/lon.
+	 */
+	public boolean isOutSideWorld() {
+		return lat() < -Projection.MAX_LAT || lat() > Projection.MAX_LAT || 
+			lon() < -Projection.MAX_LON || lon() > Projection.MAX_LON;
+	}
+}
Index: src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 71)
@@ -5,5 +5,4 @@
 import java.util.LinkedList;
 
-import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.SelectionTracker;
 
@@ -21,5 +20,5 @@
 
 	/**
-	 * All nodes goes here, even when included in other data (waies etc).
+	 * All nodes goes here, even when included in other data (ways etc).
 	 * This enables the instant conversion of the whole DataSet by iterating over
 	 * this data structure.
@@ -33,5 +32,5 @@
 
 	/**
-	 * All waies (Streets etc.) in the DataSet. 
+	 * All ways (Streets etc.) in the DataSet. 
 	 * 
 	 * The nodes of the way segments of this way must be objects from 
@@ -39,5 +38,5 @@
 	 * way list.
 	 */
-	public Collection<Way> waies = new LinkedList<Way>();
+	public Collection<Way> ways = new LinkedList<Way>();
 
 	/**
@@ -49,5 +48,5 @@
 		o.addAll(nodes);
 		o.addAll(lineSegments);
-		o.addAll(waies);
+		o.addAll(ways);
 		return o;
 	}
@@ -63,67 +62,4 @@
 		return o;
 	}
-	
-	/**
-	 * Return the bounds of this DataSet, depending on X/Y values.
-	 * The min of the return value is the upper left GeoPoint, the max the lower
-	 * down GeoPoint, regarding to the X/Y values.
-	 * 
-	 * Return null, if any point not converted yet or if there are no points at all.
-	 * 
-	 * @return Bounding coordinate structure.
-	 */
-	public Bounds getBoundsXY() {
-		if (nodes.isEmpty())
-			return null;
-
-		Node first = nodes.iterator().next();
-		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
-		for (Node w : nodes)
-		{
-			if (Double.isNaN(w.coor.x) || Double.isNaN(w.coor.y))
-				return null;
-			if (w.coor.x < b.min.x)
-				b.min.x = w.coor.x;
-			if (w.coor.y < b.min.y)
-				b.min.y = w.coor.y;
-			if (w.coor.x > b.max.x)
-				b.max.x = w.coor.x;
-			if (w.coor.y > b.max.y)
-				b.max.y = w.coor.y;
-		}
-		return b;
-	}
-
-	/**
-	 * Return the bounds of this DataSet, depending on lat/lon values.
-	 * The min of the return value is the upper left GeoPoint, the max the lower
-	 * down GeoPoint.
-	 * 
-	 * Return null, if any point does not have lat/lon or if there are no 
-	 * points at all.
-	 * 
-	 * @return Bounding coordinate structure.
-	 */
-	public Bounds getBoundsLatLon() {
-		if (nodes.isEmpty())
-			return null;
-
-		Node first = nodes.iterator().next();
-		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
-		for (Node w : nodes)
-		{
-			if (Double.isNaN(w.coor.lat) || Double.isNaN(w.coor.lon))
-				return null;
-			if (w.coor.lat < b.min.lat)
-				b.min.lat = w.coor.lat;
-			if (w.coor.lon < b.min.lon)
-				b.min.lon = w.coor.lon;
-			if (w.coor.lat > b.max.lat)
-				b.max.lat = w.coor.lat;
-			if (w.coor.lon > b.max.lon)
-				b.max.lon = w.coor.lon;
-		}
-		return b;
-	}
 
 	/**
@@ -133,5 +69,5 @@
 		clearSelection(nodes);
 		clearSelection(lineSegments);
-		clearSelection(waies);
+		clearSelection(ways);
 	}
 
@@ -144,5 +80,5 @@
 		Collection<OsmPrimitive> sel = getSelected(nodes);
 		sel.addAll(getSelected(lineSegments));
-		sel.addAll(getSelected(waies));
+		sel.addAll(getSelected(ways));
 		return sel;
 	}
Index: src/org/openstreetmap/josm/data/osm/LineSegment.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/LineSegment.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/LineSegment.java	(revision 71)
@@ -1,5 +1,4 @@
 package org.openstreetmap.josm.data.osm;
 
-import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
@@ -16,5 +15,5 @@
 	 */
 	public Node from;
-	
+
 	/**
 	 * The ending node of the line segment
@@ -48,5 +47,5 @@
 		visitor.visit(this);
 	}
-	
+
 	/**
 	 * @return <code>true</code>, if the <code>ls</code> occupy
@@ -57,11 +56,7 @@
 			return true;
 		if (incomplete || ls.incomplete)
-			return false;
-		GeoPoint s1 = from.coor;
-		GeoPoint s2 = ls.from.coor;
-		GeoPoint e1 = to.coor;
-		GeoPoint e2 = ls.to.coor;
-		return ((s1.equalsLatLon(s2) && e1.equalsLatLon(e2)) ||
-				(s1.equalsLatLon(e2) && e1.equalsLatLon(s2)));
+			return incomplete == ls.incomplete;
+		return ((from.coor.equals(ls.from.coor) && to.coor.equals(ls.to.coor)) ||
+				(from.coor.equals(ls.to.coor) && to.coor.equals(ls.from.coor)));
 	}
 
Index: src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/Node.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/Node.java	(revision 71)
@@ -1,5 +1,7 @@
 package org.openstreetmap.josm.data.osm;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
@@ -12,11 +14,10 @@
 public class Node extends OsmPrimitive {
 	
-	/**
-	 * The coordinates of this node.
-	 */
-	public GeoPoint coor;
+	public LatLon coor;
+	public EastNorth eastNorth;
 
-	public Node(GeoPoint coor) {
-		this.coor = coor;
+	public Node(LatLon latlon) {
+		this.coor = latlon;
+		eastNorth = Main.pref.getProjection().latlon2eastNorth(latlon);
 	}
 
@@ -28,5 +29,5 @@
 	@Override
 	public String toString() {
-		return "{Node id="+id+",lat="+coor.lat+",lon="+coor.lon+"}";
+		return "{Node id="+id+",lat="+coor.lat()+",lon="+coor.lon()+"}";
 	}
 
@@ -34,6 +35,6 @@
 	public void cloneFrom(OsmPrimitive osm) {
 		super.cloneFrom(osm);
-		GeoPoint g = ((Node)osm).coor;
-		coor = new GeoPoint(g.lat, g.lon, g.x, g.y); //TODO: Make GeoPoint immutable!
+		coor = ((Node)osm).coor;
+		eastNorth = ((Node)osm).eastNorth;
 	}
 }
Index: src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 71)
@@ -30,5 +30,5 @@
 	}
 	public void visit(Way t) {
-		ds.waies.add(t);
+		ds.ways.add(t);
 	}
 }
Index: src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 71)
@@ -49,7 +49,8 @@
 	 * @return All nodes the given primitive has.
 	 */
-	public static Collection<Node> getAllNodes(OsmPrimitive osm) {
+	public static Collection<Node> getAllNodes(Collection<? extends OsmPrimitive> osms) {
 		AllNodesVisitor v = new AllNodesVisitor();
-		osm.visit(v);
+		for (OsmPrimitive osm : osms)
+			osm.visit(v);
 		return v.nodes;
 	}
Index: src/org/openstreetmap/josm/data/osm/visitor/BoundingVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/BoundingVisitor.java	(revision 70)
+++ 	(revision )
@@ -1,61 +1,0 @@
-package org.openstreetmap.josm.data.osm.visitor;
-
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.osm.LineSegment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.Way;
-
-/**
- * Calculates the total bounding rectangle of a serie of OsmPrimitives.
- * @author imi
- */
-public class BoundingVisitor implements Visitor {
-
-	/**
-	 * The bounding rectangle of all primitives visited so far.
-	 */
-	public Bounds bounds;
-
-	/**
-	 * Calculate regarding lat/lon or x/y?
-	 */
-	public static enum Type {LATLON, XY}
-	private Type type;
-
-
-	public BoundingVisitor(Type type) {
-		this.type = type;
-	}
-	
-
-	public void visit(Node n) {
-		if (bounds == null)
-			bounds = new Bounds(n.coor.clone(), n.coor.clone());
-		else {
-			if (type == Type.LATLON) {
-				bounds.min.lat = Math.min(bounds.min.lat, n.coor.lat);
-				bounds.min.lon = Math.min(bounds.min.lon, n.coor.lon);
-				bounds.max.lat = Math.max(bounds.max.lat, n.coor.lat);
-				bounds.max.lon = Math.max(bounds.max.lon, n.coor.lon);
-			} else {
-				bounds.min.x = Math.min(bounds.min.x, n.coor.x);
-				bounds.min.y = Math.min(bounds.min.y, n.coor.y);
-				bounds.max.x = Math.max(bounds.max.x, n.coor.x);
-				bounds.max.y = Math.max(bounds.max.y, n.coor.y);
-			}
-		}
-	}
-
-	public void visit(LineSegment ls) {
-		if (!ls.incomplete) {
-			visit(ls.from);
-			visit(ls.to);
-		}
-	}
-
-	public void visit(Way t) {
-		for (LineSegment ls : t.segments)
-			visit(ls);
-	}
-}
-
Index: src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 71)
+++ src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 71)
@@ -0,0 +1,57 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+
+/**
+ * Calculates the total bounding rectangle of a serie of OsmPrimitives, using the EastNorth values
+ * as reference.
+ * @author imi
+ */
+public class BoundingXYVisitor implements Visitor {
+
+	public EastNorth min, max;
+
+	public void visit(Node n) {
+		visit(n.eastNorth);
+	}
+
+	public void visit(LineSegment ls) {
+		if (!ls.incomplete) {
+			visit(ls.from);
+			visit(ls.to);
+		}
+	}
+
+	public void visit(Way t) {
+		for (LineSegment ls : t.segments)
+			visit(ls);
+	}
+
+	public void visit(EastNorth eastNorth) {
+		if (eastNorth != null) {
+			if (min == null)
+				min = eastNorth;
+			else if (eastNorth.east() < min.east() || eastNorth.north() < min.north())
+				min = new EastNorth(Math.min(min.east(), eastNorth.east()), Math.min(min.north(), eastNorth.north()));
+			
+			if (max == null)
+				max = eastNorth;
+			else if (eastNorth.east() > max.east() || eastNorth.north() > max.north())
+				max = new EastNorth(Math.max(max.east(), eastNorth.east()), Math.max(max.north(), eastNorth.north()));
+		}
+	}
+
+	/**
+	 * @return The bounding box or <code>null</code> if no coordinates have passed
+	 */
+	public Bounds getBounds() {
+		if (min == null || max == null)
+			return null;
+		return new Bounds(Main.pref.getProjection().eastNorth2latlon(min), Main.pref.getProjection().eastNorth2latlon(max));
+	}
+}
Index: src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 71)
@@ -11,5 +11,5 @@
 
 /**
- * Helper that collect all line segments a node is part of, all waies
+ * Helper that collect all line segments a node is part of, all ways
  * a node or line segment is part of and all areas a node is part of. 
  * 
@@ -37,5 +37,5 @@
 	
 	public void visit(Node n) {
-		for (Way t : ds.waies) {
+		for (Way t : ds.ways) {
 			if (t.isDeleted())
 				continue;
@@ -57,5 +57,5 @@
 	}
 	public void visit(LineSegment ls) {
-		for (Way t : ds.waies) {
+		for (Way t : ds.ways) {
 			if (t.isDeleted())
 				continue;
Index: src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 71)
@@ -30,5 +30,5 @@
 	}
 	public void visit(Way t) {
-		ds.waies.remove(t);
+		ds.ways.remove(t);
 	}
 }
Index: src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 71)
@@ -58,5 +58,5 @@
 			if (myNode.modified && !otherNode.modified)
 				return;
-			if (!myNode.coor.equalsLatLonEpsilon(otherNode.coor)) {
+			if (!myNode.coor.equalsEpsilon(otherNode.coor)) {
 				myNode.coor = otherNode.coor;
 				myNode.modified = otherNode.modified;
@@ -104,5 +104,5 @@
 	public void visit(Way otherWay) {
 		Way myWay = null;
-		for (Way t : ds.waies) {
+		for (Way t : ds.ways) {
 			if (match(otherWay, t)) {
 				myWay = t;
@@ -111,5 +111,5 @@
 		}
 		if (myWay == null)
-			ds.waies.add(otherWay);
+			ds.ways.add(otherWay);
 		else {
 			mergeCommon(myWay, otherWay);
@@ -141,5 +141,5 @@
 				ls.to = mergedNodes.get(ls.to);
 		}
-		for (Way t : ds.waies) {
+		for (Way t : ds.ways) {
 			boolean replacedSomething = false;
 			LinkedList<LineSegment> newSegments = new LinkedList<LineSegment>();
@@ -168,5 +168,5 @@
 	private boolean match(Node n1, Node n2) {
 		if (n1.id == 0 || n2.id == 0)
-			return n1.coor.equalsLatLonEpsilon(n2.coor);
+			return n1.coor.equalsEpsilon(n2.coor);
 		return n1.id == n2.id;
 	}
@@ -184,5 +184,5 @@
 
 	/**
-	 * @return Whether the waies matches (in sense of "be mergable").
+	 * @return Whether the ways matches (in sense of "be mergable").
 	 */
 	private boolean match(Way t1, Way t2) {
Index: src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 71)
@@ -10,5 +10,5 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.gui.ImageProvider;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -36,8 +36,10 @@
 	public void visit(LineSegment ls) {
 		name = ls.get("name");
-		if (name == null && ls.incomplete)
-			name = ""+ls.id;
-		if (name == null)
-			name = "("+ls.from.coor.lat+","+ls.from.coor.lon+") -> ("+ls.to.coor.lat+","+ls.to.coor.lon+")";
+		if (name == null) {
+			if (ls.incomplete)
+				name = ""+ls.id;
+			else
+				name = ls.id+" ("+ls.from.coor.lat()+","+ls.from.coor.lon()+") -> ("+ls.to.coor.lat()+","+ls.to.coor.lon()+")";
+		}
 		icon = ImageProvider.get("data", "linesegment");
 	}
@@ -50,5 +52,5 @@
 		name = n.get("name");
 		if (name == null)
-			name = "("+n.coor.lat+","+n.coor.lon+")";
+			name = n.id+" ("+n.coor.lat()+","+n.coor.lon()+")";
 		icon = ImageProvider.get("data", "node");
 	}
@@ -61,4 +63,5 @@
 		name = w.get("name");
 		if (name == null) {
+			AllNodesVisitor.getAllNodes(w.segments);
 			Set<Node> nodes = new HashSet<Node>();
 			for (LineSegment ls : w.segments) {
Index: src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 70)
+++ src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 71)
@@ -84,5 +84,5 @@
 	 */
 	private void drawNode(Node n, Color color) {
-		Point p = nc.getScreenPoint(n.coor);
+		Point p = nc.getPoint(n.eastNorth);
 		g.setColor(color);
 		g.drawRect(p.x-1, p.y-1, 2, 2);
@@ -98,6 +98,6 @@
 			col = Color.WHITE;
 		g.setColor(col);
-		Point p1 = nc.getScreenPoint(ls.from.coor);
-		Point p2 = nc.getScreenPoint(ls.to.coor);
+		Point p1 = nc.getPoint(ls.from.eastNorth);
+		Point p2 = nc.getPoint(ls.to.eastNorth);
 		g.drawLine(p1.x, p1.y, p2.x, p2.y);
 	}
Index: src/org/openstreetmap/josm/data/projection/Epsg4263.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Epsg4263.java	(revision 70)
+++ src/org/openstreetmap/josm/data/projection/Epsg4263.java	(revision 71)
@@ -1,5 +1,6 @@
 package org.openstreetmap.josm.data.projection;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 
 /**
@@ -10,12 +11,10 @@
 public class Epsg4263 implements Projection {
 
-	public void latlon2xy(GeoPoint p) {
-		p.x = p.lon;
-		p.y = p.lat;
+	public EastNorth latlon2eastNorth(LatLon p) {
+		return new EastNorth(p.lon(), p.lat());
 	}
 
-	public void xy2latlon(GeoPoint p) {
-		p.lat = p.y;
-		p.lon = p.x;
+	public LatLon eastNorth2latlon(EastNorth p) {
+		return new LatLon(p.north(), p.east());
 	}
 
Index: src/org/openstreetmap/josm/data/projection/Mercator.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 70)
+++ src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 71)
@@ -1,5 +1,6 @@
 package org.openstreetmap.josm.data.projection;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 
 /**
@@ -14,12 +15,14 @@
 public class Mercator implements Projection {
 
-	public void latlon2xy(GeoPoint p) {
-		p.x = p.lon*Math.PI/180;
-		p.y = Math.log(Math.tan(Math.PI/4+p.lat*Math.PI/360));
+	public EastNorth latlon2eastNorth(LatLon p) {
+		return new EastNorth(
+			p.lon()*Math.PI/180,
+			Math.log(Math.tan(Math.PI/4+p.lat()*Math.PI/360)));
 	}
 
-	public void xy2latlon(GeoPoint p) {
-		p.lon = p.x*180/Math.PI;
-		p.lat = Math.atan(Math.sinh(p.y))*180/Math.PI;
+	public LatLon eastNorth2latlon(EastNorth p) {
+		return new LatLon(
+			p.east()*180/Math.PI,
+			Math.atan(Math.sinh(p.north()))*180/Math.PI);
 	}
 
Index: src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Projection.java	(revision 70)
+++ src/org/openstreetmap/josm/data/projection/Projection.java	(revision 71)
@@ -1,5 +1,6 @@
 package org.openstreetmap.josm.data.projection;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 
 /**
@@ -20,5 +21,5 @@
 	 * @param p		The geo point to convert. x/y members of the point are filled.
 	 */
-	void latlon2xy(GeoPoint p);
+	EastNorth latlon2eastNorth(LatLon p);
 	
 	/**
@@ -27,5 +28,5 @@
 	 * @param p		The geo point to convert. lat/lon members of the point are filled.
 	 */
-	void xy2latlon(GeoPoint p);
+	LatLon eastNorth2latlon(EastNorth p);
 
 	/**
Index: src/org/openstreetmap/josm/gui/BookmarkList.java
===================================================================
--- src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 71)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
Index: src/org/openstreetmap/josm/gui/BugReportExceptionHandler.java
===================================================================
--- src/org/openstreetmap/josm/gui/BugReportExceptionHandler.java	(revision 70)
+++ 	(revision )
@@ -1,78 +1,0 @@
-package org.openstreetmap.josm.gui;
-
-import java.awt.GridBagLayout;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URL;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-
-import org.openstreetmap.josm.Main;
-
-/**
- * An exception handler, that ask the user to send a bug report.
- * 
- * @author imi
- */
-public final class BugReportExceptionHandler implements Thread.UncaughtExceptionHandler {
-	public void uncaughtException(Thread t, Throwable e) {
-		e.printStackTrace();
-		if (Main.main != null) {
-			Object[] options = new String[]{"Do nothing", "Report Bug"};
-			int answer = JOptionPane.showOptionDialog(Main.main, "An unexpected exception occoured.\n\n" +
-					"This is always a coding error. If you are running the latest\n" +
-					"version of JOSM, please consider be kind and file a bug report.",
-					"Unexpected Exception", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE,
-					null, options, options[0]);
-			if (answer == 1) {
-				try {
-					StringWriter stack = new StringWriter();
-					e.printStackTrace(new PrintWriter(stack));
-
-					URL revUrl = Main.class.getResource("/REVISION");
-					StringBuilder sb = new StringBuilder("Please send this to josm@eigenheimstrasse.de\n\n");
-					if (revUrl == null) {
-						sb.append("Development version. Unknown revision.");
-						File f = new File("org/openstreetmap/josm/Main.class");
-						if (!f.exists())
-							f = new File("bin/org/openstreetmap/josm/Main.class");
-						if (f.exists()) {
-							DateFormat sdf = SimpleDateFormat.getDateTimeInstance();
-							sb.append("\nMain.class build on "+sdf.format(new Date(f.lastModified())));
-							sb.append("\n");
-						}
-					} else {
-						BufferedReader in = new BufferedReader(new InputStreamReader(revUrl.openStream()));
-						for (String line = in.readLine(); line != null; line = in.readLine()) {
-							sb.append(line);
-							sb.append('\n');
-						}
-					}
-					sb.append("\n"+stack.getBuffer().toString());
-
-					JPanel p = new JPanel(new GridBagLayout());
-					p.add(new JLabel("Please send an email with the following information to josm@eigenheimstrasse.de"), GBC.eop());
-
-					JTextArea info = new JTextArea(sb.toString(), 20, 60);
-					info.setCaretPosition(0);
-					info.setEditable(false);
-					p.add(new JScrollPane(info), GBC.eop());
-
-					JOptionPane.showMessageDialog(Main.main, p);
-				} catch (Exception e1) {
-					e1.printStackTrace();
-				}
-			}
-		}
-	}
-}
Index: src/org/openstreetmap/josm/gui/GBC.java
===================================================================
--- src/org/openstreetmap/josm/gui/GBC.java	(revision 70)
+++ 	(revision )
@@ -1,109 +1,0 @@
-package org.openstreetmap.josm.gui;
-
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridBagConstraints;
-import java.awt.Insets;
-
-import javax.swing.Box;
-
-/**
- * A wrapper for GridBagConstraints which has sane default static creators and
- * member functions to chain calling.
- * 
- * @author imi
- */
-public class GBC extends GridBagConstraints {
-
-	/**
-	 * Use public static creator functions to create an GBC.
-	 */
-	private GBC() {}
-	
-	/**
-	 * Create a standard constraint (which is not the last).
-	 * @return A standard constraint with no filling.
-	 */
-	public static GBC std() {
-		GBC c = new GBC();
-		c.anchor = WEST;
-		return c;
-	}
-	
-	/**
-	 * Create the constraint for the last elements on a line.
-	 * @return A constraint which indicates the last item on a line.
-	 */
-	public static GBC eol() {
-		GBC c = std();
-		c.gridwidth = REMAINDER;
-		return c;
-	}
-	
-	/**
-	 * Create the constraint for the last elements on a line and on a paragraph.
-	 * This is merely a shortcut for eol().insets(0,0,0,10)
-	 * @return A constraint which indicates the last item on a line.
-	 */
-	public static GBC eop() {
-		return eol().insets(0,0,0,10);
-	}
-
-	/**
-	 * Try to fill both, horizontal and vertical
-	 * @return This constraint for chaining.
-	 */
-	public GBC fill() {
-		return fill(BOTH);
-	}
-
-	/**
-	 * Set fill to the given value
-	 * @param value The filling value, either NONE, HORIZONTAL, VERTICAL or BOTH
-	 * @return This constraint for chaining.
-	 */
-	public GBC fill(int value) {
-		fill = value;
-		if (value == HORIZONTAL || value == BOTH)
-			weightx = 1.0;
-		if (value == VERTICAL || value == BOTH)
-			weighty = 1.0;
-		return this;
-	}
-	
-	/**
-	 * Set the anchor of this GBC to a.
-	 * @param a The new anchor, e.g. GBC.CENTER or GBC.EAST.
-	 * @return This constraint for chaining.
-	 */
-	public GBC anchor(int a) {
-		anchor = a;
-		return this;
-	}
-
-	/**
-	 * Adds insets to this GBC.
-	 * @param left		The left space of the insets
-	 * @param top		The top space of the insets
-	 * @param right		The right space of the insets
-	 * @param bottom	The bottom space of the insets
-	 * @return This constraint for chaining.
-	 */
-	public GBC insets(int left, int top, int right, int bottom) {
-		insets = new Insets(top, left, bottom, right);
-		return this;
-	}
-	
-	/**
-	 * This is a helper to easily create a glue with a minimum default value.
-	 * @param x If higher than 0, this will be a horizontal glue with x as minimum
-	 * 		horizontal strut.
-	 * @param y If higher than 0, this will be a vertical glue with y as minimum
-	 * 		vertical strut.
-	 */
-	public static Component glue(int x, int y) {
-		short maxx = x > 0 ? Short.MAX_VALUE : 0;
-		short maxy = y > 0 ? Short.MAX_VALUE : 0;
-		return new Box.Filler(new Dimension(x,y), new Dimension(x,y), new Dimension(maxx,maxy));
-	}
-}
Index: src/org/openstreetmap/josm/gui/ImageProvider.java
===================================================================
--- src/org/openstreetmap/josm/gui/ImageProvider.java	(revision 70)
+++ 	(revision )
@@ -1,89 +1,0 @@
-package org.openstreetmap.josm.gui;
-
-import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsEnvironment;
-import java.awt.Transparency;
-import java.awt.image.BufferedImage;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-
-import org.openstreetmap.josm.Main;
-
-/**
- * Helperclass to support the application with images.
- * @author imi
- */
-public class ImageProvider {
-
-	/**
-	 * Position of an overlay icon
-	 * @author imi
-	 */
-	public enum OverlayPosition {NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST}
-	
-	/**
-	 * The icon cache
-	 */
-	private static Map<URL, ImageIcon> cache = new HashMap<URL, ImageIcon>();
-	
-	/**
-	 * Return an image from the specified location.
-	 *
-	 * @param subdir	The position of the directory, e.g. "layer"
-	 * @param name		The icons name (without the ending of ".png")
-	 * @return	The requested ImageIcon.
-	 */
-	public static ImageIcon get(String subdir, String name) {
-		if (subdir != "")
-			subdir += "/";
-		URL path = Main.class.getResource("/images/"+subdir+name+".png");
-		if (path == null)
-			throw new NullPointerException("/images/"+subdir+name+".png not found");
-		ImageIcon icon = cache.get(path);
-		if (icon == null) {
-			icon = new ImageIcon(path);
-			cache.put(path, icon);
-		}
-		return icon;
-	}
-
-	/**
-	 * Shortcut for get("", name);
-	 */
-	public static ImageIcon get(String name) {
-		return get("", name);
-	}
-
-	/**
-	 * 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.
-	 *
-	 * @param ground The ground icon (base)
-	 * @param overlay The icon to put on top of the ground (overlay)
-	 * @return The merged icon.
-	 */
-	public static Icon overlay(Icon ground, Icon overlay, OverlayPosition pos) {
-		GraphicsConfiguration conf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
-		int w = ground.getIconWidth();
-		int h = ground.getIconHeight();
-		int wo = overlay.getIconWidth();
-		int ho = overlay.getIconHeight();
-		BufferedImage img = conf.createCompatibleImage(w,h, Transparency.TRANSLUCENT);
-		Graphics g = img.createGraphics();
-		ground.paintIcon(null, g, 0, 0);
-		int x = 0, y = 0;
-		switch (pos) {
-		case NORTHWEST: x = 0;		y = 0;		break;
-		case NORTHEAST: x = w-wo;	y = 0;		break;
-		case SOUTHWEST: x = 0;		y = h-ho;	break;
-		case SOUTHEAST: x = w-wo;	y = h-ho;	break;
-		}
-		overlay.paintIcon(null, g, x, y);
-		return new ImageIcon(img);
-	}
-}
Index: src/org/openstreetmap/josm/gui/MapMover.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapMover.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/MapMover.java	(revision 71)
@@ -8,5 +8,5 @@
 import java.awt.event.MouseWheelListener;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.EastNorth;
 
 /**
@@ -22,5 +22,5 @@
 	 * when moving around started.
 	 */
-	private GeoPoint mousePosMove;
+	private EastNorth mousePosMove;
 	/**
 	 * The map to move around.
@@ -51,9 +51,9 @@
 			if (mousePosMove == null)
 				startMovement(e);
-			GeoPoint center = nc.getCenter();
-			GeoPoint mouseCenter = nc.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;
+			EastNorth center = nc.getCenter();
+			EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
+			EastNorth p = new EastNorth(
+					mousePosMove.east() + center.east() - mouseCenter.east(),
+					mousePosMove.north() + center.north() - mouseCenter.north());
 			nc.zoomTo(p, nc.getScale());
 		} else
@@ -86,5 +86,5 @@
 	 */
 	private void startMovement(MouseEvent e) {
-		mousePosMove = nc.getPoint(e.getX(), e.getY(), false);
+		mousePosMove = nc.getEastNorth(e.getX(), e.getY());
 		oldCursor = nc.getCursor();
 		nc.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
@@ -108,11 +108,16 @@
 	 */
 	public void mouseWheelMoved(MouseWheelEvent e) {
+		int w = nc.getWidth();
+		int h = nc.getHeight();
+
 		double zoom = Math.max(0.1, 1 + e.getWheelRotation()/5.0);
-		double zoomfactor = (zoom -1)/2+1;
-		int newHalfWidth = (int) (nc.getWidth()*zoomfactor - nc.getWidth()/2);
-		int centerx = e.getX() - (e.getX()-nc.getWidth()/2)*newHalfWidth*2/nc.getWidth();
-		int newHalfHeight = (int) (nc.getHeight()*zoomfactor - nc.getHeight()/2);
-		int centery = e.getY() - (e.getY()-nc.getHeight()/2)*newHalfHeight*2/nc.getHeight();
-		GeoPoint newCenter = nc.getPoint(centerx, centery, false); 
+		double zoomfactor = (zoom-1)/2+1;
+
+		double newHalfWidth = w*zoomfactor - w/2;
+		double newHalfHeight = h*zoomfactor - h/2;
+		double centerx = e.getX() - (e.getX()-w/2)*newHalfWidth*2/w;
+		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/MapStatus.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapStatus.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/MapStatus.java	(revision 71)
@@ -27,7 +27,8 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.SelectionComponentVisitor;
+import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -205,6 +206,6 @@
 				// Do not update the view, if ctrl is pressed.
 				if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == 0) {
-					GeoPoint p = mv.getPoint(e.getX(),e.getY(),true);
-					positionText.setText(p.lat+" "+p.lon);
+					LatLon p = mv.getLatLon(e.getX(),e.getY());
+					positionText.setText(p.lat()+" "+p.lon());
 				}
 			}
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 71)
@@ -18,6 +18,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -176,6 +177,6 @@
 		g.setColor(Color.WHITE);
 		Bounds b = new Bounds();
-		Point min = getScreenPoint(b.min);
-		Point max = getScreenPoint(b.max);
+		Point min = getPoint(getProjection().latlon2eastNorth(b.min));
+		Point max = getPoint(getProjection().latlon2eastNorth(b.max));
 		int x1 = Math.min(min.x, max.x);
 		int y1 = Math.min(min.y, max.y);
@@ -217,33 +218,25 @@
 				h = 20;
 
-			Bounds bounds = null;
-			for (Layer l : layers) {
-				if (bounds == null)
-					bounds = l.getBoundsXY();
-				else {
-					Bounds lb = l.getBoundsXY();
-					if (lb != null)
-						bounds = bounds.mergeXY(lb);
-				}
-			}
+			BoundingXYVisitor v = new BoundingXYVisitor();
+			for (Layer l : layers)
+				l.visitBoundingBox(v);
 
 			boolean oldAutoScale = autoScale;
-			GeoPoint oldCenter = center;
+			EastNorth oldCenter = center;
 			double oldScale = this.scale;
 			
-			if (bounds == null) {
+			if (v.min == null || v.max == null) {
 				// no bounds means standard scale and center 
-				center = new GeoPoint(51.526447, -0.14746371);
-				getProjection().latlon2xy(center);
+				center = new EastNorth(51.526447, -0.14746371);
 				scale = 10;
 			} else {
-				center = bounds.centerXY();
-				getProjection().xy2latlon(center);
-				double scaleX = (bounds.max.x-bounds.min.x)/w;
-				double scaleY = (bounds.max.y-bounds.min.y)/h;
+				center = new EastNorth(v.min.east()/2+v.max.east()/2, v.min.north()/2+v.max.north()/2);
+				double scaleX = (v.max.east()-v.min.east())/w;
+				double scaleY = (v.max.north()-v.min.north())/h;
 				scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
 			}
 	
-			firePropertyChange("center", oldCenter, center);
+			if (!center.equals(oldCenter))
+				firePropertyChange("center", oldCenter, center);
 			if (oldAutoScale != autoScale)
 				firePropertyChange("autoScale", oldAutoScale, autoScale);
@@ -318,7 +311,7 @@
 	 */
 	@Override
-	public void zoomTo(GeoPoint newCenter, double scale) {
+	public void zoomTo(EastNorth newCenter, double scale) {
 		boolean oldAutoScale = autoScale;
-		GeoPoint oldCenter = center;
+		EastNorth oldCenter = center;
 		double oldScale = this.scale;
 		autoScale = false;
@@ -328,5 +321,6 @@
 		recalculateCenterScale();
 		
-		firePropertyChange("center", oldCenter, center);
+		if (!oldCenter.equals(center))
+			firePropertyChange("center", oldCenter, center);
 		if (oldAutoScale != autoScale)
 			firePropertyChange("autoScale", oldAutoScale, autoScale);
Index: src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 71)
@@ -8,5 +8,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
@@ -32,5 +33,5 @@
 	 * Center n/e coordinate of the desired screen center.
 	 */
-	protected GeoPoint center;
+	protected EastNorth center;
 
 	/**
@@ -46,50 +47,44 @@
 	 * 		change the center by accessing the return value. Use zoomTo instead.
 	 */
-	public GeoPoint getCenter() {
-		return center.clone();
-	}
-
-	/**
-	 * Get geographic coordinates from a specific pixel coordination
-	 * on the screen.
-	 * 
-	 * If you don't need it, provide false at third parameter to speed
-	 * up the calculation.
-	 *  
+	public EastNorth getCenter() {
+		return center;
+	}
+
+	/**
 	 * @param x X-Pixelposition to get coordinate from
 	 * @param y Y-Pixelposition to get coordinate from
-	 * @param latlon If set, the return value will also have the 
-	 * 				 latitude/longitude filled.
-	 * 
-	 * @return The geographic coordinate, filled with x/y (northing/easting)
-	 * 		settings and, if requested with latitude/longitude.
-	 */
-	public GeoPoint getPoint(int x, int y, boolean latlon) {
-		GeoPoint p = new GeoPoint();
-		p.x = center.x + (x - getWidth()/2.0)*scale;
-		p.y = center.y - (y - getHeight()/2.0)*scale;
-		if (latlon)
-			getProjection().xy2latlon(p);
-		return p;
-	}
-
-	/**
-	 * Return the point on the screen where this GeoPoint would be.
+	 * 
+	 * @return Geographic coordinates from a specific pixel coordination
+	 * 		on the screen.
+	 */
+	public EastNorth getEastNorth(int x, int y) {
+		return new EastNorth(
+				center.east() + (x - getWidth()/2.0)*scale,
+				center.north() - (y - getHeight()/2.0)*scale);
+	}
+
+	/**
+	 * @param x X-Pixelposition to get coordinate from
+	 * @param y Y-Pixelposition to get coordinate from
+	 * 
+	 * @return Geographic unprojected coordinates from a specific pixel coordination
+	 * 		on the screen.
+	 */
+	public LatLon getLatLon(int x, int y) {
+		EastNorth eastNorth = new EastNorth(
+				center.east() + (x - getWidth()/2.0)*scale,
+				center.north() - (y - getHeight()/2.0)*scale);
+		return Main.pref.getProjection().eastNorth2latlon(eastNorth);
+	}
+
+	/**
+	 * Return the point on the screen where this Coordinate 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();
-			getProjection().latlon2xy(p);
-		}
-		double x = (p.x-center.x)/scale + getWidth()/2;
-		double y = (center.y-p.y)/scale + getHeight()/2;
+	public Point getPoint(EastNorth p) {
+		double x = (p.east()-center.east())/scale + getWidth()/2;
+		double y = (center.north()-p.north())/scale + getHeight()/2;
 		return new Point((int)x,(int)y);
 	}
@@ -101,7 +96,7 @@
 	 * @param scale The scale to use.
 	 */
-	public void zoomTo(GeoPoint newCenter, double scale) {
-		center = newCenter.clone();
-		getProjection().xy2latlon(center);
+	public void zoomTo(EastNorth newCenter, double scale) {
+		center = newCenter;
+		getProjection().eastNorth2latlon(center);
 		this.scale = scale;
 		repaint();
@@ -127,9 +122,9 @@
 	 * 
 	 * @param p				 The point on screen.
-	 * @param lsInsteadWay Whether the line segment (true) or only the whole
+	 * @param segmentInsteadWay Whether the line segment (true) or only the whole
 	 * 					 	 way should be returned.
 	 * @return	The primitive, that is nearest to the point p.
 	 */
-	public OsmPrimitive getNearest(Point p, boolean lsInsteadWay) {
+	public OsmPrimitive getNearest(Point p, boolean segmentInsteadWay) {
 		double minDistanceSq = Double.MAX_VALUE;
 		OsmPrimitive minPrimitive = null;
@@ -139,5 +134,5 @@
 			if (n.isDeleted())
 				continue;
-			Point sp = getScreenPoint(n.coor);
+			Point sp = getPoint(n.eastNorth);
 			double dist = p.distanceSq(sp);
 			if (minDistanceSq > dist && dist < 100) {
@@ -151,6 +146,6 @@
 		// for whole ways, try the ways first
 		minDistanceSq = Double.MAX_VALUE;
-		if (!lsInsteadWay) {
-			for (Way w : Main.main.ds.waies) {
+		if (!segmentInsteadWay) {
+			for (Way w : Main.main.ds.ways) {
 				if (w.isDeleted())
 					continue;
@@ -158,6 +153,6 @@
 					if (ls.isDeleted() || ls.incomplete)
 						continue;
-					Point A = getScreenPoint(ls.from.coor);
-					Point B = getScreenPoint(ls.to.coor);
+					Point A = getPoint(ls.from.eastNorth);
+					Point B = getPoint(ls.to.eastNorth);
 					double c = A.distanceSq(B);
 					double a = p.distanceSq(B);
@@ -179,6 +174,6 @@
 			if (ls.isDeleted() || ls.incomplete)
 				continue;
-			Point A = getScreenPoint(ls.from.coor);
-			Point B = getScreenPoint(ls.to.coor);
+			Point A = getPoint(ls.from.eastNorth);
+			Point B = getPoint(ls.to.eastNorth);
 			double c = A.distanceSq(B);
 			double a = p.distanceSq(B);
@@ -201,10 +196,10 @@
 	 * If its a node, return all line segments and
 	 * streets the node is part of, as well as all nodes
-	 * (with their line segments and waies) with the same
+	 * (with their line segments and ways) with the same
 	 * location.
 	 * 
-	 * If its a line segment, return all waies this segment 
+	 * If its a line segment, return all ways this segment 
 	 * belongs to as well as all line segments that are between
-	 * the same nodes (in both direction) with all their waies.
+	 * the same nodes (in both direction) with all their ways.
 	 * 
 	 * @return A collection of all items or <code>null</code>
@@ -221,5 +216,5 @@
 			Node node = (Node)osm;
 			for (Node n : Main.main.ds.nodes)
-				if (!n.isDeleted() && n.coor.equalsLatLon(node.coor))
+				if (!n.isDeleted() && n.coor.equals(node.coor))
 					c.add(n);
 			for (LineSegment ls : Main.main.ds.lineSegments)
@@ -235,5 +230,5 @@
 		}
 		if (osm instanceof Node || osm instanceof LineSegment) {
-			for (Way t : Main.main.ds.waies) {
+			for (Way t : Main.main.ds.ways) {
 				if (t.isDeleted())
 					continue;
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 71)
@@ -31,4 +31,6 @@
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
 import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
Index: src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 71)
@@ -257,5 +257,5 @@
 	 * @param alt Whether the alt key was pressed, which means select all objects
 	 * 		that are touched, instead those which are completly covered. Also 
-	 * 		select whole waies instead of line segments.
+	 * 		select whole ways instead of line segments.
 	 */
 	public Collection<OsmPrimitive> getObjectsInRectangle(Rectangle r, boolean alt) {
@@ -273,5 +273,5 @@
 			// nodes
 			for (Node n : Main.main.ds.nodes) {
-				if (r.contains(nc.getScreenPoint(n.coor)))
+				if (r.contains(nc.getPoint(n.eastNorth)))
 					selection.add(n);
 			}
@@ -282,6 +282,6 @@
 					selection.add(ls);
 
-			// waies
-			for (Way t : Main.main.ds.waies) {
+			// ways
+			for (Way t : Main.main.ds.ways) {
 				boolean wholeWaySelected = !t.segments.isEmpty();
 				for (LineSegment ls : t.segments)
@@ -312,11 +312,11 @@
 			return false;
 		if (alt) {
-			Point p1 = nc.getScreenPoint(ls.from.coor);
-			Point p2 = nc.getScreenPoint(ls.to.coor);
+			Point p1 = nc.getPoint(ls.from.eastNorth);
+			Point p2 = nc.getPoint(ls.to.eastNorth);
 			if (r.intersectsLine(p1.x, p1.y, p2.x, p2.y))
 				return true;
 		} else {
-			if (r.contains(nc.getScreenPoint(ls.from.coor))
-					&& r.contains(nc.getScreenPoint(ls.to.coor)))
+			if (r.contains(nc.getPoint(ls.from.eastNorth))
+					&& r.contains(nc.getPoint(ls.to.eastNorth)))
 				return true;
 		}
Index: src/org/openstreetmap/josm/gui/WorldChooser.java
===================================================================
--- src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 71)
@@ -19,6 +19,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.BookmarkList.Bookmark;
@@ -48,5 +48,5 @@
 	 * Mark this rectangle (lat/lon values) when painting.
 	 */
-	protected Bounds marker;
+	private EastNorth markerMin, markerMax;
 
 	private Projection projection;
@@ -58,15 +58,17 @@
 		URL path = Main.class.getResource("/images/world.jpg");
 		world = new ImageIcon(path);
-		center = new GeoPoint(0,0,world.getIconWidth()/2, world.getIconHeight()/2);
+		center = new EastNorth(world.getIconWidth()/2, world.getIconHeight()/2);
 		setPreferredSize(new Dimension(200, 100));
 		new MapMover(this);
-		projection = new Projection(){
-			public void latlon2xy(GeoPoint p) {
-				p.x = (p.lon+180) / 360 * world.getIconWidth();
-				p.y = (p.lat+90) / 180 * world.getIconHeight();
-			}
-			public void xy2latlon(GeoPoint p) {
-				p.lon = p.x*360/world.getIconWidth() - 180;
-				p.lat = p.y*180/world.getIconHeight() - 90;
+		projection = new Projection() {
+			public EastNorth latlon2eastNorth(LatLon p) {
+				return new EastNorth(
+						(p.lon()+180) / 360 * world.getIconWidth(),
+						(p.lat()+90) / 180 * world.getIconHeight());
+			}
+			public LatLon eastNorth2latlon(EastNorth p) {
+				return new LatLon(
+						p.east()*360/world.getIconWidth() - 180,
+						p.north()*180/world.getIconHeight() - 90);
 			}
 			@Override
@@ -94,12 +96,12 @@
 	@Override
 	public void paint(Graphics g) {
-		GeoPoint tl = getPoint(0,0,false);
-		GeoPoint br = getPoint(getWidth(),getHeight(),false);
-		g.drawImage(world.getImage(),0,0,getWidth(),getHeight(),(int)tl.x,(int)tl.y,(int)br.x,(int)br.y, null);
+		EastNorth tl = getEastNorth(0,0);
+		EastNorth br = getEastNorth(getWidth(),getHeight());
+		g.drawImage(world.getImage(),0,0,getWidth(),getHeight(),(int)tl.east(),(int)tl.north(),(int)br.east(),(int)br.north(), null);
 
 		// draw marker rect
-		if (marker != null) {
-			Point p1 = getScreenPoint(marker.min);
-			Point p2 = getScreenPoint(marker.max);
+		if (markerMin != null && markerMax != null) {
+			Point p1 = getPoint(markerMin);
+			Point p2 = getPoint(markerMax);
 			double x = Math.min(p1.x, p2.x);
 			double y = Math.min(p1.y, p2.y);
@@ -117,5 +119,5 @@
 
 	@Override
-	public void zoomTo(GeoPoint newCenter, double scale) {
+	public void zoomTo(EastNorth newCenter, double scale) {
 		if (getWidth() != 0 && scale > scaleMax)
 			scale = scaleMax;
@@ -131,8 +133,10 @@
 				Bookmark b = (Bookmark)list.getSelectedValue();
 				if (b != null) {
-					marker = new Bounds(new GeoPoint(b.latlon[0],b.latlon[1]),
-							new GeoPoint(b.latlon[2],b.latlon[3]));
-				} else
-					marker = null;
+					markerMin = getProjection().latlon2eastNorth(new LatLon(b.latlon[0],b.latlon[1]));
+					markerMax = getProjection().latlon2eastNorth(new LatLon(b.latlon[2],b.latlon[3]));
+				} else {
+					markerMin = null;
+					markerMax = null;
+				}
 				repaint();
 			}
@@ -164,11 +168,12 @@
 		SelectionEnded selListener = new SelectionEnded(){
 			public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
-				GeoPoint min = getPoint(r.x, r.y+r.height, true);
-				GeoPoint max = getPoint(r.x+r.width, r.y, true);
-				marker = new Bounds(min, max);
-				field[0].setText(""+min.lat);
-				field[1].setText(""+min.lon);
-				field[2].setText(""+max.lat);
-				field[3].setText(""+max.lon);
+				markerMin = getEastNorth(r.x, r.y+r.height);
+				markerMax = getEastNorth(r.x+r.width, r.y);
+				LatLon min = getProjection().eastNorth2latlon(markerMin);
+				LatLon max = getProjection().eastNorth2latlon(markerMax);
+				field[0].setText(""+min.lat());
+				field[1].setText(""+min.lon());
+				field[2].setText(""+max.lat());
+				field[3].setText(""+max.lon());
 				for (JTextField f : field)
 					f.setCaretPosition(0);
@@ -197,6 +202,6 @@
 			}
 		}
-
-		marker = new Bounds(new GeoPoint(v[0], v[1]), new GeoPoint(v[2], v[3]));
+		markerMin = new EastNorth(v[0], v[1]);
+		markerMax = new EastNorth(v[2], v[3]);
 		repaint();
 	}
Index: src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 71)
@@ -25,9 +25,9 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 71)
@@ -39,7 +39,7 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -275,5 +275,5 @@
 		b.addActionListener(actionListener);
 		b.setToolTipText(tooltip);
-		//b.setMnemonic(mnemonic); TODO disabled until mapmodes have no Alt in their hotkey.
+		b.setMnemonic(mnemonic);
 		return b;
 	}
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 71)
@@ -23,7 +23,7 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.SearchCompiler;
 
Index: src/org/openstreetmap/josm/gui/layer/Layer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 71)
@@ -5,5 +5,5 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapView;
@@ -75,15 +75,8 @@
 	/**
 	 * @return The bounding rectangle this layer occupies on screen when looking
-	 * 		at lat/lon values or <code>null</code>, if infinite area or unknown
-	 * 		area is occupied.
-	 */
-	abstract public Bounds getBoundsLatLon();
-	
-	/**
-	 * @return The bounding rectangle this layer occupies on screen when looking
 	 * 		at x/y values or <code>null</code>, if infinite area or unknown
 	 * 		area is occupied.
 	 */
-	abstract public Bounds getBoundsXY();
+	abstract public void visitBoundingBox(BoundingXYVisitor v);
 
 	/**
Index: src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 71)
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -21,10 +20,10 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.BoundingVisitor;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
 import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -86,5 +85,5 @@
 				if (evt.getPropertyName().equals("projection"))
 					for (Node n : OsmDataLayer.this.data.nodes)
-						((Projection)evt.getNewValue()).latlon2xy(n.coor);
+						((Projection)evt.getNewValue()).latlon2eastNorth(n.coor);
 			}
 		});
@@ -113,5 +112,5 @@
 			if (!osm.isDeleted())
 				osm.visit(visitor);
-		for (OsmPrimitive osm : data.waies)
+		for (OsmPrimitive osm : data.ways)
 			if (!osm.isDeleted())
 				osm.visit(visitor);
@@ -128,5 +127,5 @@
 		return undeletedSize(data.nodes)+" nodes, "+
 			undeletedSize(data.lineSegments)+" segments, "+
-			undeletedSize(data.waies)+" streets.";
+			undeletedSize(data.ways)+" streets.";
 	}
 
@@ -145,17 +144,7 @@
 
 	@Override
-	public Bounds getBoundsLatLon() {
-		BoundingVisitor b = new BoundingVisitor(BoundingVisitor.Type.LATLON);
+	public void visitBoundingBox(BoundingXYVisitor v) {
 		for (Node n : data.nodes)
-			b.visit(n);
-		return b.bounds != null ? b.bounds : new Bounds();
-	}
-
-	@Override
-	public Bounds getBoundsXY() {
-		BoundingVisitor b = new BoundingVisitor(BoundingVisitor.Type.XY);
-		for (Node n : data.nodes)
-			b.visit(n);
-		return b.bounds != null ? b.bounds : new Bounds();
+			v.visit(n);
 	}
 
@@ -163,5 +152,5 @@
 	public void init(Projection projection) {
 		for (Node n : data.nodes)
-			projection.latlon2xy(n.coor);
+			projection.latlon2eastNorth(n.coor);
 	}
 
@@ -238,5 +227,5 @@
 			for (Iterator<LineSegment> it = data.lineSegments.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
-			for (Iterator<Way> it = data.waies.iterator(); it.hasNext();)
+			for (Iterator<Way> it = data.ways.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
 		}
Index: src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 70)
+++ src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 71)
@@ -7,13 +7,15 @@
 import java.beans.PropertyChangeListener;
 import java.util.Collection;
+import java.util.LinkedList;
 
 import javax.swing.Icon;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -28,11 +30,13 @@
 
 	/**
-	 * A list of waies which containing a list of points.
+	 * A list of ways which containing a list of points.
 	 */
-	private final Collection<Collection<GeoPoint>> data;
+	private final Collection<Collection<LatLon>> data;
+	private Collection<Collection<EastNorth>> eastNorth;
 
-	public RawGpsDataLayer(Collection<Collection<GeoPoint>> data, String name) {
+	public RawGpsDataLayer(Collection<Collection<LatLon>> data, String name) {
 		super(name);
 		this.data = data;
+		
 		Main.pref.addPropertyChangeListener(new PropertyChangeListener(){
 			public void propertyChange(PropertyChangeEvent evt) {
@@ -62,9 +66,9 @@
 		g.setColor(Color.GRAY);
 		Point old = null;
-		for (Collection<GeoPoint> c : data) {
+		for (Collection<EastNorth> c : eastNorth) {
 			if (!Main.pref.isForceRawGpsLines())
 				old = null;
-			for (GeoPoint p : c) {
-				Point screen = mv.getScreenPoint(p);
+			for (EastNorth eastNorth : c) {
+				Point screen = mv.getPoint(eastNorth);
 				if (Main.pref.isDrawRawGpsLines() && old != null)
 					g.drawLine(old.x, old.y, screen.x, screen.y);
@@ -78,5 +82,8 @@
 	@Override
 	public String getToolTipText() {
-		return data.size()+" waies.";
+		int points = 0;
+		for (Collection<LatLon> c : data)
+			points += c.size();
+		return data.size()+" ways, "+points+" points.";
 	}
 
@@ -93,52 +100,19 @@
 
 	@Override
-	public Bounds getBoundsLatLon() {
-		GeoPoint min = null;
-		GeoPoint max = null;
-		for (Collection<GeoPoint> c : data) {
-			for (GeoPoint p : c) {
-				if (min == null) {
-					min = p.clone();
-					max = p.clone();
-				} else {
-					min.lat = Math.min(min.lat, p.lat);
-					min.lon = Math.min(min.lon, p.lon);
-					max.lat = Math.max(max.lat, p.lat);
-					max.lon = Math.max(max.lon, p.lon);
-				}
-			}
-		}
-		if (min == null)
-			return null;
-		return new Bounds(min, max);
-	}
-
-	@Override
-	public Bounds getBoundsXY() {
-		GeoPoint min = null;
-		GeoPoint max = null;
-		for (Collection<GeoPoint> c : data) {
-			for (GeoPoint p : c) {
-				if (min == null) {
-					min = p.clone();
-					max = p.clone();
-				} else {
-					min.x = Math.min(min.x, p.x);
-					min.y = Math.min(min.y, p.y);
-					max.x = Math.max(max.x, p.x);
-					max.y = Math.max(max.y, p.y);
-				}
-			}
-		}
-		if (min == null)
-			return null;
-		return new Bounds(min, max);
+	public void visitBoundingBox(BoundingXYVisitor v) {
+		for (Collection<EastNorth> c : eastNorth)
+			for (EastNorth eastNorth : c)
+				v.visit(eastNorth);
 	}
 
 	@Override
 	public void init(Projection projection) {
-		for (Collection<GeoPoint> c : data)
-			for (GeoPoint p : c)
-				projection.latlon2xy(p);
+		eastNorth = new LinkedList<Collection<EastNorth>>();
+		for (Collection<LatLon> c : data) {
+			Collection<EastNorth> eastNorthList = new LinkedList<EastNorth>();
+			for (LatLon ll : c)
+				eastNorthList.add(Main.pref.getProjection().latlon2eastNorth(ll));
+			this.eastNorth.add(eastNorthList);
+		}
 	}
 }
Index: src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxReader.java	(revision 70)
+++ src/org/openstreetmap/josm/io/GpxReader.java	(revision 71)
@@ -12,5 +12,5 @@
 import org.jdom.JDOMException;
 import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -73,5 +73,5 @@
 	 */
 	private Node parseWaypoint(Element e) {
-		Node data = new Node(new GeoPoint(
+		Node data = new Node(new LatLon(
 			Double.parseDouble(e.getAttributeValue("lat")),
 			Double.parseDouble(e.getAttributeValue("lon"))));
@@ -97,5 +97,5 @@
 	private DataSet parseDataSet(Element e) {
 		DataSet data = new DataSet();
-		// read waypoints not contained in waies or areas
+		// read waypoints not contained in ways or areas
 		for (Object o : e.getChildren("wpt", GPX)) {
 			Node node = parseWaypoint((Element)o);
@@ -103,5 +103,5 @@
 		}
 	
-		// read waies (and line segments)
+		// read ways (and line segments)
 		for (Object wayElement : e.getChildren("trk", GPX))
 			parseWay((Element)wayElement, data);
@@ -155,5 +155,5 @@
 		ds.lineSegments.addAll(way.segments);
 		if (!realLineSegment)
-			ds.waies.add(way);
+			ds.ways.add(way);
 	}
 
@@ -170,5 +170,5 @@
 		if (mergeNodes)
 			for (Node n : data.nodes)
-				if (node.coor.equalsLatLon(n.coor))
+				if (node.coor.equals(n.coor))
 					return n;
 		data.nodes.add(node);
Index: src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxWriter.java	(revision 70)
+++ src/org/openstreetmap/josm/io/GpxWriter.java	(revision 71)
@@ -106,6 +106,6 @@
 		LinkedList<LineSegment> unrefLs = new LinkedList<LineSegment>(ds.lineSegments);
 
-		// waies
-		for (Way t : ds.waies) {
+		// ways
+		for (Way t : ds.ways) {
 			if (t.isDeleted() && t.id == 0)
 				continue;
@@ -135,5 +135,5 @@
 		}
 		
-		// encode pending line segments as waies
+		// encode pending line segments as ways
 		for (LineSegment ls : unrefLs) {
 			if (ls.isDeleted() && ls.id == 0)
@@ -195,6 +195,6 @@
 	private Element parseWaypoint(Node n, String name) {
 		Element e = new Element(name, GPX);
-		e.setAttribute("lat", Double.toString(n.coor.lat));
-		e.setAttribute("lon", Double.toString(n.coor.lon));
+		e.setAttribute("lat", Double.toString(n.coor.lat()));
+		e.setAttribute("lon", Double.toString(n.coor.lon()));
 		HashMap<String, String> keys = null;
 		if (n.keys != null) {
Index: src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmConnection.java	(revision 70)
+++ src/org/openstreetmap/josm/io/OsmConnection.java	(revision 71)
@@ -14,5 +14,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.GBC;
+import org.openstreetmap.josm.tools.GBC;
 
 /**
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 70)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 71)
@@ -6,5 +6,5 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -76,5 +76,5 @@
 					throw new SAXException("Unknown version: "+atts.getValue("version"));
 			} else if (qName.equals("node")) {
-				Node n = new Node(new GeoPoint(getDouble(atts, "lat"), getDouble(atts, "lon")));
+				Node n = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
 				current = n;
 				readCommon(atts);
Index: src/org/openstreetmap/josm/io/OsmReaderOld.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReaderOld.java	(revision 70)
+++ src/org/openstreetmap/josm/io/OsmReaderOld.java	(revision 71)
@@ -9,5 +9,5 @@
 import org.jdom.JDOMException;
 import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -62,11 +62,11 @@
 	 */
 	private Node parseNode(Element e) throws JDOMException {
-		Node data = new Node(new GeoPoint(
+		Node data = new Node(new LatLon(
 			Double.parseDouble(e.getAttributeValue("lat")),
 			Double.parseDouble(e.getAttributeValue("lon"))));
-		if (Double.isNaN(data.coor.lat) || 
-				data.coor.lat < -90 || data.coor.lat > 90 ||
-				data.coor.lon < -180 || data.coor.lon > 180)
-			throw new JDOMException("Illegal lat or lon value: "+data.coor.lat+"/"+data.coor.lon);
+		if (Double.isNaN(data.coor.lat()) || 
+				data.coor.lat() < -90 || data.coor.lat() > 90 ||
+				data.coor.lon() < -180 || data.coor.lon() > 180)
+			throw new JDOMException("Illegal lat or lon value: "+data.coor.lat()+"/"+data.coor.lon());
 		parseCommon(data, e);
 		return data;
@@ -221,5 +221,5 @@
 			if (osm.id == id)
 				return osm;
-		for (OsmPrimitive osm : data.waies)
+		for (OsmPrimitive osm : data.ways)
 			if (osm.id == id)
 				return osm;
Index: src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 70)
+++ src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 71)
@@ -11,5 +11,5 @@
 import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.xml.sax.SAXException;
@@ -45,10 +45,10 @@
 	 * @return A list of all primitives retrieved. Currently, the list of lists
 	 * 		contain only one list, since the server cannot distinguish between
-	 * 		waies.
+	 * 		ways.
 	 */
-	public Collection<Collection<GeoPoint>> parseRawGps() throws IOException, JDOMException {
+	public Collection<Collection<LatLon>> parseRawGps() throws IOException, JDOMException {
 		String url = Main.pref.osmDataServer+"/0.3/trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";
-		Collection<Collection<GeoPoint>> data = new LinkedList<Collection<GeoPoint>>();
-		Collection<GeoPoint> list = new LinkedList<GeoPoint>();
+		Collection<Collection<LatLon>> data = new LinkedList<Collection<LatLon>>();
+		Collection<LatLon> list = new LinkedList<LatLon>();
 		
 		for (int i = 0;;++i) {
@@ -57,7 +57,7 @@
 				break;
 			RawGpsReader gpsReader = new RawGpsReader(r);
-			Collection<Collection<GeoPoint>> allWays = gpsReader.parse();
+			Collection<Collection<LatLon>> allWays = gpsReader.parse();
 			boolean foundSomething = false;
-			for (Collection<GeoPoint> t : allWays) {
+			for (Collection<LatLon> t : allWays) {
 				if (!t.isEmpty()) {
 					foundSomething = true;
@@ -101,4 +101,5 @@
 		HttpURLConnection con = (HttpURLConnection)url.openConnection();
 		con.setConnectTimeout(20000);
+		System.out.println("response: "+con.getResponseCode());
 		if (con.getResponseCode() == 401 && isCancelled())
 			return null;
Index: src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmWriter.java	(revision 70)
+++ src/org/openstreetmap/josm/io/OsmWriter.java	(revision 71)
@@ -72,5 +72,5 @@
 		for (LineSegment ls : ds.lineSegments)
 			writer.visit(ls);
-		for (Way w : ds.waies)
+		for (Way w : ds.ways)
 			writer.visit(w);
 		writer.out.println("</osm>");
@@ -99,5 +99,5 @@
 	public void visit(Node n) {
 		addCommon(n, "node");
-		out.print(" lat='"+n.coor.lat+"' lon='"+n.coor.lon+"'");
+		out.print(" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");
 		addTags(n, "node", true);
 	}
Index: src/org/openstreetmap/josm/io/RawCsvReader.java
===================================================================
--- src/org/openstreetmap/josm/io/RawCsvReader.java	(revision 70)
+++ src/org/openstreetmap/josm/io/RawCsvReader.java	(revision 71)
@@ -11,5 +11,5 @@
 import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 
 /**
@@ -28,6 +28,6 @@
 	}
 	
-	public Collection<GeoPoint> parse() throws JDOMException, IOException {
-		Collection<GeoPoint> data = new LinkedList<GeoPoint>();
+	public Collection<LatLon> parse() throws JDOMException, IOException {
+		Collection<LatLon> data = new LinkedList<LatLon>();
 		String formatStr = Main.pref.csvImportString;
 		if (formatStr == null)
@@ -62,10 +62,10 @@
 				lineNo++;
 				StringTokenizer st = new StringTokenizer(line, delim);
-				GeoPoint p = new GeoPoint();
+				double lat = 0, lon = 0;
 				for (String token : format) {
 					if (token.equals("lat"))
-						p.lat = Double.parseDouble(st.nextToken());
+						lat = Double.parseDouble(st.nextToken());
 					else if (token.equals("lon"))
-						p.lon = Double.parseDouble(st.nextToken());
+						lon = Double.parseDouble(st.nextToken());
 					else if (token.equals("ignore"))
 						st.nextToken();
@@ -73,5 +73,5 @@
 						throw new JDOMException("Unknown data type: '"+token+"'."+(Main.pref.csvImportString == null ? " Maybe add an format string in preferences." : ""));
 				}
-				data.add(p);
+				data.add(new LatLon(lat, lon));
 			}
 		} catch (RuntimeException e) {
Index: src/org/openstreetmap/josm/io/RawGpsReader.java
===================================================================
--- src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 70)
+++ src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 71)
@@ -11,8 +11,8 @@
 import org.jdom.Namespace;
 import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.coor.LatLon;
 
 /**
- * Read raw gps data from a gpx file. Only way points with their waies segments
+ * Read raw gps data from a gpx file. Only way points with their ways segments
  * and waypoints are imported.
  * @author imi
@@ -42,5 +42,5 @@
 	 * Parse and return the read data
 	 */
-	public Collection<Collection<GeoPoint>> parse() throws JDOMException, IOException {
+	public Collection<Collection<LatLon>> parse() throws JDOMException, IOException {
 		final SAXBuilder builder = new SAXBuilder();
 		builder.setValidation(false);
@@ -55,6 +55,6 @@
 	 */
 	@SuppressWarnings("unchecked")
-	private Collection<Collection<GeoPoint>> parseData(Element root) throws JDOMException {
-		Collection<Collection<GeoPoint>> data = new LinkedList<Collection<GeoPoint>>();
+	private Collection<Collection<LatLon>> parseData(Element root) throws JDOMException {
+		Collection<Collection<LatLon>> data = new LinkedList<Collection<LatLon>>();
 
 		// workaround for bug where the server adds /gpx.asd to the namespace
@@ -62,10 +62,10 @@
 		
 		for (Object o : root.getChildren("wpt", GPX)) {
-			Collection<GeoPoint> line = new LinkedList<GeoPoint>();
-			line.add(new GeoPoint(parseDouble((Element)o, LatLon.lat), parseDouble((Element)o, LatLon.lon)));
+			Collection<LatLon> line = new LinkedList<LatLon>();
+			line.add(new LatLon(parseDouble((Element)o, LatLonAttr.lat), parseDouble((Element)o, LatLonAttr.lon)));
 			data.add(line);
 		}
 		for (Object o : root.getChildren("rte", GPX)) {
-			Collection<GeoPoint> line = parseLine(((Element)o).getChildren("rtept", GPX));
+			Collection<LatLon> line = parseLine(((Element)o).getChildren("rtept", GPX));
 			if (!line.isEmpty())
 				data.add(line);
@@ -73,5 +73,5 @@
 		for (Object o : root.getChildren("trk", GPX)) {
 			for (Object seg : ((Element)o).getChildren("trkseg", GPX)) {
-				Collection<GeoPoint> line = parseLine(((Element)seg).getChildren("trkpt", GPX));
+				Collection<LatLon> line = parseLine(((Element)seg).getChildren("trkpt", GPX));
 				if (!line.isEmpty())
 					data.add(line);
@@ -81,5 +81,5 @@
 	}
 
-	enum LatLon {lat, lon}
+	private enum LatLonAttr {lat, lon}
 	/**
 	 * Return a parsed float value from the element behind the object o.
@@ -88,7 +88,7 @@
 	 * @throws JDOMException If the absolute of the value is out of bound.
 	 */
-	private double parseDouble(Element e, LatLon attr) throws JDOMException {
+	private double parseDouble(Element e, LatLonAttr attr) throws JDOMException {
 		double d = Double.parseDouble(e.getAttributeValue(attr.toString()));
-		if (Math.abs(d) > (attr == LatLon.lat ? 90 : 180))
+		if (Math.abs(d) > (attr == LatLonAttr.lat ? 90 : 180))
 			throw new JDOMException("Data error: "+attr+" value '"+d+"' is out of bound.");
 		return d;
@@ -99,8 +99,8 @@
 	 * points read.
 	 */
-	private Collection<GeoPoint> parseLine(List<Element> wpt) throws JDOMException {
-		Collection<GeoPoint> data = new LinkedList<GeoPoint>();
+	private Collection<LatLon> parseLine(List<Element> wpt) throws JDOMException {
+		Collection<LatLon> data = new LinkedList<LatLon>();
 		for (Element e : wpt)
-			data.add(new GeoPoint(parseDouble(e, LatLon.lat), parseDouble(e, LatLon.lon)));
+			data.add(new LatLon(parseDouble(e, LatLonAttr.lat), parseDouble(e, LatLonAttr.lon)));
 		return data;
 	}
Index: src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java
===================================================================
--- src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 71)
+++ src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 71)
@@ -0,0 +1,78 @@
+package org.openstreetmap.josm.tools;
+
+import java.awt.GridBagLayout;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import org.openstreetmap.josm.Main;
+
+/**
+ * An exception handler, that ask the user to send a bug report.
+ * 
+ * @author imi
+ */
+public final class BugReportExceptionHandler implements Thread.UncaughtExceptionHandler {
+	public void uncaughtException(Thread t, Throwable e) {
+		e.printStackTrace();
+		if (Main.main != null) {
+			Object[] options = new String[]{"Do nothing", "Report Bug"};
+			int answer = JOptionPane.showOptionDialog(Main.main, "An unexpected exception occoured.\n\n" +
+					"This is always a coding error. If you are running the latest\n" +
+					"version of JOSM, please consider be kind and file a bug report.",
+					"Unexpected Exception", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE,
+					null, options, options[0]);
+			if (answer == 1) {
+				try {
+					StringWriter stack = new StringWriter();
+					e.printStackTrace(new PrintWriter(stack));
+
+					URL revUrl = Main.class.getResource("/REVISION");
+					StringBuilder sb = new StringBuilder("Please send this to josm@eigenheimstrasse.de\n\n");
+					if (revUrl == null) {
+						sb.append("Development version. Unknown revision.");
+						File f = new File("org/openstreetmap/josm/Main.class");
+						if (!f.exists())
+							f = new File("bin/org/openstreetmap/josm/Main.class");
+						if (f.exists()) {
+							DateFormat sdf = SimpleDateFormat.getDateTimeInstance();
+							sb.append("\nMain.class build on "+sdf.format(new Date(f.lastModified())));
+							sb.append("\n");
+						}
+					} else {
+						BufferedReader in = new BufferedReader(new InputStreamReader(revUrl.openStream()));
+						for (String line = in.readLine(); line != null; line = in.readLine()) {
+							sb.append(line);
+							sb.append('\n');
+						}
+					}
+					sb.append("\n"+stack.getBuffer().toString());
+
+					JPanel p = new JPanel(new GridBagLayout());
+					p.add(new JLabel("Please send an email with the following information to josm@eigenheimstrasse.de"), GBC.eop());
+
+					JTextArea info = new JTextArea(sb.toString(), 20, 60);
+					info.setCaretPosition(0);
+					info.setEditable(false);
+					p.add(new JScrollPane(info), GBC.eop());
+
+					JOptionPane.showMessageDialog(Main.main, p);
+				} catch (Exception e1) {
+					e1.printStackTrace();
+				}
+			}
+		}
+	}
+}
Index: src/org/openstreetmap/josm/tools/GBC.java
===================================================================
--- src/org/openstreetmap/josm/tools/GBC.java	(revision 71)
+++ src/org/openstreetmap/josm/tools/GBC.java	(revision 71)
@@ -0,0 +1,109 @@
+package org.openstreetmap.josm.tools;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+
+import javax.swing.Box;
+
+/**
+ * A wrapper for GridBagConstraints which has sane default static creators and
+ * member functions to chain calling.
+ * 
+ * @author imi
+ */
+public class GBC extends GridBagConstraints {
+
+	/**
+	 * Use public static creator functions to create an GBC.
+	 */
+	private GBC() {}
+	
+	/**
+	 * Create a standard constraint (which is not the last).
+	 * @return A standard constraint with no filling.
+	 */
+	public static GBC std() {
+		GBC c = new GBC();
+		c.anchor = WEST;
+		return c;
+	}
+	
+	/**
+	 * Create the constraint for the last elements on a line.
+	 * @return A constraint which indicates the last item on a line.
+	 */
+	public static GBC eol() {
+		GBC c = std();
+		c.gridwidth = REMAINDER;
+		return c;
+	}
+	
+	/**
+	 * Create the constraint for the last elements on a line and on a paragraph.
+	 * This is merely a shortcut for eol().insets(0,0,0,10)
+	 * @return A constraint which indicates the last item on a line.
+	 */
+	public static GBC eop() {
+		return eol().insets(0,0,0,10);
+	}
+
+	/**
+	 * Try to fill both, horizontal and vertical
+	 * @return This constraint for chaining.
+	 */
+	public GBC fill() {
+		return fill(BOTH);
+	}
+
+	/**
+	 * Set fill to the given value
+	 * @param value The filling value, either NONE, HORIZONTAL, VERTICAL or BOTH
+	 * @return This constraint for chaining.
+	 */
+	public GBC fill(int value) {
+		fill = value;
+		if (value == HORIZONTAL || value == BOTH)
+			weightx = 1.0;
+		if (value == VERTICAL || value == BOTH)
+			weighty = 1.0;
+		return this;
+	}
+	
+	/**
+	 * Set the anchor of this GBC to a.
+	 * @param a The new anchor, e.g. GBC.CENTER or GBC.EAST.
+	 * @return This constraint for chaining.
+	 */
+	public GBC anchor(int a) {
+		anchor = a;
+		return this;
+	}
+
+	/**
+	 * Adds insets to this GBC.
+	 * @param left		The left space of the insets
+	 * @param top		The top space of the insets
+	 * @param right		The right space of the insets
+	 * @param bottom	The bottom space of the insets
+	 * @return This constraint for chaining.
+	 */
+	public GBC insets(int left, int top, int right, int bottom) {
+		insets = new Insets(top, left, bottom, right);
+		return this;
+	}
+	
+	/**
+	 * This is a helper to easily create a glue with a minimum default value.
+	 * @param x If higher than 0, this will be a horizontal glue with x as minimum
+	 * 		horizontal strut.
+	 * @param y If higher than 0, this will be a vertical glue with y as minimum
+	 * 		vertical strut.
+	 */
+	public static Component glue(int x, int y) {
+		short maxx = x > 0 ? Short.MAX_VALUE : 0;
+		short maxy = y > 0 ? Short.MAX_VALUE : 0;
+		return new Box.Filler(new Dimension(x,y), new Dimension(x,y), new Dimension(maxx,maxy));
+	}
+}
Index: src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 71)
+++ src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 71)
@@ -0,0 +1,89 @@
+package org.openstreetmap.josm.tools;
+
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.Main;
+
+/**
+ * Helperclass to support the application with images.
+ * @author imi
+ */
+public class ImageProvider {
+
+	/**
+	 * Position of an overlay icon
+	 * @author imi
+	 */
+	public enum OverlayPosition {NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST}
+	
+	/**
+	 * The icon cache
+	 */
+	private static Map<URL, ImageIcon> cache = new HashMap<URL, ImageIcon>();
+	
+	/**
+	 * Return an image from the specified location.
+	 *
+	 * @param subdir	The position of the directory, e.g. "layer"
+	 * @param name		The icons name (without the ending of ".png")
+	 * @return	The requested ImageIcon.
+	 */
+	public static ImageIcon get(String subdir, String name) {
+		if (subdir != "")
+			subdir += "/";
+		URL path = Main.class.getResource("/images/"+subdir+name+".png");
+		if (path == null)
+			throw new NullPointerException("/images/"+subdir+name+".png not found");
+		ImageIcon icon = cache.get(path);
+		if (icon == null) {
+			icon = new ImageIcon(path);
+			cache.put(path, icon);
+		}
+		return icon;
+	}
+
+	/**
+	 * Shortcut for get("", name);
+	 */
+	public static ImageIcon get(String name) {
+		return get("", name);
+	}
+
+	/**
+	 * 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.
+	 *
+	 * @param ground The ground icon (base)
+	 * @param overlay The icon to put on top of the ground (overlay)
+	 * @return The merged icon.
+	 */
+	public static Icon overlay(Icon ground, Icon overlay, OverlayPosition pos) {
+		GraphicsConfiguration conf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
+		int w = ground.getIconWidth();
+		int h = ground.getIconHeight();
+		int wo = overlay.getIconWidth();
+		int ho = overlay.getIconHeight();
+		BufferedImage img = conf.createCompatibleImage(w,h, Transparency.TRANSLUCENT);
+		Graphics g = img.createGraphics();
+		ground.paintIcon(null, g, 0, 0);
+		int x = 0, y = 0;
+		switch (pos) {
+		case NORTHWEST: x = 0;		y = 0;		break;
+		case NORTHEAST: x = w-wo;	y = 0;		break;
+		case SOUTHWEST: x = 0;		y = h-ho;	break;
+		case SOUTHEAST: x = w-wo;	y = h-ho;	break;
+		}
+		overlay.paintIcon(null, g, x, y);
+		return new ImageIcon(img);
+	}
+}
