Index: src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 15)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package org.openstreetmap.josm.actions;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-
-import javax.swing.AbstractAction;
-import javax.swing.ImageIcon;
-
-import org.openstreetmap.josm.gui.Layer;
-import org.openstreetmap.josm.gui.Main;
-
-/**
- * Toggles the autoScale feature of the layer
- * @author imi
- */
-public class AutoScaleAction extends AbstractAction {
-	/**
-	 * The Layer, that belongs to this AutoScaleSction.
-	 */
-	private final Layer layer;
-	
-	public AutoScaleAction(Layer layer) {
-		super("Auto Scale", new ImageIcon(Main.class.getResource("/images/autoscale.png")));
-		this.layer = layer;
-		putValue(MNEMONIC_KEY, KeyEvent.VK_A);
-	}
-	public void actionPerformed(ActionEvent e) {
-		layer.setAutoScale(!layer.isAutoScale());
-	}
-}
Index: src/org/openstreetmap/josm/actions/OpenGpxAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 16)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.Main;
+import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.io.GpxReader;
 import org.openstreetmap.josm.io.DataReader.ConnectionException;
@@ -54,5 +55,6 @@
 		try {
 			DataSet dataSet = new GpxReader(new FileReader(gpxFile)).parse();
-			Main.main.setMapFrame(gpxFile.getName(), dataSet);
+			MapFrame map = new MapFrame(dataSet);
+			Main.main.setMapFrame(gpxFile.getName(), map);
 		} catch (ParseException x) {
 			x.printStackTrace();
Index: src/org/openstreetmap/josm/actions/SaveGpxAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveGpxAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/SaveGpxAction.java	(revision 16)
@@ -46,5 +46,5 @@
 		try {
 			FileWriter fileWriter = new FileWriter(gpxFile);
-			GpxWriter out = new GpxWriter(fileWriter, Main.main.getMapFrame().layer.dataSet);
+			GpxWriter out = new GpxWriter(fileWriter, Main.main.getMapFrame().mapView.dataSet);
 			out.output();
 			fileWriter.close();
Index: src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 16)
@@ -59,6 +59,6 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseListener(this);
-		layer.addMouseMotionListener(this);
+		mv.addMouseListener(this);
+		mv.addMouseMotionListener(this);
 	}
 
@@ -66,6 +66,6 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseListener(this);
-		layer.removeMouseMotionListener(this);
+		mv.removeMouseListener(this);
+		mv.removeMouseMotionListener(this);
 		drawHint(false);
 	}
@@ -79,5 +79,5 @@
 			return;
 
-		OsmPrimitive clicked = layer.getNearest(e.getPoint(), false);
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), false);
 		if (clicked == null || !(clicked instanceof Node))
 			return;
@@ -96,5 +96,5 @@
 			return;
 
-		OsmPrimitive clicked = layer.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 		if (clicked == null || clicked == second || !(clicked instanceof Node))
 			return;
@@ -161,5 +161,5 @@
 		}
 		
-		layer.repaint();
+		mv.repaint();
 	}
 
@@ -175,9 +175,9 @@
 			return;
 
-		Graphics g = layer.getGraphics();
+		Graphics g = mv.getGraphics();
 		g.setColor(Color.BLACK);
 		g.setXORMode(Color.WHITE);
-		Point firstDrawn = layer.getScreenPoint(first.coor);
-		Point secondDrawn = layer.getScreenPoint(second.coor);
+		Point firstDrawn = mv.getScreenPoint(first.coor);
+		Point secondDrawn = mv.getScreenPoint(second.coor);
 		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 15)
+++ src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 16)
@@ -30,5 +30,5 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseListener(this);
+		mv.addMouseListener(this);
 	}
 
@@ -36,5 +36,5 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseListener(this);
+		mv.removeMouseListener(this);
 	}
 
@@ -47,7 +47,7 @@
 		if (e.getButton() == MouseEvent.BUTTON1) {
 			Node node = new Node();
-			node.coor = layer.getPoint(e.getX(), e.getY(), true);
+			node.coor = mv.getPoint(e.getX(), e.getY(), true);
 			ds.nodes.add(node);
-			layer.repaint();
+			mv.repaint();
 		}
 	}
Index: src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java	(revision 16)
@@ -43,5 +43,5 @@
 	public AddTrackAction(MapFrame mapFrame) {
 		super("Add Track", "addtrack", "Combine line segments to a new track.", KeyEvent.VK_T, mapFrame);
-		this.selectionManager = new SelectionManager(this, false, layer);
+		this.selectionManager = new SelectionManager(this, false, mv);
 	}
 
@@ -49,5 +49,5 @@
 	public void registerListener() {
 		super.registerListener();
-		selectionManager.register(layer);
+		selectionManager.register(mv);
 	}
 
@@ -55,5 +55,5 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		selectionManager.unregister(layer);
+		selectionManager.unregister(mv);
 	}
 
@@ -82,5 +82,5 @@
 			osm.setSelected(!ctrl, ds);
 
-		layer.repaint(); // from now on, the map has to be repainted.
+		mv.repaint(); // from now on, the map has to be repainted.
 
 		if (ctrl || shift)
Index: src/org/openstreetmap/josm/actions/mapmode/CombineAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/CombineAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/CombineAction.java	(revision 16)
@@ -80,6 +80,6 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseListener(this);
-		layer.addMouseMotionListener(this);
+		mv.addMouseListener(this);
+		mv.addMouseMotionListener(this);
 		ds.clearSelection();
 	}
@@ -88,6 +88,6 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseListener(this);
-		layer.removeMouseMotionListener(this);
+		mv.removeMouseListener(this);
+		mv.removeMouseMotionListener(this);
 		drawCombineHint(false);
 	}
@@ -103,5 +103,5 @@
 			return;
 
-		OsmPrimitive clicked = layer.getNearest(e.getPoint(), true);
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
 		if (clicked == null || clicked instanceof Node)
 			return;
@@ -119,5 +119,5 @@
 			return;
 		
-		OsmPrimitive clicked = layer.getNearest(e.getPoint(), true);
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
 		if (clicked == null || clicked == second || clicked instanceof Node)
 			return;
@@ -168,5 +168,5 @@
 			}
 		}
-		layer.repaint();
+		mv.repaint();
 	}
 
@@ -198,5 +198,5 @@
 			return;
 
-		Graphics g = layer.getGraphics();
+		Graphics g = mv.getGraphics();
 		g.setColor(Color.BLACK);
 		g.setXORMode(Color.WHITE);
@@ -214,7 +214,7 @@
 		if (osm instanceof LineSegment) {
 			LineSegment ls = (LineSegment)osm;
-			Point start = layer.getScreenPoint(ls.getStart().coor);
-			Point end = layer.getScreenPoint(ls.getEnd().coor);
-			if (layer.dataSet.pendingLineSegments().contains(osm) && g.getColor() == Color.GRAY)
+			Point start = mv.getScreenPoint(ls.getStart().coor);
+			Point end = mv.getScreenPoint(ls.getEnd().coor);
+			if (mv.dataSet.pendingLineSegments().contains(osm) && g.getColor() == Color.GRAY)
 				g.drawLine(start.x, start.y, end.x, end.y);
 			else
Index: src/org/openstreetmap/josm/actions/mapmode/DebugAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DebugAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/DebugAction.java	(revision 16)
@@ -31,6 +31,6 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseMotionListener(this);
-		layer.addMouseListener(this);
+		mv.addMouseMotionListener(this);
+		mv.addMouseListener(this);
 		mapFrame.add(label, BorderLayout.SOUTH);
 	}
@@ -39,6 +39,6 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseMotionListener(this);
-		layer.removeMouseListener(this);
+		mv.removeMouseMotionListener(this);
+		mv.removeMouseListener(this);
 		mapFrame.remove(label);
 	}
@@ -46,10 +46,10 @@
 	@Override
 	public void mouseClicked(MouseEvent e) {
-		Graphics g = mapFrame.layer.getGraphics();
+		Graphics g = mapFrame.mapView.getGraphics();
 		g.setColor(Color.WHITE);
-		for (Track t :mapFrame.layer.dataSet.tracks())
+		for (Track t :mapFrame.mapView.dataSet.tracks())
 			for (LineSegment ls : t.segments()) {
-				Point A = mapFrame.layer.getScreenPoint(ls.getStart().coor);
-				Point B = mapFrame.layer.getScreenPoint(ls.getEnd().coor);
+				Point A = mapFrame.mapView.getScreenPoint(ls.getStart().coor);
+				Point B = mapFrame.mapView.getScreenPoint(ls.getEnd().coor);
 				Point C = e.getPoint();
 				Rectangle r = new Rectangle(A.x, A.y, B.x-A.x, B.y-A.y);
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 16)
@@ -71,5 +71,5 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseListener(this);
+		mv.addMouseListener(this);
 	}
 
@@ -77,5 +77,5 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseListener(this);
+		mv.removeMouseListener(this);
 	}
 
@@ -89,5 +89,5 @@
 			return;
 		
-		OsmPrimitive sel = layer.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive sel = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 		if (sel == null)
 			return;
@@ -98,5 +98,5 @@
 			delete(sel);
 
-		layer.repaint();
+		mv.repaint();
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 16)
@@ -14,5 +14,5 @@
 import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.Layer;
+import org.openstreetmap.josm.gui.MapView;
 
 /**
@@ -31,7 +31,7 @@
 	protected final MapFrame mapFrame;
 	/**
-	 * Shortcut to the Layer.
+	 * Shortcut to the MapView.
 	 */
-	protected final Layer layer;
+	protected final MapView mv;
 	/**
 	 * Shortcut to the DataSet.
@@ -53,10 +53,11 @@
 		mapFrame.getActionMap().put(this, this);
 		this.mapFrame = mapFrame;
-		layer = mapFrame.layer;
-		ds = layer.dataSet;
+		mv = mapFrame.mapView;
+		ds = mv.dataSet;
 	}
 	
 	/**
-	 * Register all listener to the layer
+	 * Register all listener to the mapView
+	 * @param mapView	The view, where the listener should be registered.
 	 */
 	public void registerListener() {
@@ -66,4 +67,5 @@
 	/**
 	 * Unregister all listener previously registered. 
+	 * @param mapView	The view from which the listener should be deregistered.
 	 */
 	public void unregisterListener() {
Index: src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 16)
@@ -48,6 +48,6 @@
 	public void registerListener() {
 		super.registerListener();
-		layer.addMouseListener(this);
-		layer.addMouseMotionListener(this);
+		mv.addMouseListener(this);
+		mv.addMouseMotionListener(this);
 	}
 
@@ -55,6 +55,6 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		layer.removeMouseListener(this);
-		layer.removeMouseMotionListener(this);
+		mv.removeMouseListener(this);
+		mv.removeMouseMotionListener(this);
 	}
 
@@ -86,10 +86,10 @@
 
 		for (Node n : movingNodes) {
-			Point pos = layer.getScreenPoint(n.coor);
+			Point pos = mv.getScreenPoint(n.coor);
 			pos.x += dx;
 			pos.y += dy;
-			n.coor = layer.getPoint(pos.x, pos.y, true);
+			n.coor = mv.getPoint(pos.x, pos.y, true);
 		}
-		layer.repaint();
+		mv.repaint();
 		
 		mousePos = e.getPoint();
@@ -111,15 +111,15 @@
 
 		if (ds.getSelected().size() == 0) {
-			OsmPrimitive osm = layer.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+			OsmPrimitive osm = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 			if (osm != null)
 				osm.setSelected(true, ds);
 			singleOsmPrimitive = osm;
-			layer.repaint();
+			mv.repaint();
 		} else
 			singleOsmPrimitive = null;
 		
 		mousePos = e.getPoint();
-		oldCursor = layer.getCursor();
-		layer.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+		oldCursor = mv.getCursor();
+		mv.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
 	}
 	
@@ -129,8 +129,8 @@
 	@Override
 	public void mouseReleased(MouseEvent e) {
-		layer.setCursor(oldCursor);
+		mv.setCursor(oldCursor);
 		if (singleOsmPrimitive != null) {
 			singleOsmPrimitive.setSelected(false, ds);
-			layer.repaint();
+			mv.repaint();
 		}
 	}
Index: src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 16)
@@ -46,5 +46,5 @@
  * and the user clicked in or 10 pixel away from an area, this area is selected. 
  * If there is even no area, nothing is selected. Shift and Ctrl key applies to 
- * this as usual. For more, @see Layer#getNearest(Point, boolean)
+ * this as usual. For more, @see MapView#getNearest(Point, boolean)
  *
  * @author imi
@@ -63,5 +63,5 @@
 	public SelectionAction(MapFrame mapFrame) {
 		super("Selection", "selection", "Select objects by dragging or clicking", KeyEvent.VK_S, mapFrame);
-		this.selectionManager = new SelectionManager(this, false, layer);
+		this.selectionManager = new SelectionManager(this, false, mv);
 	}
 
@@ -69,5 +69,5 @@
 	public void registerListener() {
 		super.registerListener();
-		selectionManager.register(layer);
+		selectionManager.register(mv);
 	}
 
@@ -75,5 +75,5 @@
 	public void unregisterListener() {
 		super.unregisterListener();
-		selectionManager.unregister(layer);
+		selectionManager.unregister(mv);
 	}
 
@@ -92,5 +92,5 @@
 		for (OsmPrimitive osm : selectionList)
 			osm.setSelected(!ctrl, ds);
-		layer.repaint();
+		mv.repaint();
 	}
 }
Index: src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 15)
+++ src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 16)
@@ -6,5 +6,5 @@
 import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.Layer;
+import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.SelectionManager;
 import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
@@ -14,5 +14,5 @@
  * 
  * Holding down the left mouse button select a rectangle with the same aspect 
- * ratio than the current layer.
+ * ratio than the current map view.
  * Holding down left and right let the user move the former selected rectangle.
  * Releasing the left button zoom to the selection.
@@ -28,8 +28,8 @@
 	 * Shortcut to the mapview.
 	 */
-	private final Layer mv;
+	private final MapView mv;
 	/**
 	 * Manager that manages the selection rectangle with the aspect ratio of the
-	 * Layer.
+	 * MapView.
 	 */
 	private final SelectionManager selectionManager;
@@ -42,5 +42,5 @@
 	public ZoomAction(MapFrame mapFrame) {
 		super("Zoom", "zoom", "Zoom in by dragging", KeyEvent.VK_Z, mapFrame);
-		mv = mapFrame.layer;
+		mv = mapFrame.mapView;
 		selectionManager = new SelectionManager(this, true, mv);
 	}
Index: src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- src/org/openstreetmap/josm/data/Preferences.java	(revision 15)
+++ src/org/openstreetmap/josm/data/Preferences.java	(revision 16)
@@ -1,9 +1,8 @@
 package org.openstreetmap.josm.data;
 
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
@@ -28,20 +27,37 @@
 public class Preferences {
 
-	
 	/**
 	 * The look and feel. Classname of the look and feel class to use.
 	 */
-	private LookAndFeelInfo laf = UIManager.getInstalledLookAndFeels()[0];
+	public LookAndFeelInfo laf = UIManager.getInstalledLookAndFeels()[0];
+
 	/**
 	 * The convertor used to translate lat/lon points to screen points.
 	 */
 	private Projection projection = new UTM();
+
+
 	/**
 	 * Whether nodes on the same place should be considered identical.
 	 */
-	private boolean mergeNodes = true;
+	public boolean mergeNodes = true;
+	
+	
 
+	/**
+	 * List of all available Projections.
+	 */
+	public static final Projection[] allProjections = new Projection[]{
+		new UTM(),
+		new LatitudeLongitude()
+	};
 
-
+	/**
+	 * Return the location of the preferences file
+	 */
+	public static String getPreferencesFile() {
+		return System.getProperty("user.home")+"/.josm-preferences";
+	}
+	
 	/**
 	 * Exception thrown in case of any loading/saving error (including parse errors).
@@ -53,57 +69,4 @@
 		}
 	}
-
-	/**
-	 * List of all available Projections.
-	 */
-	public static final Projection[] allProjections = new Projection[]{
-		new UTM(),
-		new LatitudeLongitude()
-	};
-
-
-
-
-	// listener stuff
-	
-	/**
-	 * The event listener list
-	 */
-	private List<PropertyChangeListener> listener = new LinkedList<PropertyChangeListener>();
-	/**
-	 * If <code>listener != null</code>, add it to the listener list.
-	 */
-	public void addPropertyChangeListener(PropertyChangeListener listener) {
-		if (listener != null)
-			this.listener.add(listener);
-	}
-	/**
-	 * If <code>listener != null</code>, remove it from the listener list.
-	 */
-	public void removePropertyChangeListener(PropertyChangeListener listener) {
-		if (listener != null)
-			this.listener.remove(listener);
-	}
-	/**
-	 * Fires an event that the property has changed.
-	 */
-	private void firePropertyChanged(String propName, Object oldValue, Object newValue) {
-		PropertyChangeEvent event = null;
-		for (PropertyChangeListener l : listener) {
-			if (event == null)
-				event = new PropertyChangeEvent(this, propName, oldValue, newValue);
-			l.propertyChange(event);
-		}
-	}
-
-	
-	
-	/**
-	 * Return the location of the preferences file
-	 */
-	public static String getPreferencesFile() {
-		return System.getProperty("user.home")+"/.josm-preferences";
-	}
-	
 	/**
 	 * Load from disk.
@@ -120,11 +83,11 @@
 			for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels())
 				if (lafInfo.getClassName().equals(lafClassName)) {
-					setLaf(lafInfo);
+					laf = lafInfo;
 					break;
 				}
-			if (getLaf() == null)
+			if (laf == null)
 				throw new PreferencesException("Look and Feel not found.", null);
-
-			// set projection
+			
+			// projection
 			Class<?> projectionClass = Class.forName(root.getChildText("projection"));
 			projection = allProjections[0]; // defaults to UTM
@@ -136,5 +99,5 @@
 			}
 
-			setMergeNodes(root.getChild("mergeNodes") != null);
+			mergeNodes = root.getChild("mergeNodes") != null;
 		} catch (Exception e) {
 			if (e instanceof PreferencesException)
@@ -153,7 +116,7 @@
 		
 		List children = root.getChildren();
-		children.add(new Element("laf").setText(getLaf().getClassName()));
+		children.add(new Element("laf").setText(laf.getClassName()));
 		children.add(new Element("projection").setText(getProjection().getClass().getName()));
-		if (isMergeNodes())
+		if (mergeNodes)
 			children.add(new Element("mergeNodes"));
 
@@ -167,29 +130,49 @@
 	}
 
-	// getter / setter
-
+	
+	// projection change listener stuff
+	
+	/**
+	 * This interface notifies any interested about changes in the projection
+	 * @author imi
+	 */
+	public interface ProjectionChangeListener {
+		void projectionChanged(Projection oldProjection, Projection newProjection);
+	}
+	/**
+	 * The list of all listeners to projection changes.
+	 */
+	private Collection<ProjectionChangeListener> listener = new LinkedList<ProjectionChangeListener>();
+	/**
+	 * Add a listener of projection changes to the list of listeners.
+	 * @param listener The listerner to add.
+	 */
+	public void addProjectionChangeListener(ProjectionChangeListener listener) {
+		if (listener != null)
+			this.listener.add(listener);
+	}
+	/**
+	 * Remove the listener from the list.
+	 */
+	public void removeProjectionChangeListener(ProjectionChangeListener listener) {
+		this.listener.remove(listener);
+	}
+	/**
+	 * Set the projection and fire an event to all ProjectionChangeListener
+	 * @param projection The new Projection.
+	 */
 	public void setProjection(Projection projection) {
 		Projection old = this.projection;
 		this.projection = projection;
-		firePropertyChanged("projection", old, projection);
+		if (old != projection)
+			for (ProjectionChangeListener l : listener)
+				l.projectionChanged(old, projection);
 	}
+	/**
+	 * Get the current projection.
+	 * @return The current projection set.
+	 */
 	public Projection getProjection() {
 		return projection;
 	}
-	public void setMergeNodes(boolean mergeNodes) {
-		boolean old = this.mergeNodes;
-		this.mergeNodes = mergeNodes;
-		firePropertyChanged("mergeNodes", old, mergeNodes);
-	}
-	public boolean isMergeNodes() {
-		return mergeNodes;
-	}
-	public void setLaf(LookAndFeelInfo laf) {
-		LookAndFeelInfo old = this.laf;
-		this.laf = laf;
-		firePropertyChanged("laf", old, laf);
-	}
-	public LookAndFeelInfo getLaf() {
-		return laf;
-	}
 }
Index: src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 15)
+++ src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 16)
@@ -113,16 +113,16 @@
 		Node first = nodes.iterator().next();
 		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
-		for (Node n : nodes)
+		for (Node w : nodes)
 		{
-			if (Double.isNaN(n.coor.x) || Double.isNaN(n.coor.y))
+			if (Double.isNaN(w.coor.x) || Double.isNaN(w.coor.y))
 				return null;
-			if (n.coor.x < b.min.x)
-				b.min.x = n.coor.x;
-			if (n.coor.y < b.min.y)
-				b.min.y = n.coor.y;
-			if (n.coor.x > b.max.x)
-				b.max.x = n.coor.x;
-			if (n.coor.y > b.max.y)
-				b.max.y = n.coor.y;
+			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;
Index: src/org/openstreetmap/josm/data/projection/LatitudeLongitude.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/LatitudeLongitude.java	(revision 15)
+++ src/org/openstreetmap/josm/data/projection/LatitudeLongitude.java	(revision 16)
@@ -1,5 +1,5 @@
 package org.openstreetmap.josm.data.projection;
 
-import javax.swing.JPanel;
+import javax.swing.JComponent;
 
 import org.openstreetmap.josm.data.GeoPoint;
@@ -30,11 +30,10 @@
 
 	@Override
-	public String description() {
-		return "Use lat/lon values directly.";
+	public JComponent getConfigurationPanel() {
+		return null;
 	}
 
 	@Override
-	public JPanel getConfigurationPanel() {
-		return null;
+	public void commitConfigurationPanel() {
 	}
 }
Index: src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Projection.java	(revision 15)
+++ src/org/openstreetmap/josm/data/projection/Projection.java	(revision 16)
@@ -47,22 +47,26 @@
 	abstract public String toString();
 	
-	/**
-	 * Describe the projection converter. Give examples, where it is best to use
-	 * and maybe a reference link to more information about the converter. 
-	 */
-	abstract public String description();
-
-	
-
 	// miscellous functions
 	
 	/**
 	 * If the projection supports any configuration, this function return
-	 * the configuration panel. If no configuration needed, return null.
+	 * the configuration panel. If no configuration needed, 
+	 * return <code>null</code>.
 	 * 
-	 * The items on the configuration panel should update the configuration
-	 * directly, so the changes are instantly visible on screen.
+	 * The items on the configuration panel should not update the configuration
+	 * directly, but remember changed settings so a call to commitConfigurationPanel
+	 * can set them.
+	 * 
+	 * This function also rolls back all changes to the configuration panel interna
+	 * components.
 	 */
 	abstract public JComponent getConfigurationPanel();
+	/**
+	 * Commits any changes from components created by addToConfigurationPanel.
+	 * The projection should now obtain the new settings. If any setting has
+	 * changed, the implementation have to call to fireStateChanged to inform
+	 * the listeners.
+	 */
+	abstract public void commitConfigurationPanel();
 
 	/**
Index: src/org/openstreetmap/josm/data/projection/UTM.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/UTM.java	(revision 15)
+++ src/org/openstreetmap/josm/data/projection/UTM.java	(revision 16)
@@ -1,21 +1,23 @@
 package org.openstreetmap.josm.data.projection;
 
+import java.awt.Font;
+import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 
-import javax.swing.BorderFactory;
-import javax.swing.Box;
+import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
 import javax.swing.JSpinner;
 import javax.swing.SpinnerNumberModel;
-import javax.swing.border.Border;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
 
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.GBC;
+import org.openstreetmap.josm.gui.Main;
 
 /**
@@ -93,4 +95,17 @@
 	protected Ellipsoid ellipsoid = allEllipsoids[allEllipsoids.length-1];
 
+	/**
+	 * Combobox with all ellipsoids for the configuration panel
+	 */
+	private JComboBox ellipsoidCombo = new JComboBox(allEllipsoids);
+	/**
+	 * Spinner with all possible zones for the configuration panel
+	 */
+	private JSpinner zoneSpinner = new JSpinner(new SpinnerNumberModel(1,1,60,1));
+	/**
+	 * Hemisphere combo for the configuration panel
+	 */
+	private JComboBox hemisphereCombo = new JComboBox(Hemisphere.values());
+
 	
 	@Override
@@ -168,11 +183,48 @@
 	}
 
-	@Override
-	public String description() {
-		return "UTM projection ported from Ben Gimpert's ruby port.\n" +
-			"http://www.openstreetmap.org/websvn/filedetails.php?repname=" +
-			"OpenStreetMap&path=%2Futils%2Ftiger_import%2Ftiger%2Futm.rb";
-	}
-
+	/**
+	 * Helper class for the zone detection
+	 * @author imi
+	 */
+	private class ZoneData {
+		int zone = 0;
+		Hemisphere hemisphere = Hemisphere.north;
+	}
+	/**
+	 * Try to autodetect the zone and hemisphere from the dataset.
+	 * @param dataSet The dataset to extrakt zone information from.
+	 * @return The zone data extrakted from the dataset.
+	 */
+	private ZoneData autoDetect(DataSet dataSet) {
+		ZoneData zd = new ZoneData();
+		
+		Bounds b = dataSet.getBoundsLatLon();
+		if (b == null)
+			return zd;
+		GeoPoint center = b.centerLatLon();
+		double lat = center.lat;
+		double lon = center.lon;
+		// make sure the longitude is between -180.00 .. 179.9
+		double long_temp = (lon + 180) - (Math.floor((lon + 180) / 360) * 360) - 180;
+		
+		zd.zone = (int)((long_temp + 180) / 6) + 1;
+		if ((lat >= 56.0) && (lat < 64.0) && (long_temp >= 3.0) && (long_temp < 12.0))
+			zd.zone = 32; 
+		// special zones for Svalbard
+		if ((lat >= 72.0) && (lat < 84.0))
+		{
+			if ((long_temp >= 0.0) && (long_temp < 9.0))
+				zd.zone = 31;
+			else if ((long_temp >= 9.0) && (long_temp < 21.0))
+				zd.zone = 33;
+			else if ((long_temp >= 21.0) && (long_temp < 33.0))
+				zd.zone = 35;
+			else if ((long_temp >= 33.0) && (long_temp < 42.0))
+				zd.zone = 37;
+		}
+		zd.hemisphere = lat > 0 ? Hemisphere.north : Hemisphere.south;
+		return zd;
+	}
+	
 	/**
 	 * If the zone is not already set, calculate it from this dataset. 
@@ -184,29 +236,7 @@
 	public void init(DataSet dataSet) {
 		if (zone == 0) {
-			Bounds b = dataSet.getBoundsLatLon();
-			if (b == null)
-				return;
-			GeoPoint center = b.centerLatLon();
-			double lat = center.lat;
-			double lon = center.lon;
-			// make sure the longitude is between -180.00 .. 179.9
-			double long_temp = (lon + 180) - (Math.floor((lon + 180) / 360) * 360) - 180;
-			
-			zone = (int)((long_temp + 180) / 6) + 1;
-			if ((lat >= 56.0) && (lat < 64.0) && (long_temp >= 3.0) && (long_temp < 12.0))
-				zone = 32; 
-			// special zones for Svalbard
-			if ((lat >= 72.0) && (lat < 84.0))
-			{
-				if ((long_temp >= 0.0) && (long_temp < 9.0))
-					zone = 31;
-				else if ((long_temp >= 9.0) && (long_temp < 21.0))
-					zone = 33;
-				else if ((long_temp >= 21.0) && (long_temp < 33.0))
-					zone = 35;
-				else if ((long_temp >= 33.0) && (long_temp < 42.0))
-					zone = 37;
-			}
-			hemisphere = lat > 0 ? Hemisphere.north : Hemisphere.south;
+			ZoneData zd = autoDetect(dataSet);
+			zone = zd.zone;
+			hemisphere = zd.hemisphere;
 		}
 	}
@@ -214,52 +244,55 @@
 	@Override
 	public JComponent getConfigurationPanel() {
-		Border border = BorderFactory.createEmptyBorder(5,0,0,0);
-		Box panel = Box.createVerticalBox();
-
+		JPanel panel = new JPanel(new GridBagLayout());
+		GBC gbc = GBC.std().insets(0,0,5,0);
+		
 		// ellipsoid
-		Box ellipsoidPanel = Box.createHorizontalBox();
-		ellipsoidPanel.add(new JLabel("Ellipsoid"));
-		final JComboBox ellipsoidCombo = new JComboBox(allEllipsoids);
-		ellipsoidPanel.add(ellipsoidCombo);
+		panel.add(new JLabel("Ellipsoid"), gbc);
+		panel.add(ellipsoidCombo, GBC.eol());
 		ellipsoidCombo.setSelectedItem(ellipsoid);
-		ellipsoidCombo.addActionListener(new ActionListener(){
+		
+		// zone
+		panel.add(new JLabel("Zone"), gbc);
+		panel.add(zoneSpinner, GBC.eol().insets(0,5,0,5));
+		if (zone != 0)
+			zoneSpinner.setValue(zone);
+		
+		// hemisphere
+		panel.add(new JLabel("Hemisphere"), gbc);
+		panel.add(hemisphereCombo, GBC.eop());
+		hemisphereCombo.setSelectedItem(hemisphere);
+
+		// Autodetect
+		JButton autoDetect = new JButton("Detect");
+		autoDetect.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
-				ellipsoid = (Ellipsoid)ellipsoidCombo.getSelectedItem();
-				fireStateChanged();
+				if (Main.main.getMapFrame() != null) {
+					DataSet ds = Main.main.getMapFrame().mapView.dataSet;
+					ZoneData zd = autoDetect(ds);
+					if (zd.zone == 0)
+						JOptionPane.showMessageDialog(Main.main, "Autodetection failed. Maybe the data set contain too few information.");
+					else {
+						zoneSpinner.setValue(zd.zone);
+						hemisphereCombo.setSelectedItem(zd.hemisphere);
+					}
+				} else {
+					JOptionPane.showMessageDialog(Main.main, "No data loaded. Please open a data set first.");
+				}
 			}
 		});
-		ellipsoidPanel.setBorder(border);
-		panel.add(ellipsoidPanel);
-		
-		// zone
-		Box zonePanel = Box.createHorizontalBox();
-		zonePanel.add(new JLabel("Zone"));
-		final JSpinner zoneSpinner = new JSpinner(new SpinnerNumberModel(zone,1,60,1));
-		zonePanel.add(zoneSpinner);
-		zoneSpinner.addChangeListener(new ChangeListener(){
-			public void stateChanged(ChangeEvent e) {
-				zone = (Integer)zoneSpinner.getValue();
-				fireStateChanged();
-			}
-		});
-		zonePanel.setBorder(border);
-		panel.add(zonePanel);
-		
-		// hemisphere
-		Box hemispherePanel = Box.createHorizontalBox();
-		hemispherePanel.add(new JLabel("Hemisphere"));
-		final JComboBox hemisphereCombo = new JComboBox(Hemisphere.values());
-		hemispherePanel.add(hemisphereCombo);
-		hemisphereCombo.setSelectedItem(hemisphere);
-		hemisphereCombo.addActionListener(new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				hemisphere = (Hemisphere)hemisphereCombo.getSelectedItem();
-				fireStateChanged();
-			}
-		});
-		hemispherePanel.setBorder(border);
-		panel.add(hemispherePanel);
-
+		JLabel descLabel = new JLabel("Autodetect parameter based on loaded data");
+		descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC));
+		panel.add(descLabel, GBC.eol().fill(GBC.HORIZONTAL));
+		panel.add(autoDetect, GBC.eol().anchor(GBC.CENTER));
+		
 		return panel;
 	}
+
+	@Override
+	public void commitConfigurationPanel() {
+		ellipsoid = (Ellipsoid)ellipsoidCombo.getSelectedItem();
+		zone = (Integer)zoneSpinner.getValue();
+		hemisphere = (Hemisphere)hemisphereCombo.getSelectedItem();
+		fireStateChanged();
+	}
 }
Index: src/org/openstreetmap/josm/gui/GBC.java
===================================================================
--- src/org/openstreetmap/josm/gui/GBC.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/GBC.java	(revision 16)
@@ -41,4 +41,13 @@
 	}
 	
+	/**
+	 * 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
Index: src/org/openstreetmap/josm/gui/Layer.java
===================================================================
--- src/org/openstreetmap/josm/gui/Layer.java	(revision 15)
+++ 	(revision )
@@ -1,373 +1,0 @@
-package org.openstreetmap.josm.gui;
-
-import java.awt.Graphics;
-import java.awt.Point;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.JComponent;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.gui.engine.Engine;
-import org.openstreetmap.josm.gui.engine.SimpleEngine;
-
-/**
- * This is a component used in the MapFrame for browsing the map. It use is to
- * provide the MapMode's enough capabilities to operate.
- * 
- * Layer holds one dataset. There can be more than one Layer active.
- * 
- * Layer hold data of the current displayed graphics as scale level and
- * center point view.
- * 
- * @author imi
- */
-public class Layer extends JComponent implements ComponentListener, ChangeListener, PropertyChangeListener {
-
-	/**
-	 * Whether to adjust the scale property on every resize.
-	 */
-	private boolean autoScale = true;
-
-	/**
-	 * The scale factor in meter per pixel.
-	 */
-	private double scale;
-	/**
-	 * Center n/e coordinate of the desired screen center.
-	 */
-	private GeoPoint center;
-
-	/**
-	 * The underlying DataSet.
-	 */
-	public final DataSet dataSet;
-
-	/**
-	 * The drawing engine.
-	 */
-	private Engine engine;
-	
-	/**
-	 * Construct a Layer.
-	 */
-	public Layer(DataSet dataSet) {
-		this.dataSet = dataSet;
-		addComponentListener(this);
-
-		// initialize the movement listener
-		new MapMover(this);
-
-		// initialize the drawing engine
-		engine = new SimpleEngine(this);
-		
-		// initialize on the preferences for projection changes.
-		Main.pref.addPropertyChangeListener(this);
-	}
-
-	/**
-	 * 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.
-	 *  
-	 * @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 = (x - getWidth()/2.0)*scale + center.x;
-		p.y = (getHeight()/2.0 - y)*scale + center.y;
-		if (latlon)
-			Main.pref.getProjection().xy2latlon(p);
-		return p;
-	}
-	
-	/**
-	 * Return the point on the screen where this GeoPoint would be.
-	 * @param point The point, where this geopoint would be drawn.
-	 * @return The point on screen where "point" would be drawn, relative
-	 * 		to the own top/left.
-	 */
-	public Point getScreenPoint(GeoPoint point) {
-		GeoPoint p;
-		if (!Double.isNaN(point.x) && !Double.isNaN(point.y))
-			p = point;
-		else {
-			if (Double.isNaN(point.lat) || Double.isNaN(point.lon))
-				throw new IllegalArgumentException("point: Either lat/lon or x/y must be set.");
-			p = point.clone();
-			Main.pref.getProjection().latlon2xy(p);
-		}
-		int x = ((int)Math.round((p.x-center.x) / scale + getWidth()/2));
-		int y = ((int)Math.round((center.y-p.y) / scale + getHeight()/2));
-		return new Point(x,y);
-	}
-
-	/**
-	 * Return the object, that is nearest to the given screen point.
-	 * 
-	 * First, a node will be searched. If a node within 10 pixel is found, the
-	 * nearest node is returned.
-	 * 
-	 * If no node is found, search for pending line segments.
-	 * 
-	 * If no such line segment is found, and a non-pending line segment is 
-	 * within 10 pixel to p, this segment is returned, except when 
-	 * <code>wholeTrack</code> is <code>true</code>, in which case the 
-	 * corresponding Track is returned.
-	 * 
-	 * If no line segment is found and the point is within an area, return that
-	 * area.
-	 * 
-	 * If no area is found, return <code>null</code>.
-	 * 
-	 * @param p				The point on screen.
-	 * @param wholeTrack	Whether the whole track or only the line segment
-	 * 					 	should be returned.
-	 * @return	The primitive, that is nearest to the point p.
-	 */
-	public OsmPrimitive getNearest(Point p, boolean wholeTrack) {
-		double minDistanceSq = Double.MAX_VALUE;
-		OsmPrimitive minPrimitive = null;
-		
-		// nodes
-		for (Node n : dataSet.nodes) {
-			Point sp = getScreenPoint(n.coor);
-			double dist = p.distanceSq(sp);
-			if (minDistanceSq > dist && dist < 100) {
-				minDistanceSq = p.distanceSq(sp);
-				minPrimitive = n;
-			}
-		}
-		if (minPrimitive != null)
-			return minPrimitive;
-		
-		// pending line segments
-		for (LineSegment ls : dataSet.pendingLineSegments()) {
-			Point A = getScreenPoint(ls.getStart().coor);
-			Point B = getScreenPoint(ls.getEnd().coor);
-			double c = A.distanceSq(B);
-			double a = p.distanceSq(B);
-			double b = p.distanceSq(A);
-			double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
-			if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
-				minDistanceSq = perDist;
-				minPrimitive = ls;
-			}
-		}
-
-		// tracks & line segments
-		minDistanceSq = Double.MAX_VALUE;
-		for (Track t : dataSet.tracks()) {
-			for (LineSegment ls : t.segments()) {
-				Point A = getScreenPoint(ls.getStart().coor);
-				Point B = getScreenPoint(ls.getEnd().coor);
-				double c = A.distanceSq(B);
-				double a = p.distanceSq(B);
-				double b = p.distanceSq(A);
-				double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
-				if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
-					minDistanceSq = perDist;
-					minPrimitive = wholeTrack ? t : ls;
-				}
-			}			
-		}
-		if (minPrimitive != null)
-			return minPrimitive;
-		
-		// TODO areas
-		
-		return null; // nothing found
-	}
-
-	
-	/**
-	 * Zoom to the given coordinate.
-	 * @param centerX The center x-value (easting) to zoom to.
-	 * @param centerY The center y-value (northing) to zoom to.
-	 * @param scale The scale to use.
-	 */
-	public void zoomTo(GeoPoint newCenter, double scale) {
-		boolean oldAutoScale = autoScale;
-		GeoPoint oldCenter = center;
-		double oldScale = this.scale;
-		
-		autoScale = false;
-		center = newCenter.clone();
-		Main.pref.getProjection().xy2latlon(center);
-		this.scale = scale;
-		recalculateCenterScale();
-
-		firePropertyChange("center", oldCenter, center);
-		if (oldAutoScale != autoScale)
-			firePropertyChange("autoScale", oldAutoScale, autoScale);
-		if (oldScale != scale)
-			firePropertyChange("scale", oldScale, scale);
-	}
-	
-	/**
-	 * Draw the component.
-	 */
-	@Override
-	public void paint(Graphics g) {
-		engine.init(g);
-		engine.drawBackground(getPoint(0,0,true), getPoint(getWidth(), getHeight(), true));
-
-		for (Track t : dataSet.tracks())
-			engine.drawTrack(t);
-		for (LineSegment ls : dataSet.pendingLineSegments())
-			engine.drawPendingLineSegment(ls);
-		for (Node n : dataSet.nodes)
-			engine.drawNode(n);
-	}
-
-	/**
-	 * Notify from the projection, that something has changed.
-	 * @param e
-	 */
-	public void stateChanged(ChangeEvent e) {
-		initDataSet();
-	}
-
-	/**
-	 * Called when a property, as example the projection of the Main preferences
-	 * changes.
-	 */
-	public void propertyChange(PropertyChangeEvent evt) {
-		if (evt.getPropertyName().equals("projection")) {
-			Projection oldProjection = (Projection)evt.getOldValue();
-			if (oldProjection != null)
-				oldProjection.removeChangeListener(this);
-
-			Projection newProjection = (Projection)evt.getNewValue();
-			if (newProjection != null)
-				newProjection.addChangeListener(this);
-
-			initDataSet();
-		}
-	}
-
-	/**
-	 * Return the current scale value.
-	 * @return The scale value currently used in display
-	 */
-	public double getScale() {
-		return scale;
-	}
-
-	/**
-	 * @return Returns the autoScale.
-	 */
-	public boolean isAutoScale() {
-		return autoScale;
-	}
-
-	/**
-	 * @param autoScale The autoScale to set.
-	 */
-	public void setAutoScale(boolean autoScale) {
-		if (this.autoScale != autoScale) {
-			this.autoScale = autoScale;
-			if (autoScale)
-				recalculateCenterScale();
-			firePropertyChange("autoScale", !autoScale, autoScale);
-		}
-	}
-	/**
-	 * @return Returns the center point. A copy is returned, so users cannot
-	 * 		change the center by accessing the return value. Use zoomTo instead.
-	 */
-	public GeoPoint getCenter() {
-		return center.clone();
-	}
-
-	/**
-	 * Initialize the DataSet with the projection taken from the preference
-	 * settings.
-	 */
-	public void initDataSet() {
-		for (Node n : dataSet.nodes)
-			Main.pref.getProjection().latlon2xy(n.coor);
-		recalculateCenterScale();
-	}
-	
-	
-	/**
-	 * Set the new dimension to the projection class. Also adjust the components 
-	 * scale, if in autoScale mode.
-	 */
-	private void recalculateCenterScale() {
-		if (autoScale) {
-			// -20 to leave some border
-			int w = getWidth()-20;
-			if (w < 20)
-				w = 20;
-			int h = getHeight()-20;
-			if (h < 20)
-				h = 20;
-			Bounds bounds = dataSet.getBoundsXY();
-			
-			boolean oldAutoScale = autoScale;
-			GeoPoint oldCenter = center;
-			double oldScale = this.scale;
-			
-			if (bounds == null) {
-				// no bounds means standard scale and center 
-				center = new GeoPoint(51.526447, -0.14746371);
-				Main.pref.getProjection().latlon2xy(center);
-				scale = 10;
-			} else {
-				center = bounds.centerXY();
-				Main.pref.getProjection().xy2latlon(center);
-				double scaleX = (bounds.max.x-bounds.min.x)/w;
-				double scaleY = (bounds.max.y-bounds.min.y)/h;
-				scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
-			}
-	
-			firePropertyChange("center", oldCenter, center);
-			if (oldAutoScale != autoScale)
-				firePropertyChange("autoScale", oldAutoScale, autoScale);
-			if (oldScale != scale)
-				firePropertyChange("scale", oldScale, scale);
-		}
-		repaint();
-	}
-
-	/**
-	 * Call to recalculateCenterScale.
-	 */
-	public void componentResized(ComponentEvent e) {
-		recalculateCenterScale();
-	}
-
-	/**
-	 * Does nothing. Just to satisfy ComponentListener.
-	 */
-	public void componentMoved(ComponentEvent e) {}
-	/**
-	 * Does nothing. Just to satisfy ComponentListener.
-	 */
-	public void componentShown(ComponentEvent e) {}
-	/**
-	 * Does nothing. Just to satisfy ComponentListener.
-	 */
-	public void componentHidden(ComponentEvent e) {}
-}
Index: src/org/openstreetmap/josm/gui/Main.java
===================================================================
--- src/org/openstreetmap/josm/gui/Main.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/Main.java	(revision 16)
@@ -5,4 +5,5 @@
 import java.awt.Container;
 
+import javax.swing.ImageIcon;
 import javax.swing.JFrame;
 import javax.swing.JMenu;
@@ -19,6 +20,4 @@
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.projection.Projection;
 
 /**
@@ -103,4 +102,6 @@
 	 */
 	public static void main(String[] args) {
+		setupUiDefaults();
+		
 		// load preferences
 		String errMsg = null;
@@ -121,5 +122,5 @@
 		
 		try {
-			UIManager.setLookAndFeel(pref.getLaf().getClassName());
+			UIManager.setLookAndFeel(pref.laf.getClassName());
 		} catch (Exception e) {
 			e.printStackTrace();
@@ -133,11 +134,10 @@
 
 	/**
-	 * Create and 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
+	 * 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. 
 	 */
-	public void setMapFrame(String name, DataSet dataSet) {
+	public void setMapFrame(String name, MapFrame mapFrame) {
 		//TODO: Check for changes and ask user
-		MapFrame mapFrame = new MapFrame(dataSet);
 		this.name = name;
 		this.mapFrame = mapFrame;
@@ -147,7 +147,4 @@
 		panel.add(mapFrame.toolBarActions, BorderLayout.WEST);
 		panel.add(mapFrame.statusLine, BorderLayout.SOUTH);
-		for (Projection p : Preferences.allProjections)
-			p.init(dataSet);
-		mapFrame.layer.initDataSet();
 		panel.setVisible(true);
 	}
@@ -165,3 +162,13 @@
 	}
 
+	
+	/**
+	 * Sets some icons to the ui.
+	 */
+	private static void setupUiDefaults() {
+		UIManager.put("OptionPane.okIcon", new ImageIcon(Main.class.getResource("/images/ok.png")));
+		UIManager.put("OptionPane.yesIcon", UIManager.get("OptionPane.okIcon"));
+		UIManager.put("OptionPane.cancelIcon", new ImageIcon(Main.class.getResource("/images/cancel.png")));
+		UIManager.put("OptionPane.noIcon", UIManager.get("OptionPane.cancelIcon"));
+	}
 }
Index: src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapFrame.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/MapFrame.java	(revision 16)
@@ -14,5 +14,4 @@
 import javax.swing.JToolBar;
 
-import org.openstreetmap.josm.actions.AutoScaleAction;
 import org.openstreetmap.josm.actions.mapmode.AddLineSegmentAction;
 import org.openstreetmap.josm.actions.mapmode.AddNodeAction;
@@ -26,4 +25,5 @@
 import org.openstreetmap.josm.actions.mapmode.ZoomAction;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.dialogs.PropertiesDialog;
 import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
 
@@ -43,5 +43,5 @@
 	 * The view control displayed.
 	 */
-	public Layer layer;
+	public MapView mapView;
 	/**
 	 * The toolbar with the action icons
@@ -61,5 +61,5 @@
 		setLayout(new BorderLayout());
 
-		add(layer = new Layer(dataSet), BorderLayout.CENTER);
+		add(mapView = new MapView(dataSet), BorderLayout.CENTER);
 
 		// toolbar
@@ -84,14 +84,17 @@
 		// autoScale
 		toolBarActions.addSeparator();
-		final JToggleButton autoScaleButton = new IconToggleButton(this, new AutoScaleAction(layer));
+		final JToggleButton autoScaleButton = new IconToggleButton(this, mapView.new AutoScaleAction());
 		toolBarActions.add(autoScaleButton);
 		autoScaleButton.setText(null);
-		autoScaleButton.setSelected(layer.isAutoScale());
-		layer.addPropertyChangeListener(new PropertyChangeListener(){
+		autoScaleButton.setSelected(mapView.isAutoScale());
+		mapView.addPropertyChangeListener(new PropertyChangeListener(){
 			public void propertyChange(PropertyChangeEvent evt) {
 				if (evt.getPropertyName().equals("autoScale"))
-					autoScaleButton.setSelected(layer.isAutoScale());
+					autoScaleButton.setSelected(mapView.isAutoScale());
 			}
 		});
+
+		// properties
+		toolBarActions.add(new IconToggleButton(this, new PropertiesDialog(this)));
 
 		// selection dialog
@@ -107,5 +110,5 @@
 
 		// status line below the map
-		statusLine = new MapStatus(layer);
+		statusLine = new MapStatus(mapView);
 	}
 
Index: src/org/openstreetmap/josm/gui/MapMover.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapMover.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/MapMover.java	(revision 16)
@@ -26,5 +26,5 @@
 	 * The map to move around.
 	 */
-	private final Layer mv;
+	private final MapView mv;
 	/**
 	 * The old cursor when we changed it to movement cursor.
@@ -34,8 +34,8 @@
 	/**
 	 * Create a new MapMover
-	 * @param layer The map that should be moved.
+	 * @param mapView The map that should be moved.
 	 */
-	public MapMover(Layer layer) {
-		this.mv = layer;
+	public MapMover(MapView mapView) {
+		this.mv = mapView;
 		mv.addMouseListener(this);
 		mv.addMouseMotionListener(this);
Index: src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapStatus.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/MapStatus.java	(revision 16)
@@ -39,7 +39,7 @@
 
 	/**
-	 * The Layer this status belongs. 
+	 * The MapView this status belongs. 
 	 */
-	final Layer mv;
+	final MapView mv;
 	/**
 	 * The position of the mouse cursor.
@@ -145,8 +145,8 @@
 	
 	/**
-	 * Construct a new MapStatus and attach it to the Layer.
-	 * @param mv The Layer the status line is part of.
+	 * Construct a new MapStatus and attach it to the map view.
+	 * @param mv The MapView the status line is part of.
 	 */
-	public MapStatus(final Layer mv) {
+	public MapStatus(final MapView mv) {
 		this.mv = mv;
 		
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 16)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 16)
@@ -0,0 +1,384 @@
+package org.openstreetmap.josm.gui;
+
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.GeoPoint;
+import org.openstreetmap.josm.data.Preferences.ProjectionChangeListener;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Track;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.engine.Engine;
+import org.openstreetmap.josm.gui.engine.SimpleEngine;
+
+/**
+ * This is a component used in the MapFrame for browsing the map. It use is to
+ * provide the MapMode's enough capabilities to operate. 
+ * 
+ * MapView holds the map data, organize it, convert it, provide access to it.
+ * 
+ * MapView hold meta-data about the data set currently displayed, as scale level,
+ * center point viewed, what scrolling mode or editing mode is selected or with
+ * what projection the map is viewed etc..
+ *
+ * @author imi
+ */
+public class MapView extends JComponent implements ComponentListener, ChangeListener, ProjectionChangeListener {
+
+	/**
+	 * Toggles the autoScale feature of the mapView
+	 * @author imi
+	 */
+	public class AutoScaleAction extends AbstractAction {
+		public AutoScaleAction() {
+			super("Auto Scale", new ImageIcon(Main.class.getResource("/images/autoscale.png")));
+			putValue(MNEMONIC_KEY, KeyEvent.VK_A);
+		}
+		public void actionPerformed(ActionEvent e) {
+			autoScale = !autoScale;
+			recalculateCenterScale();
+		}
+	}
+
+	/**
+	 * Whether to adjust the scale property on every resize.
+	 */
+	private boolean autoScale = true;
+
+	/**
+	 * The scale factor in meter per pixel.
+	 */
+	private double scale;
+	/**
+	 * Center n/e coordinate of the desired screen center.
+	 */
+	private GeoPoint center;
+
+	/**
+	 * The underlying DataSet.
+	 */
+	public final DataSet dataSet;
+
+	/**
+	 * The drawing engine.
+	 */
+	private Engine engine;
+	
+	/**
+	 * Construct a MapView.
+	 */
+	public MapView(DataSet dataSet) {
+		this.dataSet = dataSet;
+		addComponentListener(this);
+
+		// initialize the movement listener
+		new MapMover(this);
+
+		// initialize the projection
+		projectionChanged(null, Main.pref.getProjection());
+		Main.pref.addProjectionChangeListener(this);
+		
+		// initialize the drawing engine
+		engine = new SimpleEngine(this);
+	}
+
+	/**
+	 * 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.
+	 *  
+	 * @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 = (x - getWidth()/2.0)*scale + center.x;
+		p.y = (getHeight()/2.0 - y)*scale + center.y;
+		if (latlon)
+			Main.pref.getProjection().xy2latlon(p);
+		return p;
+	}
+	
+	/**
+	 * Return the point on the screen where this GeoPoint would be.
+	 * @param point The point, where this geopoint would be drawn.
+	 * @return The point on screen where "point" would be drawn, relative
+	 * 		to the own top/left.
+	 */
+	public Point getScreenPoint(GeoPoint point) {
+		GeoPoint p;
+		if (!Double.isNaN(point.x) && !Double.isNaN(point.y))
+			p = point;
+		else {
+			if (Double.isNaN(point.lat) || Double.isNaN(point.lon))
+				throw new IllegalArgumentException("point: Either lat/lon or x/y must be set.");
+			p = point.clone();
+			Main.pref.getProjection().latlon2xy(p);
+		}
+		int x = ((int)Math.round((p.x-center.x) / scale + getWidth()/2));
+		int y = ((int)Math.round((center.y-p.y) / scale + getHeight()/2));
+		return new Point(x,y);
+	}
+
+	/**
+	 * Return the object, that is nearest to the given screen point.
+	 * 
+	 * First, a node will be searched. If a node within 10 pixel is found, the
+	 * nearest node is returned.
+	 * 
+	 * If no node is found, search for pending line segments.
+	 * 
+	 * If no such line segment is found, and a non-pending line segment is 
+	 * within 10 pixel to p, this segment is returned, except when 
+	 * <code>wholeTrack</code> is <code>true</code>, in which case the 
+	 * corresponding Track is returned.
+	 * 
+	 * If no line segment is found and the point is within an area, return that
+	 * area.
+	 * 
+	 * If no area is found, return <code>null</code>.
+	 * 
+	 * @param p				The point on screen.
+	 * @param wholeTrack	Whether the whole track or only the line segment
+	 * 					 	should be returned.
+	 * @return	The primitive, that is nearest to the point p.
+	 */
+	public OsmPrimitive getNearest(Point p, boolean wholeTrack) {
+		double minDistanceSq = Double.MAX_VALUE;
+		OsmPrimitive minPrimitive = null;
+		
+		// nodes
+		for (Node n : dataSet.nodes) {
+			Point sp = getScreenPoint(n.coor);
+			double dist = p.distanceSq(sp);
+			if (minDistanceSq > dist && dist < 100) {
+				minDistanceSq = p.distanceSq(sp);
+				minPrimitive = n;
+			}
+		}
+		if (minPrimitive != null)
+			return minPrimitive;
+		
+		// pending line segments
+		for (LineSegment ls : dataSet.pendingLineSegments()) {
+			Point A = getScreenPoint(ls.getStart().coor);
+			Point B = getScreenPoint(ls.getEnd().coor);
+			double c = A.distanceSq(B);
+			double a = p.distanceSq(B);
+			double b = p.distanceSq(A);
+			double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
+			if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
+				minDistanceSq = perDist;
+				minPrimitive = ls;
+			}
+		}
+
+		// tracks & line segments
+		minDistanceSq = Double.MAX_VALUE;
+		for (Track t : dataSet.tracks()) {
+			for (LineSegment ls : t.segments()) {
+				Point A = getScreenPoint(ls.getStart().coor);
+				Point B = getScreenPoint(ls.getEnd().coor);
+				double c = A.distanceSq(B);
+				double a = p.distanceSq(B);
+				double b = p.distanceSq(A);
+				double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
+				if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
+					minDistanceSq = perDist;
+					minPrimitive = wholeTrack ? t : ls;
+				}
+			}			
+		}
+		if (minPrimitive != null)
+			return minPrimitive;
+		
+		// TODO areas
+		
+		return null; // nothing found
+	}
+
+	
+	/**
+	 * Zoom to the given coordinate.
+	 * @param centerX The center x-value (easting) to zoom to.
+	 * @param centerY The center y-value (northing) to zoom to.
+	 * @param scale The scale to use.
+	 */
+	public void zoomTo(GeoPoint newCenter, double scale) {
+		boolean oldAutoScale = autoScale;
+		GeoPoint oldCenter = center;
+		double oldScale = this.scale;
+		
+		autoScale = false;
+		center = newCenter.clone();
+		Main.pref.getProjection().xy2latlon(center);
+		this.scale = scale;
+		recalculateCenterScale();
+
+		firePropertyChange("center", oldCenter, center);
+		if (oldAutoScale != autoScale)
+			firePropertyChange("autoScale", oldAutoScale, autoScale);
+		if (oldScale != scale)
+			firePropertyChange("scale", oldScale, scale);
+	}
+	
+	/**
+	 * Draw the component.
+	 */
+	@Override
+	public void paint(Graphics g) {
+		engine.init(g);
+		engine.drawBackground(getPoint(0,0,true), getPoint(getWidth(), getHeight(), true));
+
+		for (Track t : dataSet.tracks())
+			engine.drawTrack(t);
+		for (LineSegment ls : dataSet.pendingLineSegments())
+			engine.drawPendingLineSegment(ls);
+		for (Node n : dataSet.nodes)
+			engine.drawNode(n);
+	}
+
+	/**
+	 * Notify from the projection, that something has changed.
+	 * @param e
+	 */
+	public void stateChanged(ChangeEvent e) {
+		for (Node n : dataSet.nodes)
+			Main.pref.getProjection().latlon2xy(n.coor);
+		recalculateCenterScale();
+	}
+
+	/**
+	 * Return the current scale value.
+	 * @return The scale value currently used in display
+	 */
+	public double getScale() {
+		return scale;
+	}
+
+	/**
+	 * @return Returns the autoScale.
+	 */
+	public boolean isAutoScale() {
+		return autoScale;
+	}
+
+	/**
+	 * @param autoScale The autoScale to set.
+	 */
+	public void setAutoScale(boolean autoScale) {
+		if (this.autoScale != autoScale) {
+			this.autoScale = autoScale;
+			firePropertyChange("autoScale", !autoScale, autoScale);
+		}
+	}
+	/**
+	 * @return Returns the center point. A copy is returned, so users cannot
+	 * 		change the center by accessing the return value. Use zoomTo instead.
+	 */
+	public GeoPoint getCenter() {
+		return center.clone();
+	}
+
+	
+
+	/**
+	 * Change to the new projection. Recalculate the dataset and zoom, if autoZoom
+	 * is active.
+	 * @param oldProjection The old projection. Unregister from this.
+	 * @param newProjection	The new projection. Register as state change listener.
+	 */
+	public void projectionChanged(Projection oldProjection, Projection newProjection) {
+		if (oldProjection != null)
+			oldProjection.removeChangeListener(this);
+		if (newProjection != null) {
+			newProjection.addChangeListener(this);
+			newProjection.init(dataSet);
+			for (Node n : dataSet.nodes)
+				newProjection.latlon2xy(n.coor);
+		}
+		recalculateCenterScale();
+	}
+	
+	/**
+	 * Set the new dimension to the projection class. Also adjust the components 
+	 * scale, if in autoScale mode.
+	 */
+	private void recalculateCenterScale() {
+		if (autoScale) {
+			// -20 to leave some border
+			int w = getWidth()-20;
+			if (w < 20)
+				w = 20;
+			int h = getHeight()-20;
+			if (h < 20)
+				h = 20;
+			Bounds bounds = dataSet.getBoundsXY();
+			
+			boolean oldAutoScale = autoScale;
+			GeoPoint oldCenter = center;
+			double oldScale = this.scale;
+			
+			if (bounds == null) {
+				// no bounds means standard scale and center 
+				center = new GeoPoint(51.526447, -0.14746371);
+				Main.pref.getProjection().latlon2xy(center);
+				scale = 10;
+			} else {
+				center = bounds.centerXY();
+				Main.pref.getProjection().xy2latlon(center);
+				double scaleX = (bounds.max.x-bounds.min.x)/w;
+				double scaleY = (bounds.max.y-bounds.min.y)/h;
+				scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
+			}
+	
+			firePropertyChange("center", oldCenter, center);
+			if (oldAutoScale != autoScale)
+				firePropertyChange("autoScale", oldAutoScale, autoScale);
+			if (oldScale != scale)
+				firePropertyChange("scale", oldScale, scale);
+		}
+		repaint();
+	}
+
+	/**
+	 * Call to recalculateCenterScale.
+	 */
+	public void componentResized(ComponentEvent e) {
+		recalculateCenterScale();
+	}
+
+	/**
+	 * Does nothing. Just to satisfy ComponentListener.
+	 */
+	public void componentMoved(ComponentEvent e) {}
+	/**
+	 * Does nothing. Just to satisfy ComponentListener.
+	 */
+	public void componentShown(ComponentEvent e) {}
+	/**
+	 * Does nothing. Just to satisfy ComponentListener.
+	 */
+	public void componentHidden(ComponentEvent e) {}
+}
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 16)
@@ -7,8 +7,8 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
 import java.io.File;
 
 import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
 import javax.swing.Box;
 import javax.swing.DefaultListCellRenderer;
@@ -17,4 +17,5 @@
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
+import javax.swing.JComponent;
 import javax.swing.JDialog;
 import javax.swing.JLabel;
@@ -43,15 +44,16 @@
 	class OkAction extends AbstractAction {
 		public OkAction() {
-			super("Ok", new ImageIcon(Main.class.getResource("/images/ok.png")));
-			putValue(MNEMONIC_KEY, KeyEvent.VK_ENTER);
+			super(UIManager.getString("OptionPane.okButtonText"), 
+					UIManager.getIcon("OptionPane.okIcon"));
+			putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.okButtonMnemonic")));
 		}
 		public void actionPerformed(ActionEvent e) {
-			Preferences pref = new Preferences();
-			pref.setLaf((LookAndFeelInfo)lafCombo.getSelectedItem());
-			pref.setProjection((Projection)projectionCombo.getSelectedItem());
-			pref.setMergeNodes(mergeNodes.isSelected());
-			Main.pref.setProjection(pref.getProjection());
+			Main.pref.laf = (LookAndFeelInfo)lafCombo.getSelectedItem();
+			Projection projection = (Projection)projectionCombo.getSelectedItem();
+			projection.commitConfigurationPanel();
+			Main.pref.setProjection(projection);
+			Main.pref.mergeNodes = mergeNodes.isSelected();
 			try {
-				pref.save();
+				Main.pref.save();
 			} catch (PreferencesException x) {
 				x.printStackTrace();
@@ -69,6 +71,7 @@
 	class CancelAction extends AbstractAction {
 		public CancelAction() {
-			super("Cancel", new ImageIcon("images/cancel.png"));
-			putValue(MNEMONIC_KEY, KeyEvent.VK_ESCAPE);
+			super(UIManager.getString("OptionPane.cancelButtonText"), 
+					UIManager.getIcon("OptionPane.cancelIcon"));
+			putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.cancelButtonMnemonic")));
 		}
 		public void actionPerformed(ActionEvent e) {
@@ -125,5 +128,5 @@
 				return oldRenderer.getListCellRendererComponent(list, ((LookAndFeelInfo)value).getName(), index, isSelected, cellHasFocus);
 			}});
-		lafCombo.setSelectedItem(pref.getLaf());
+		lafCombo.setSelectedItem(pref.laf);
 		lafCombo.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
@@ -131,5 +134,5 @@
 			}});
 
-		// projection method combo box
+		// projection combo box
 		for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
 			if (projectionCombo.getItemAt(i).getClass().equals(pref.getProjection().getClass())) {
@@ -138,7 +141,28 @@
 			}
 		}
+		JButton projectionDetail = new JButton("Configure");
+		projectionDetail.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				Projection p = (Projection)projectionCombo.getSelectedItem();
+				JComponent configurationPanel = p.getConfigurationPanel();
+				if (configurationPanel == null) {
+					JOptionPane.showMessageDialog(PreferenceDialog.this,
+							"This projection does not need any configuration.");
+					return;
+				}
+				JPanel detail = new JPanel(new GridBagLayout());
+				detail.setLayout(new GridBagLayout());
+				detail.add(configurationPanel, GBC.eop().fill());
+				int result = JOptionPane.showConfirmDialog(
+						PreferenceDialog.this, detail, "Configuration of "+p, 
+						JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+				if (result != JOptionPane.OK_OPTION)
+					p.getConfigurationPanel(); // rollback
+			}
+		});
+		
 		
 		// Display tab
-		JPanel display = createPreferenceTab("display", "Display Settings", "Various settings than influence the visual representation of the whole Program.");
+		JPanel display = createPreferenceTab("display", "Display Settings", "Various settings that influence the visual representation of the whole program.");
 		display.add(new JLabel("Look and Feel"), GBC.std());
 		display.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
@@ -150,15 +174,11 @@
 		map.add(new JLabel("Projection method"), GBC.std());
 		map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
-		map.add(projectionCombo, GBC.eol().fill(GBC.HORIZONTAL));
-		JLabel labelNoteProjection = new JLabel(
-				"<html>Note: This is the default projection method used for files, " +
-				"where the correct projection could not be determined. " +
-				"The actual used projection can be changed in the property " +
-				"settings of each map.</html>");
-		labelNoteProjection.setMinimumSize(new Dimension(550, 50));
-		labelNoteProjection.setPreferredSize(new Dimension(550, 50));
-		map.add(labelNoteProjection, GBC.eol().insets(0,5,0,20));
+		map.add(projectionCombo, GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
+		map.add(new JLabel("Projection details:"), GBC.std());
+		map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
+		map.add(projectionDetail, GBC.eop());
+		
 		map.add(new JLabel("GPX import / export"), GBC.eol());
-		mergeNodes.setSelected(pref.isMergeNodes());
+		mergeNodes.setSelected(pref.mergeNodes);
 		map.add(mergeNodes, GBC.eol());
 		map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
@@ -172,4 +192,5 @@
 		okPanel.add(new JButton(new OkAction()), GBC.std());
 		okPanel.add(new JButton(new CancelAction()), GBC.std());
+		okPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
 
 		// merging all in the content pane
@@ -196,7 +217,8 @@
 		JPanel p = new JPanel(new GridBagLayout());
 		p.add(new JLabel(title), GBC.eol().anchor(GBC.CENTER).insets(0,5,0,10));
-		JLabel descLabel = new JLabel(desc);
+		
+		JLabel descLabel = new JLabel("<html>"+desc+"</html>");
 		descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC));
-		p.add(descLabel, GBC.eol().insets(5,0,5,20));
+		p.add(descLabel, GBC.eol().insets(5,0,5,20).fill(GBC.HORIZONTAL));
 
 		tabPane.addTab(null, new ImageIcon("images/preferences/"+icon+".png"), p);
Index: src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 16)
@@ -88,7 +88,7 @@
 	private Point mousePos;
 	/**
-	 * The Layer, the selection rectangle is drawn onto.
-	 */
-	private final Layer mv;
+	 * The MapView, the selection rectangle is drawn onto.
+	 */
+	private final MapView mv;
 	/**
 	 * Whether the selection rectangle must obtain the aspect ratio of the 
@@ -104,10 +104,10 @@
 	 * @param aspectRatio If true, the selection window must obtain the aspect
 	 * 		ratio of the drawComponent.
-	 * @param layer The view, the rectangle is drawn onto.
-	 */
-	public SelectionManager(SelectionEnded selectionEndedListener, boolean aspectRatio, Layer layer) {
+	 * @param mapView The view, the rectangle is drawn onto.
+	 */
+	public SelectionManager(SelectionEnded selectionEndedListener, boolean aspectRatio, MapView mapView) {
 		this.selectionEndedListener = selectionEndedListener;
 		this.aspectRatio = aspectRatio;
-		this.mv = layer;
+		this.mv = mapView;
 	}
 	
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 16)
@@ -5,4 +5,6 @@
 import javax.swing.BorderFactory;
 import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.border.Border;
 
 import org.openstreetmap.josm.gui.Main;
@@ -25,38 +27,10 @@
 		putValue(MNEMONIC_KEY, KeyEvent.VK_P);
 
-//		final Border panelBorder = BorderFactory.createEmptyBorder(5,0,0,0);
+		final Border panelBorder = BorderFactory.createEmptyBorder(5,0,0,0);
 		Box panel = Box.createVerticalBox();
-
-		// making an array of all projections and the current one within
-//		Projection[] allProjections = Preferences.allProjections.clone();
-//		for (int i = 0; i < allProjections.length; ++i)
-//			if (allProjections[i].getClass() == frame.layer.getProjection().getClass())
-//				allProjections[i] = frame.layer.getProjection();
-//		
-//		// projection
-//		Box projectionPanel = Box.createHorizontalBox();
-//		projectionPanel.setBorder(panelBorder);
-//		projectionPanel.add(new JLabel("Projection"));
-//		final JComboBox projectionCombo = new JComboBox(allProjections);
-//		projectionPanel.add(projectionCombo);
-//		panel.add(projectionPanel);
-//		final JPanel configurationPanel = new JPanel();
-//		configurationPanel.setLayout(new BoxLayout(configurationPanel, BoxLayout.X_AXIS));
-//		
-//		// projections details
-//		projectionCombo.addActionListener(new ActionListener(){
-//			public void actionPerformed(ActionEvent e) {
-//				configurationPanel.removeAll();
-//				frame.layer.setProjection((Projection)projectionCombo.getSelectedItem());
-//				JComponent panel = frame.layer.getProjection().getConfigurationPanel();
-//				if (panel != null) {
-//					panel.setBorder(panelBorder);
-//					configurationPanel.add(panel);
-//				}
-//				pack();
-//			}
-//		});
-//		panel.add(configurationPanel);
-//		projectionCombo.setSelectedItem(frame.layer.getProjection());
+		
+		JLabel todo = new JLabel("Nothing implemented yet.");
+		todo.setBorder(panelBorder);
+		panel.add(todo);
 		
 		panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
Index: src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 16)
@@ -2,4 +2,5 @@
 
 import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
 import java.util.HashMap;
 import java.util.Map;
@@ -30,6 +31,6 @@
 		putValue(NAME, name);
 		putValue(MNEMONIC_KEY, mnemonic);
-		putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(mnemonic,0));
-		putValue(LONG_DESCRIPTION, tooltip);
+		putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E,0));
+		putValue(LONG_DESCRIPTION, "Open a selection list window.");
 	}
 
Index: src/org/openstreetmap/josm/gui/engine/Engine.java
===================================================================
--- src/org/openstreetmap/josm/gui/engine/Engine.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/engine/Engine.java	(revision 16)
@@ -2,4 +2,6 @@
 
 import java.awt.Graphics;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 
 import org.openstreetmap.josm.data.GeoPoint;
@@ -7,5 +9,6 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Layer;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.MapView;
 
 /**
@@ -15,6 +18,10 @@
  * @author imi
  */
-abstract public class Engine {
+abstract public class Engine implements PropertyChangeListener {
 
+	/**
+	 * The projection method, this engine uses to render the graphics.
+	 */
+	protected Projection projection;
 	/**
 	 * The Graphics surface to draw on. This should be set before each painting
@@ -23,15 +30,16 @@
 	protected Graphics g;
 	/**
-	 * The layer, this engine was created for.
+	 * The mapView, this engine was created for.
 	 */
-	protected final Layer layer;
+	protected final MapView mv;
 
 	
 	/**
-	 * Creates an Engine from an Layer it belongs to.
-	 * @param layer The mapview this engine belongs to.
+	 * Creates an Engine from an MapView it belongs to.
+	 * @param mapView The mapview this engine belongs to.
 	 */
-	public Engine(Layer layer) {
-		this.layer = layer;
+	public Engine(MapView mapView) {
+		mv = mapView;
+		mv.addPropertyChangeListener(this);
 	}
 	
@@ -65,3 +73,12 @@
 	 */
 	abstract public void drawPendingLineSegment(LineSegment ls);
+
+	/**
+	 * Called when the projection method for the map changed. Subclasses with
+	 * caches depending on the projection should empty the cache now.
+	 */
+	public void propertyChange(PropertyChangeEvent e) {
+		if (e.getPropertyName().equals("projection"))
+			projection = (Projection)e.getNewValue();
+	}
 }
Index: src/org/openstreetmap/josm/gui/engine/SimpleEngine.java
===================================================================
--- src/org/openstreetmap/josm/gui/engine/SimpleEngine.java	(revision 15)
+++ src/org/openstreetmap/josm/gui/engine/SimpleEngine.java	(revision 16)
@@ -10,5 +10,5 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Layer;
+import org.openstreetmap.josm.gui.MapView;
 
 /**
@@ -23,6 +23,6 @@
 	private final static Color darkgreen = new Color(0,128,0);
 
-	public SimpleEngine(Layer layer) {
-		super(layer);
+	public SimpleEngine(MapView mapView) {
+		super(mapView);
 	}
 
@@ -33,5 +33,5 @@
 	public void drawBackground(GeoPoint ulGeo, GeoPoint lrGeo) {
 		g.setColor(Color.BLACK);
-		g.fillRect(0,0,layer.getWidth(),layer.getHeight());
+		g.fillRect(0,0,mv.getWidth(),mv.getHeight());
 	}
 
@@ -109,6 +109,6 @@
 	private void drawLineSegment(LineSegment ls, Color color) {
 		g.setColor(ls.isSelected() ? Color.WHITE : color);
-		Point p1 = layer.getScreenPoint(ls.getStart().coor);
-		Point p2 = layer.getScreenPoint(ls.getEnd().coor);
+		Point p1 = mv.getScreenPoint(ls.getStart().coor);
+		Point p2 = mv.getScreenPoint(ls.getEnd().coor);
 		g.drawLine(p1.x, p1.y, p2.x, p2.y);
 	}
@@ -121,5 +121,5 @@
 	 */
 	private void drawNode(Node n, Color color) {
-		Point p = layer.getScreenPoint(n.coor);
+		Point p = mv.getScreenPoint(n.coor);
 		g.setColor(color);
 		g.drawRect(p.x-1, p.y-1, 2, 2);
Index: src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxReader.java	(revision 15)
+++ src/org/openstreetmap/josm/io/GpxReader.java	(revision 16)
@@ -161,5 +161,5 @@
 	 */
 	private Node addNode (DataSet data, Node node) {
-		if (Main.pref.isMergeNodes())
+		if (Main.pref.mergeNodes)
 			for (Node n : data.nodes)
 				if (node.coor.lat == n.coor.lat && node.coor.lon == n.coor.lon)
