Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 97)
+++ src/org/openstreetmap/josm/Main.java	(revision 98)
@@ -1,15 +1,15 @@
-//Licence: GPL
 package org.openstreetmap.josm;
 
 import java.awt.BorderLayout;
+import java.awt.Component;
 import java.awt.Dimension;
-import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.Toolkit;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
 import java.io.File;
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.LinkedList;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.concurrent.Executor;
@@ -19,5 +19,4 @@
 
 import javax.swing.Action;
-import javax.swing.JFrame;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
@@ -44,23 +43,20 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.ShowModifiers;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.tools.BugReportExceptionHandler;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
 import org.openstreetmap.josm.tools.ImageProvider;
 
-/**
- * Main window class application.
- *  
- * @author imi
- */
-public class Main extends JFrame {
-
+abstract public class Main {
+	/**
+	 * Global parent component for all dialogs and message boxes
+	 */
+	public static Component parent;
 	/**
 	 * Global application window. Use this as JOPtionPane-parent to center on application.
 	 */
 	public static Main main;
-
 	/**
 	 * The worker thread slave. This is for executing all long and intensive
@@ -68,64 +64,71 @@
 	 * and sequenciel.
 	 */
-	public static Executor worker = Executors.newSingleThreadExecutor();
-
-
+	public final static Executor worker = Executors.newSingleThreadExecutor();
+	/**
+	 * Global application preferences
+	 */
+	public static Preferences pref = new Preferences();
+	/**
+	 * The global dataset.
+	 */
+	public static DataSet ds = new DataSet();
+	/**
+	 * The projection method used.
+	 */
 	public static Projection proj;
-
-	/**
-	 * Global application preferences
-	 */
-	public final static Preferences pref = new Preferences();
-
-	/**
-	 * The global dataset.
-	 */
-	public static DataSet ds = new DataSet();
-
-	/**
-	 * The main panel.
-	 */
-	public JPanel panel;
-	/**
-	 * The mapFrame currently loaded.
-	 */
-	private MapFrame mapFrame;
-
-	public final UndoAction undoAction;
-	public final RedoAction redoAction;
-
-	private OpenAction openAction;
-	private DownloadAction downloadAction;
-	//private Action wmsServerAction;
-
-	/**
-	 * Construct an main frame, ready sized and operating. Does not 
-	 * display the frame.
-	 */
+	/**
+	 * The MapFrame. Use setMapFrame to set or clear it.
+	 */
+	public static MapFrame map;
+
+	/**
+	 * Set or clear (if passed <code>null</code>) the map.
+	 */
+	public final void setMapFrame(final MapFrame map) {
+		Main.map = map;
+		panel.setVisible(false);
+		panel.removeAll();
+		if (map != null) {
+			map.fillPanel(panel);
+			panel.setVisible(true);
+			map.mapView.addLayerChangeListener(new LayerChangeListener(){
+				public void activeLayerChange(final Layer oldLayer, final Layer newLayer) {}
+				public void layerAdded(final Layer newLayer) {
+					if (newLayer instanceof OsmDataLayer)
+						Main.main.editLayer().listenerCommands.add(redoUndoListener);
+				}
+				public void layerRemoved(final Layer oldLayer) {}
+			});
+		}
+		redoUndoListener.commandChanged(0,0);
+	}
+
+	/**
+	 * Remove the specified layer from the map. If it is the last layer, remove the map as well.
+	 */
+	public final void removeLayer(final Layer layer) {
+		final Collection<Layer> allLayers = map.mapView.getAllLayers();
+		if (allLayers.size() == 1 && allLayers.iterator().next() == layer) {
+			Main.map.setVisible(false);
+			setMapFrame(null);
+			ds = new DataSet();
+		} else {
+			map.mapView.removeLayer(layer);
+			if (layer instanceof OsmDataLayer)
+				ds = new DataSet();
+		}
+	}
 	public Main() {
-		super("Java Open Street Map - Editor");
-		Main.main = this;
-		setLayout(new BorderLayout());
-		panel = new JPanel(new BorderLayout());
-		getContentPane().add(panel, BorderLayout.CENTER);
-		setSize(1000,740); // some strange default size
-
-		downloadAction = new DownloadAction();
-		Action uploadAction = new UploadAction();
-		//wmsServerAction = new WmsServerAction();
-		openAction = new OpenAction();
-		Action saveAction = new SaveAction();
-		Action gpxExportAction = new GpxExportAction(null);
-		Action exitAction = new ExitAction();
-		undoAction = new UndoAction();
-		redoAction = new RedoAction();
-		Action preferencesAction = new PreferencesAction();
-		Action aboutAction = new AboutAction();
-
-		// creating menu
-		JMenuBar mainMenu = new JMenuBar();
-		setJMenuBar(mainMenu);
-
-		JMenu fileMenu = new JMenu("Files");
+		main = this;
+		contentPane.add(panel, BorderLayout.CENTER);
+
+		final Action uploadAction = new UploadAction();
+		final Action saveAction = new SaveAction();
+		final Action gpxExportAction = new GpxExportAction(null);
+		final Action exitAction = new ExitAction();
+		final Action preferencesAction = new PreferencesAction();
+		final Action aboutAction = new AboutAction();
+
+		final JMenu fileMenu = new JMenu("Files");
 		fileMenu.setMnemonic('F');
 		fileMenu.add(openAction);
@@ -137,13 +140,12 @@
 
 
-		JMenu layerMenu = new JMenu("Layer");
+		final JMenu layerMenu = new JMenu("Layer");
 		layerMenu.setMnemonic('L');
 		layerMenu.add(downloadAction);
 		layerMenu.add(uploadAction);
 		layerMenu.addSeparator();
-		//layerMenu.add(new JCheckBoxMenuItem(wmsServerAction));
 		mainMenu.add(layerMenu);
 
-		JMenu editMenu = new JMenu("Edit");
+		final JMenu editMenu = new JMenu("Edit");
 		editMenu.setMnemonic('E');
 		editMenu.add(undoAction);
@@ -154,5 +156,5 @@
 
 		mainMenu.add(new JSeparator());
-		JMenu helpMenu = new JMenu("Help");
+		final JMenu helpMenu = new JMenu("Help");
 		helpMenu.setMnemonic('H');
 		helpMenu.add(aboutAction);
@@ -160,9 +162,8 @@
 
 		// creating toolbar
-		JToolBar toolBar = new JToolBar();
+		final JToolBar toolBar = new JToolBar();
 		toolBar.setFloatable(false);
 		toolBar.add(downloadAction);
 		toolBar.add(uploadAction);
-		//toolBar.add(new IconToggleButton(wmsServerAction));
 		toolBar.addSeparator();
 		toolBar.add(openAction);
@@ -174,92 +175,75 @@
 		toolBar.addSeparator();
 		toolBar.add(preferencesAction);
-
-		getContentPane().add(toolBar, BorderLayout.NORTH);
-
-		addWindowListener(new WindowAdapter(){
-			@Override public void windowClosing(WindowEvent arg0) {
-				if (mapFrame != null) {
-					boolean modified = false;
-					boolean uploadedModified = false;
-					for (Layer l : mapFrame.mapView.getAllLayers()) {
-						if (l instanceof OsmDataLayer && ((OsmDataLayer)l).isModified()) {
-							modified = true;
-							uploadedModified = ((OsmDataLayer)l).uploadedModified;
-							break;
-						}
-					}
-					if (modified) {
-						String msg = uploadedModified ? "\nHint: Some changes came from uploading new data to the server." : "";
-						int answer = JOptionPane.showConfirmDialog(
-								Main.this, "There are unsaved changes. Really quit?"+msg,
-								"Unsaved Changes", JOptionPane.YES_NO_OPTION);
-						if (answer != JOptionPane.YES_OPTION)
-							return;
-					}
-				}
-				System.exit(0);
-			}
-		});
-		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-	}
-
-	/**
-	 * Main application Startup
-	 * @param args	No parameters accepted.
-	 */
-	public static void main(String[] args) {
-		setupExceptionHandler();
-		setupUiDefaults();
-
-		LinkedList<String> arguments = new LinkedList<String>(Arrays.asList(args));
-
-		if (arguments.contains("--help") || arguments.contains("-?") || arguments.contains("-h")) {
-			System.out.println("Java OpenStreetMap Editor");
-			System.out.println();
-			System.out.println("usage:");
-			System.out.println("\tjava -jar josm.jar <option> <option> <option>...");
-			System.out.println();
-			System.out.println("options:");
-			System.out.println("\t--help|-?|-h                              Show this help");
-			System.out.println("\t--geometry=widthxheight(+|-)x(+|-)y       Standard unix geometry argument");
-			System.out.println("\t--download=minlat,minlon,maxlat,maxlon    Download the bounding box");
-			System.out.println("\t--downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box");
-			System.out.println("\t--selection=<searchstring>                Select with the given search");
-			System.out.println("\t--no-fullscreen                           Don't launch in fullscreen mode");
-			System.out.println("\t--reset-preferences                       Reset the preferences to default");
-			System.out.println("\tURL|filename(.osm|.xml|.gpx|.txt|.csv)    Open file / Download url");
-			System.out.println();
-			System.out.println("examples:");
-			System.out.println("\tjava -jar josm.jar track1.gpx track2.gpx london.osm");
-			System.out.println("\tjava -jar josm.jar http://www.openstreetmap.org/index.html?lat=43.2&lon=11.1&zoom=13");
-			System.out.println("\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml");
-			System.out.println("\tjava -jar josm.jar osm://43.2,11.1,43.4,11.4");
-			System.out.println();
-			System.out.println("Parameters are read in the order they are specified, so make sure you load");
-			System.out.println("some data before --selection");
-			System.out.println();
-			System.out.println("Instead of --download=<bbox> you may specify osm://<bbox>");
-			System.exit(0);
-		}
-
-		File prefDir = new File(Preferences.getPreferencesDir());
-		if (prefDir.exists() && !prefDir.isDirectory()) {
-			JOptionPane.showMessageDialog(null, "Cannot open preferences directory: "+Preferences.getPreferencesDir());
-			return;
-		}
-		if (!prefDir.exists())
-			prefDir.mkdirs();
-
+		contentPane.add(toolBar, BorderLayout.NORTH);
+
+		contentPane.updateUI();
+	}
+	/**
+	 * Add a new layer to the map. If no map exist, create one.
+	 */
+	public final void addLayer(final Layer layer) {
+		if (map == null) {
+			final MapFrame mapFrame = new MapFrame(layer);
+			setMapFrame(mapFrame);
+			mapFrame.setVisible(true);
+			mapFrame.setVisibleDialogs();
+		} else
+			map.mapView.addLayer(layer);
+	}
+	/**
+	 * @return The edit osm layer. If none exist, it will be created.
+	 */
+	public final OsmDataLayer editLayer() {
+		if (map == null || map.mapView.editLayer == null)
+			addLayer(new OsmDataLayer(ds, "unnamed", false));
+		return map.mapView.editLayer;
+	}
+
+
+
+
+	/**
+	 * Use this to register shortcuts to
+	 */
+	public static JPanel panel = new JPanel(new BorderLayout());
+
+
+	////////////////////////////////////////////////////////////////////////////////////////
+	//  Implementation part
+	////////////////////////////////////////////////////////////////////////////////////////
+
+
+	protected final JMenuBar mainMenu = new JMenuBar();
+	protected static final JPanel contentPane = new JPanel(new BorderLayout());
+	protected static Rectangle bounds;
+
+	private final UndoAction undoAction = new UndoAction();
+	private final RedoAction redoAction = new RedoAction();
+	private final OpenAction openAction = new OpenAction();
+	private final DownloadAction downloadAction = new DownloadAction();
+
+	private final CommandQueueListener redoUndoListener = new CommandQueueListener(){
+		public void commandChanged(final int queueSize, final int redoSize) {
+			undoAction.setEnabled(queueSize > 0);
+			redoAction.setEnabled(redoSize > 0);
+		}
+	};
+
+	/**
+	 * Should be called before the main constructor to setup some parameter stuff
+	 * @param args The parsed argument list.
+	 */
+	public static void preConstructorInit(Map<String, Collection<String>> args) {
 		// load preferences
 		String errMsg = null;
 		try {
-			if (arguments.remove("--reset-preferences")) {
-				pref.resetToDefault();
+			if (args.containsKey("reset-preferences")) {
+				Main.pref.resetToDefault();
 			} else
-				pref.load();
-		} catch (IOException e1) {
+				Main.pref.load();
+		} catch (final IOException e1) {
 			e1.printStackTrace();
-			errMsg = "Preferences could not be loaded. Write default preference file to '"+Preferences.getPreferencesDir()+"preferences'.";
-			pref.resetToDefault();
+			errMsg = "Preferences could not be loaded. Write default preference file to '"+pref.getPreferencesDir()+"preferences'.";
+			Main.pref.resetToDefault();
 		}
 		if (errMsg != null)
@@ -267,130 +251,88 @@
 
 		try {
-			proj = (Projection)Class.forName(pref.get("projection")).newInstance();
-		} catch (Exception e) {
+			Main.proj = (Projection)Class.forName(Main.pref.get("projection")).newInstance();
+		} catch (final Exception e) {
 			e.printStackTrace();
 			JOptionPane.showMessageDialog(null, "The projection could not be read from preferences. Using EPSG:4263.");
-			proj = new Epsg4326();
+			Main.proj = new Epsg4326();
 		}
 
 		try {
-			UIManager.setLookAndFeel(pref.get("laf"));
-		} catch (Exception e) {
+			UIManager.setLookAndFeel(Main.pref.get("laf"));
+			contentPane.updateUI();
+			panel.updateUI();
+		} catch (final Exception e) {
 			e.printStackTrace();
 		}
-
-		new Main();
-		main.setVisible(true);
-
-		if (!arguments.remove("--no-fullscreen")) {
-			if (Toolkit.getDefaultToolkit().isFrameStateSupported(MAXIMIZED_BOTH))
-				main.setExtendedState(MAXIMIZED_BOTH); // some platform are able to maximize
-			else {
-				Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
-				main.setSize(d);
-			}
-		}
-
-		boolean showModifiers = false;
-
-		for (String s : arguments) {
-			if (s.startsWith("--download=") || s.startsWith("osm:")) {
-				downloadFromParamString(false, s);
-			} else if (s.startsWith("--downloadgps=")) {
-				downloadFromParamString(true, s);
-			} else if (s.startsWith("--geometry=")) {
-				Matcher m = Pattern.compile("(\\d+)x(\\d+)(([+-])(\\d+)([+-])(\\d+))?").matcher(s.substring(11));
-				if (m.matches()) {
-					main.setExtendedState(NORMAL);
-					Integer w = Integer.valueOf(m.group(1));
-					Integer h = Integer.valueOf(m.group(2));
-					main.setSize(w, h);
-					if (m.group(3) != null) {
-						int x = Integer.valueOf(m.group(5));
-						int y = Integer.valueOf(m.group(7));
-						if (m.group(4).equals("-"))
-							x = Toolkit.getDefaultToolkit().getScreenSize().width - x - w;
-						if (m.group(6).equals("-"))
-							y = Toolkit.getDefaultToolkit().getScreenSize().height - y - h;
-						main.setLocation(x,y);
-					}
-				} else
-					System.out.println("Ignoring malformed geometry: "+s.substring(11));
-			} else if (s.equals("--show-modifiers")) {
-				showModifiers = true;
-			} else if (s.startsWith("--selection=")) {
-				SelectionListDialog.search(s.substring(12), SelectionListDialog.SearchMode.add);
-			} else if (s.startsWith("http:")) {
-				Bounds b = DownloadAction.osmurl2bounds(s);
-				if (b == null)
-					JOptionPane.showMessageDialog(main, "Ignoring malformed url: "+s);
-				else
-					main.downloadAction.download(false, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
-			} else {
-				main.openAction.openFile(new File(s));
-			}
-		}
-
-		if (showModifiers) {
-			Point p = main.getLocationOnScreen();
-			Dimension s = main.getSize();
-			new ShowModifiers(p.x + s.width - 3, p.y + s.height - 32);
-			main.setVisible(true);
-		}
-	}
-
-
-	private static void downloadFromParamString(boolean rawGps, String s) {
-		s = s.replaceAll("^(osm:/?/?)|(--download(gps)?=)", "");
-		StringTokenizer st = new StringTokenizer(s, ",");
-		if (st.countTokens() != 4) {
-			JOptionPane.showMessageDialog(main, "Malformed bounding box: "+s);
-			return;
-		}
-
-		try {
-			main.downloadAction.download(rawGps, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
-		} catch (NumberFormatException e) {
-			JOptionPane.showMessageDialog(main, "Could not parse the Coordinates: "+s);
-		}
-	}
-
-	//TODO: should be solved better.
-	public void setMapFrame(MapFrame mapFrame) {
-		if (this.mapFrame != null)
-			this.mapFrame.setVisible(false);
-		this.mapFrame = mapFrame;
-		panel.setVisible(false);
-		panel.removeAll();
-		if (mapFrame != null) {
-			mapFrame.fillPanel(panel);
-			panel.setVisible(true);
-			mapFrame.setVisible(true);
-		}
-	}
-	/**
-	 * @return Returns the mapFrame.
-	 */
-	public MapFrame getMapFrame() {
-		return mapFrame;
-	}
-
-
-	/**
-	 * Sets some icons to the ui.
-	 */
-	private static void setupUiDefaults() {
 		UIManager.put("OptionPane.okIcon", ImageProvider.get("ok"));
 		UIManager.put("OptionPane.yesIcon", UIManager.get("OptionPane.okIcon"));
 		UIManager.put("OptionPane.cancelIcon", ImageProvider.get("cancel"));
 		UIManager.put("OptionPane.noIcon", UIManager.get("OptionPane.cancelIcon"));
-	}
-
-	/**
-	 * Setup an exception handler that displays a sorry message and the possibility
-	 * to do a bug report.
-	 */
-	private static void setupExceptionHandler() {
-		Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
+
+		Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+		if (args.containsKey("geometry")) {
+			String geometry = args.get("geometry").iterator().next();
+			final Matcher m = Pattern.compile("(\\d+)x(\\d+)(([+-])(\\d+)([+-])(\\d+))?").matcher(geometry);
+			if (m.matches()) {
+				int w = Integer.valueOf(m.group(1));
+				int h = Integer.valueOf(m.group(2));
+				int x = 0, y = 0;
+				if (m.group(3) != null) {
+					x = Integer.valueOf(m.group(5));
+					y = Integer.valueOf(m.group(7));
+					if (m.group(4).equals("-"))
+						x = screenDimension.width - x - w;
+					if (m.group(6).equals("-"))
+						y = screenDimension.height - y - h;
+				}
+				bounds = new Rectangle(x,y,w,h);
+			} else
+				System.out.println("Ignoring malformed geometry: "+geometry);
+		}
+		if (bounds == null)
+			bounds = !args.containsKey("no-fullscreen") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
+	}
+
+	public void postConstructorProcessCmdLine(Map<String, Collection<String>> args) {
+		if (args.containsKey("download"))
+			for (String s : args.get("download"))
+				downloadFromParamString(false, s);
+		if (args.containsKey("downloadgps"))
+			for (String s : args.get("downloadgps"))
+				downloadFromParamString(true, s);
+		if (args.containsKey("selection"))
+			for (String s : args.get("selection"))
+				SelectionListDialog.search(s, SelectionListDialog.SearchMode.add);
+	}
+
+	private static void downloadFromParamString(final boolean rawGps, String s) {
+		if (s.startsWith("http:")) {
+			final Bounds b = DownloadAction.osmurl2bounds(s);
+			if (b == null)
+				JOptionPane.showMessageDialog(Main.parent, "Ignoring malformed url: '"+s+"'");
+			else
+				main.downloadAction.download(false, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
+			return;
+		}
+
+		if (s.startsWith("file:")) {
+			try {
+				main.openAction.openFile(new File(new URI(s)));
+			} catch (URISyntaxException e) {
+				JOptionPane.showMessageDialog(Main.parent, "Ignoring malformed file url: '"+s+"'");
+			}
+			return;
+		}
+
+		final StringTokenizer st = new StringTokenizer(s, ",");
+		if (st.countTokens() == 4) {
+			try {
+				main.downloadAction.download(rawGps, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
+				return;
+			} catch (final NumberFormatException e) {
+			}
+		}
+
+		main.openAction.openFile(new File(s));
 	}
 }
Index: src/org/openstreetmap/josm/actions/AboutAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AboutAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/AboutAction.java	(revision 98)
@@ -67,5 +67,5 @@
 		about.setPreferredSize(new Dimension(500,300));
 		
-		JOptionPane.showMessageDialog(Main.main, about, "About JOSM...",
+		JOptionPane.showMessageDialog(Main.parent, about, "About JOSM...",
 				JOptionPane.INFORMATION_MESSAGE, ImageProvider.get("logo"));
 	}
Index: src/org/openstreetmap/josm/actions/DiskAccessAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DiskAccessAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/DiskAccessAction.java	(revision 98)
@@ -44,5 +44,5 @@
 		fc.setAcceptAllFileFilterUsed(true);
 	
-		int answer = open ? fc.showOpenDialog(Main.main) : fc.showSaveDialog(Main.main);
+		int answer = open ? fc.showOpenDialog(Main.parent) : fc.showSaveDialog(Main.parent);
 		if (answer != JFileChooser.APPROVE_OPTION)
 			return null;
@@ -54,5 +54,5 @@
 			File file = fc.getSelectedFile();
 			if (file == null || (file.exists() && JOptionPane.YES_OPTION != 
-					JOptionPane.showConfirmDialog(Main.main, "File exists. Overwrite?", "Overwrite", JOptionPane.YES_NO_OPTION)))
+					JOptionPane.showConfirmDialog(Main.parent, "File exists. Overwrite?", "Overwrite", JOptionPane.YES_NO_OPTION)))
 				return null;
 		}
Index: src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 98)
@@ -33,10 +33,8 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.BookmarkList;
-import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.WorldChooser;
 import org.openstreetmap.josm.gui.BookmarkList.Bookmark;
-import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.RawGpsDataLayer;
@@ -79,9 +77,5 @@
 			if (dataSet.nodes.isEmpty())
 				errorMessage = "No data imported.";
-			Layer layer = new OsmDataLayer(dataSet, "Data Layer", false);
-			if (Main.main.getMapFrame() == null)
-				Main.main.setMapFrame(new MapFrame(layer));
-			else
-				Main.main.getMapFrame().mapView.addLayer(layer);
+			Main.main.addLayer(new OsmDataLayer(dataSet, "Data Layer", false));
 		}
 
@@ -110,9 +104,5 @@
 				return;
 			String name = latlon[0].getText() + " " + latlon[1].getText() + " x " + latlon[2].getText() + " " + latlon[3].getText();
-			Layer layer = new RawGpsDataLayer(rawData, name);
-			if (Main.main.getMapFrame() == null)
-				Main.main.setMapFrame(new MapFrame(layer));
-			else
-				Main.main.getMapFrame().mapView.addLayer(layer);
+			Main.main.addLayer(new RawGpsDataLayer(rawData, name));
 		}
 
@@ -145,5 +135,5 @@
 		//TODO: Remove this in later versions (temporary only)
 		if (osmDataServer.endsWith("/0.2") || osmDataServer.endsWith("/0.2/")) {
-			int answer = JOptionPane.showConfirmDialog(Main.main, 
+			int answer = JOptionPane.showConfirmDialog(Main.parent, 
 					"You seem to have an outdated server entry in your preferences.\n" +
 					"\n" +
@@ -175,6 +165,6 @@
 		dlg.add(new JLabel("max lon"), GBC.std().insets(10,0,5,0));
 		dlg.add(latlon[3], GBC.eol());
-		if (Main.main.getMapFrame() != null) {
-			MapView mv = Main.main.getMapFrame().mapView;
+		if (Main.map != null) {
+			MapView mv = Main.map.mapView;
 			setEditBounds(new Bounds(
 					mv.getLatLon(0, mv.getHeight()),
@@ -260,8 +250,8 @@
 				Bookmark b = readBookmark();
 				if (b == null) {
-					JOptionPane.showMessageDialog(Main.main, "Please enter the desired coordinates first.");
+					JOptionPane.showMessageDialog(Main.parent, "Please enter the desired coordinates first.");
 					return;
 				}
-				b.name = JOptionPane.showInputDialog(Main.main, "Please enter a name for the location.");
+				b.name = JOptionPane.showInputDialog(Main.parent, "Please enter a name for the location.");
 				if (b.name != null && !b.name.equals("")) {
 					((DefaultListModel)bookmarks.getModel()).addElement(b);
@@ -276,5 +266,5 @@
 				Object sel = bookmarks.getSelectedValue();
 				if (sel == null) {
-					JOptionPane.showMessageDialog(Main.main, "Select a bookmark first.");
+					JOptionPane.showMessageDialog(Main.parent, "Select a bookmark first.");
 					return;
 				}
@@ -293,5 +283,5 @@
 		Bookmark b;
 		do {
-			int r = JOptionPane.showConfirmDialog(Main.main, dlg, "Choose an area", 
+			int r = JOptionPane.showConfirmDialog(Main.parent, dlg, "Choose an area", 
 					JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
 			if (r != JOptionPane.OK_OPTION)
@@ -299,5 +289,5 @@
 			b = readBookmark();
 			if (b == null)
-				JOptionPane.showMessageDialog(Main.main, "Please enter the desired coordinates or click on a bookmark.");
+				JOptionPane.showMessageDialog(Main.parent, "Please enter the desired coordinates or click on a bookmark.");
 		} while (b == null);
 
Index: src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 98)
@@ -46,6 +46,6 @@
 
 	public void actionPerformed(ActionEvent e) {
-		if (layer == null && Main.main.getMapFrame() == null) {
-			JOptionPane.showMessageDialog(Main.main, "Nothing to export. Get some data first.");
+		if (layer == null && Main.map == null) {
+			JOptionPane.showMessageDialog(Main.parent, "Nothing to export. Get some data first.");
 			return;
 		}
@@ -102,5 +102,5 @@
 		p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
 
-		int answer = JOptionPane.showConfirmDialog(Main.main, p, "Export options", JOptionPane.OK_CANCEL_OPTION);
+		int answer = JOptionPane.showConfirmDialog(Main.parent, p, "Export options", JOptionPane.OK_CANCEL_OPTION);
 		if (answer != JOptionPane.OK_OPTION)
 			return;
@@ -113,5 +113,5 @@
 		
 		try {
-			Layer layer = this.layer == null ? Main.main.getMapFrame().mapView.editLayer() : this.layer;
+			Layer layer = this.layer == null ? Main.main.editLayer() : this.layer;
 			FileWriter out = new FileWriter(file);
 			GpxWriter w = new GpxWriter(out, layer.name, desc.getText(),
@@ -125,5 +125,5 @@
 		} catch (IOException x) {
 			x.printStackTrace();
-			JOptionPane.showMessageDialog(Main.main, "Error while exporting "+fn+":\n"+x.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
+			JOptionPane.showMessageDialog(Main.parent, "Error while exporting "+fn+":\n"+x.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
 		}		
 	}
@@ -179,5 +179,5 @@
 				l.setVisibleRowCount(4);
 				l.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-				int answer = JOptionPane.showConfirmDialog(Main.main, new JScrollPane(l), "Choose a predefined license", JOptionPane.OK_CANCEL_OPTION);
+				int answer = JOptionPane.showConfirmDialog(Main.parent, new JScrollPane(l), "Choose a predefined license", JOptionPane.OK_CANCEL_OPTION);
 				if (answer != JOptionPane.OK_OPTION || l.getSelectedIndex() == -1)
 					return;
Index: src/org/openstreetmap/josm/actions/GroupAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/GroupAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/GroupAction.java	(revision 98)
@@ -10,8 +10,10 @@
 import javax.swing.Action;
 import javax.swing.Icon;
+import javax.swing.JComponent;
 import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
 import javax.swing.KeyStroke;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.IconToggleButton;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -49,5 +51,7 @@
 
 	public GroupAction(int shortCut, int modifiers) {
-		registerShortCut(getClass().getName(), KeyStroke.getKeyStroke(shortCut, modifiers));
+		String idName = getClass().getName();
+		Main.panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(shortCut, modifiers), idName);
+        Main.panel.getActionMap().put(idName, this);
 		shortCutName = ShortCutLabel.name(shortCut, modifiers);
 		addPropertyChangeListener(new PropertyChangeListener(){
Index: src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/JosmAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/JosmAction.java	(revision 98)
@@ -33,13 +33,9 @@
 		super(name, ImageProvider.get(iconName));
 		putValue(SHORT_DESCRIPTION, "<html>"+tooltip+" <font size='-2'>"+shortCutName+"</font>&nbsp;</html>");
-		registerShortCut(name, shortCut);
+		Main.panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortCut, name);
+        Main.panel.getActionMap().put(name, this);
 	}
 
 	public JosmAction() {
 	}
-
-	public void registerShortCut(String idName, KeyStroke shortCut) {
-		Main.main.panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortCut, idName);
-		Main.main.panel.getActionMap().put(idName, this);
-	}
 }
Index: src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/OpenAction.java	(revision 98)
@@ -17,6 +17,4 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.RawGpsDataLayer;
@@ -59,6 +57,4 @@
 		String fn = filename.getName();
 		try {
-			Layer layer;
-
 			if (asRawData(fn)) {
 				Collection<Collection<GpsPoint>> data;
@@ -70,9 +66,9 @@
 				} else
 					throw new IllegalStateException();
-				layer = new RawGpsDataLayer(data, filename.getName());
+				Main.main.addLayer(new RawGpsDataLayer(data, filename.getName()));
 			} else {
 				DataSet dataSet;
 				if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-					JOptionPane.showMessageDialog(Main.main, "Warning: Soon, it will be no longer possible to open GPX files as osm data. Please convert your files to .osm format.");
+					JOptionPane.showMessageDialog(Main.parent, "Warning: Soon, it will be no longer possible to open GPX files as osm data. Please convert your files to .osm format.");
 					dataSet = new GpxReader(new FileReader(filename)).parse();
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn)) {
@@ -82,5 +78,5 @@
 					} catch (SAXException x) {
 						if (x.getMessage().equals("Unknown version null")) {
-							int answer = JOptionPane.showConfirmDialog(Main.main, 
+							int answer = JOptionPane.showConfirmDialog(Main.parent, 
 									fn+" seems to be an old 0.2 API XML file.\n" +
 									"JOSM can try to open it with the old parser. This option\n" +
@@ -96,27 +92,21 @@
 					}					
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
-					JOptionPane.showMessageDialog(Main.main, fn+": CSV Data import for non-GPS data is not implemented yet.");
+					JOptionPane.showMessageDialog(Main.parent, fn+": CSV Data import for non-GPS data is not implemented yet.");
 					return;
 				} else {
-					JOptionPane.showMessageDialog(Main.main, fn+": Unknown file extension: "+fn.substring(filename.getName().lastIndexOf('.')+1));
+					JOptionPane.showMessageDialog(Main.parent, fn+": Unknown file extension: "+fn.substring(filename.getName().lastIndexOf('.')+1));
 					return;
 				}
-				layer = new OsmDataLayer(dataSet, "Data Layer", true);
+				Main.main.addLayer(new OsmDataLayer(dataSet, "Data Layer", true));
 			}
-			
-			if (Main.main.getMapFrame() == null)
-				Main.main.setMapFrame(new MapFrame(layer));
-			else
-				Main.main.getMapFrame().mapView.addLayer(layer);
-
 		} catch (SAXException x) {
 			x.printStackTrace();
-			JOptionPane.showMessageDialog(Main.main, "Error while parsing: "+x.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "Error while parsing: "+x.getMessage());
 		} catch (JDOMException x) {
 			x.printStackTrace();
-			JOptionPane.showMessageDialog(Main.main, "Error while parsing: "+x.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "Error while parsing: "+x.getMessage());
 		} catch (IOException x) {
 			x.printStackTrace();
-			JOptionPane.showMessageDialog(Main.main, "Could not read '"+fn+"'\n"+x.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "Could not read '"+fn+"'\n"+x.getMessage());
 		}
 	}
@@ -132,5 +122,5 @@
 			return false;
 		return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(
-				Main.main, "Do you want to open "+fn+" as raw gps data?",
+				Main.parent, "Do you want to open "+fn+" as raw gps data?",
 				"Open as raw data?", JOptionPane.YES_NO_OPTION);
 	}
Index: src/org/openstreetmap/josm/actions/RedoAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/RedoAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/RedoAction.java	(revision 98)
@@ -26,8 +26,8 @@
 
 	public void actionPerformed(ActionEvent e) {
-		if (Main.main.getMapFrame() == null)
+		if (Main.map == null)
 			return;
-		Main.main.getMapFrame().repaint();
-		Main.main.getMapFrame().mapView.editLayer().redo();
+		Main.map.repaint();
+		Main.main.editLayer().redo();
 	}
 }
Index: src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/SaveAction.java	(revision 98)
@@ -35,12 +35,12 @@
 	
 	public void actionPerformed(ActionEvent event) {
-		if (Main.main.getMapFrame() == null) {
-			JOptionPane.showMessageDialog(Main.main, "No document open so nothing to save.");
+		if (Main.map == null) {
+			JOptionPane.showMessageDialog(Main.parent, "No document open so nothing to save.");
 			return;
 		}
-		if (isDataSetEmpty() && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.main, "The document contains no data. Save anyway?", "Empty document", JOptionPane.YES_NO_OPTION))
+		if (isDataSetEmpty() && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.parent, "The document contains no data. Save anyway?", "Empty document", JOptionPane.YES_NO_OPTION))
 			return;
-		if (!Main.main.getMapFrame().conflictDialog.conflicts.isEmpty()) {
-			int answer = JOptionPane.showConfirmDialog(Main.main, 
+		if (!Main.map.conflictDialog.conflicts.isEmpty()) {
+			int answer = JOptionPane.showConfirmDialog(Main.parent, 
 					"There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?", "Conflicts", JOptionPane.YES_NO_OPTION);
 			if (answer != JOptionPane.YES_OPTION)
@@ -68,5 +68,5 @@
 				for (Segment ls : Main.ds.segments) {
 					if (ls.incomplete) {
-						JOptionPane.showMessageDialog(Main.main, "Export of data containing incomplete ways to GPX is not implemented.\nBe aware, that in future versions of JOSM, GPX support will be kept at a minimum.\nPlease use .osm or .xml as extension for the better OSM support.");
+						JOptionPane.showMessageDialog(Main.parent, "Export of data containing incomplete ways to GPX is not implemented.\nBe aware, that in future versions of JOSM, GPX support will be kept at a minimum.\nPlease use .osm or .xml as extension for the better OSM support.");
 						return;
 					}
@@ -76,15 +76,15 @@
 				OsmWriter.output(fileWriter = new FileWriter(file), Main.ds, false);
 			else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
-				JOptionPane.showMessageDialog(Main.main, "CSV output not supported yet.");
+				JOptionPane.showMessageDialog(Main.parent, "CSV output not supported yet.");
 				return;
 			} else {
-				JOptionPane.showMessageDialog(Main.main, "Unknown file extension.");
+				JOptionPane.showMessageDialog(Main.parent, "Unknown file extension.");
 				return;
 			}
 			fileWriter.close();
-			Main.main.getMapFrame().mapView.editLayer().cleanData(null, false);
+			Main.main.editLayer().cleanData(null, false);
 		} catch (IOException e) {
 			e.printStackTrace();
-			JOptionPane.showMessageDialog(Main.main, "An error occoured while saving.\n"+e.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "An error occoured while saving.\n"+e.getMessage());
 		}
 	}
Index: src/org/openstreetmap/josm/actions/UndoAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/UndoAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/UndoAction.java	(revision 98)
@@ -26,8 +26,8 @@
 
 	public void actionPerformed(ActionEvent e) {
-		if (Main.main.getMapFrame() == null)
+		if (Main.map == null)
 			return;
-		Main.main.getMapFrame().repaint();
-		Main.main.getMapFrame().mapView.editLayer().undo();
+		Main.map.repaint();
+		Main.main.editLayer().undo();
 	}
 }
Index: src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/UploadAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/UploadAction.java	(revision 98)
@@ -43,5 +43,5 @@
 		//TODO: Remove this in later versions (temporary only)
 		if (osmDataServer.endsWith("/0.2") || osmDataServer.endsWith("/0.2/")) {
-			int answer = JOptionPane.showConfirmDialog(Main.main, 
+			int answer = JOptionPane.showConfirmDialog(Main.parent, 
 					"You seem to have an outdated server entry in your preferences.\n" +
 					"\n" +
@@ -56,8 +56,8 @@
 		}
 
-		if (!Main.main.getMapFrame().conflictDialog.conflicts.isEmpty()) {
-			JOptionPane.showMessageDialog(Main.main, "There are unresolved conflicts. You have to resolve these first.");
-			Main.main.getMapFrame().conflictDialog.action.button.setSelected(true);
-			Main.main.getMapFrame().conflictDialog.action.actionPerformed(null);
+		if (!Main.map.conflictDialog.conflicts.isEmpty()) {
+			JOptionPane.showMessageDialog(Main.parent, "There are unresolved conflicts. You have to resolve these first.");
+			Main.map.conflictDialog.action.button.setSelected(true);
+			Main.map.conflictDialog.action.actionPerformed(null);
 			return;
 		}
@@ -90,5 +90,5 @@
 			}
 			@Override protected void finish() {
-				Main.main.getMapFrame().mapView.editLayer().cleanData(server.processed, !add.isEmpty());
+				Main.main.editLayer().cleanData(server.processed, !add.isEmpty());
 			}
 			@Override protected void cancel() {
@@ -108,5 +108,5 @@
 	private boolean displayUploadScreen(Collection<OsmPrimitive> add, Collection<OsmPrimitive> update, Collection<OsmPrimitive> delete) {
 		if (add.isEmpty() && update.isEmpty() && delete.isEmpty()) {
-			JOptionPane.showMessageDialog(Main.main, "No changes to upload.");
+			JOptionPane.showMessageDialog(Main.parent, "No changes to upload.");
 			return false;
 		}
@@ -140,5 +140,5 @@
 		}
 
-		return JOptionPane.showConfirmDialog(Main.main, p, "Upload this changes?", 
+		return JOptionPane.showConfirmDialog(Main.parent, p, "Upload this changes?", 
 				JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
 	}
Index: src/org/openstreetmap/josm/actions/WmsServerAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/WmsServerAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/WmsServerAction.java	(revision 98)
@@ -4,13 +4,7 @@
 import java.awt.event.KeyEvent;
 
-import javax.swing.AbstractButton;
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.WmsServerLayer;
 
 public class WmsServerAction extends JosmAction {
@@ -21,28 +15,5 @@
 
     public void actionPerformed(ActionEvent e) {
-    	JOptionPane.showMessageDialog(Main.main, "Not implemented yet.");
-    	if (1==1) return;
-        MapFrame mapFrame = Main.main.getMapFrame();
-        if (!((AbstractButton)e.getSource()).isSelected()) {
-            if (mapFrame != null) {
-                MapView mv = mapFrame.mapView;
-                for (Layer l : mv.getAllLayers()) {
-                    if (l instanceof WmsServerLayer) {
-                        if (mv.getAllLayers().size() == 1) {
-                            Main.main.setMapFrame(null);
-                            Main.ds = new DataSet();
-                        } else
-                            mv.removeLayer(l);
-                        return;
-                    }
-                }
-            }
-        } else {
-            WmsServerLayer layer = new WmsServerLayer(Main.pref.get("wms.baseurl", "http://wms.jpl.nasa.gov/wms.cgi?request=GetMap&width=512&height=512&layers=global_mosaic&styles=&srs=EPSG:4326&format=image/jpeg&"));
-            if (mapFrame == null)
-                Main.main.setMapFrame(new MapFrame(layer));
-            else
-                mapFrame.mapView.addLayer(layer);
-        }
+    	JOptionPane.showMessageDialog(Main.parent, "Not implemented yet.");
     }
 }
Index: src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 98)
@@ -5,4 +5,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedList;
 
@@ -51,10 +52,10 @@
 	@Override public void enterMode() {
 		super.enterMode();
-		mv.addMouseListener(this);
+		Main.map.mapView.addMouseListener(this);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		mv.removeMouseListener(this);
+		Main.map.mapView.removeMouseListener(this);
 	}
 
@@ -71,7 +72,7 @@
 			return;
 
-		Node n = new Node(mv.getLatLon(e.getX(), e.getY()));
+		Node n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
 		if (n.coor.isOutSideWorld()) {
-			JOptionPane.showMessageDialog(Main.main, "Can not add a node outside of the world.");
+			JOptionPane.showMessageDialog(Main.parent, "Can not add a node outside of the world.");
 			return;
 		}
@@ -79,5 +80,5 @@
 		Command c = new AddCommand(n);
 		if (mode == Mode.nodesegment) {
-			Segment s = mv.getNearestSegment(e.getPoint());
+			Segment s = Main.map.mapView.getNearestSegment(e.getPoint());
 			if (s == null)
 				return;
@@ -89,4 +90,6 @@
 			Segment s2 = new Segment(s.from, s.to);
 			s2.from = n;
+			if (s.keys != null)
+				s2.keys = new HashMap<String, String>(s.keys);
 
 			cmds.add(new ChangeCommand(s, s1));
@@ -110,6 +113,6 @@
 			c = new SequenceCommand(cmds);
 		}
-		mv.editLayer().add(c);
-		mv.repaint();
+		Main.main.editLayer().add(c);
+		Main.map.mapView.repaint();
 	}
 }
Index: src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 98)
@@ -51,12 +51,12 @@
 	@Override public void enterMode() {
 		super.enterMode();
-		mv.addMouseListener(this);
-		mv.addMouseMotionListener(this);
+		Main.map.mapView.addMouseListener(this);
+		Main.map.mapView.addMouseMotionListener(this);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		mv.removeMouseListener(this);
-		mv.removeMouseMotionListener(this);
+		Main.map.mapView.removeMouseListener(this);
+		Main.map.mapView.removeMouseMotionListener(this);
 		drawHint(false);
 	}
@@ -75,5 +75,5 @@
 			return;
 
-		OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
+		OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), true);
 		if (clicked == null || !(clicked instanceof Node))
 			return;
@@ -91,5 +91,5 @@
 			return;
 
-		OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 		if (clicked == null || clicked == second || !(clicked instanceof Node))
 			return;
@@ -136,8 +136,8 @@
 
 			Segment ls = new Segment(start, end);
-			mv.editLayer().add(new AddCommand(ls));
+			Main.main.editLayer().add(new AddCommand(ls));
 		}
 
-		mv.repaint();
+		Main.map.mapView.repaint();
 	}
 
@@ -153,9 +153,9 @@
 			return;
 
-		Graphics g = mv.getGraphics();
+		Graphics g = Main.map.mapView.getGraphics();
 		g.setColor(Color.BLACK);
 		g.setXORMode(Color.WHITE);
-		Point firstDrawn = mv.getPoint(first.eastNorth);
-		Point secondDrawn = mv.getPoint(second.eastNorth);
+		Point firstDrawn = Main.map.mapView.getPoint(first.eastNorth);
+		Point secondDrawn = Main.map.mapView.getPoint(second.eastNorth);
 		g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
 		hintDrawn = !hintDrawn;
Index: src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 98)
@@ -69,8 +69,8 @@
 			c = new AddCommand(way);
 			Main.ds.setSelected(way);
-			mv.editLayer().add(c);
+			Main.main.editLayer().add(c);
 		} else
 			Main.ds.clearSelection();
-		mv.addMouseListener(this);
+		Main.map.mapView.addMouseListener(this);
 	}
 
@@ -78,5 +78,5 @@
 		super.exitMode();
 		way = null;
-		mv.removeMouseListener(this);
+		Main.map.mapView.removeMouseListener(this);
 	}
 
@@ -85,5 +85,5 @@
 			return;
 
-		Segment s = mv.getNearestSegment(e.getPoint());
+		Segment s = Main.map.mapView.getNearestSegment(e.getPoint());
 		if (s == null)
 			return;
@@ -91,5 +91,5 @@
 		// special case for initial selecting one way
 		if (way == null && (e.getModifiers() & MouseEvent.ALT_DOWN_MASK) == 0) {
-			Way w = mv.getNearestWay(e.getPoint());
+			Way w = Main.map.mapView.getNearestWay(e.getPoint());
 			if (w != null) {
 				way = w;
@@ -104,13 +104,13 @@
 			copy.segments.remove(s);
 			if (copy.segments.isEmpty()) {
-				mv.editLayer().add(new DeleteCommand(Arrays.asList(new OsmPrimitive[]{way})));
+				Main.main.editLayer().add(new DeleteCommand(Arrays.asList(new OsmPrimitive[]{way})));
 				way = null;
 			} else
-				mv.editLayer().add(new ChangeCommand(way, copy));
+				Main.main.editLayer().add(new ChangeCommand(way, copy));
 		} else {
 			if (way == null) {
 				way = new Way();
 				way.segments.add(s);
-				mv.editLayer().add(new AddCommand(way));
+				Main.main.editLayer().add(new AddCommand(way));
 			} else {
 				Way copy = new Way(way);
@@ -120,5 +120,5 @@
 						break;
 				copy.segments.add(i, s);
-				mv.editLayer().add(new ChangeCommand(way, copy));
+				Main.main.editLayer().add(new ChangeCommand(way, copy));
 			}
 		}
@@ -149,5 +149,5 @@
 		if (numberOfSelectedWays > 0) {
 			String ways = "way" + (numberOfSelectedWays==1?" has":"s have");
-			int answer = JOptionPane.showConfirmDialog(Main.main, numberOfSelectedWays+" "+ways+" been selected.\n" +
+			int answer = JOptionPane.showConfirmDialog(Main.parent, numberOfSelectedWays+" "+ways+" been selected.\n" +
 					"Do you wish to select all segments belonging to the "+ways+" instead?", "Add segments from ways", JOptionPane.YES_NO_OPTION);
 			if (answer == JOptionPane.YES_OPTION) {
@@ -193,5 +193,5 @@
 		}
 
-		if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(Main.main, "Create a new way out of "+sortedSegments.size()+" segments?", "Create new way", JOptionPane.YES_NO_OPTION))
+		if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(Main.parent, "Create a new way out of "+sortedSegments.size()+" segments?", "Create new way", JOptionPane.YES_NO_OPTION))
 			return null;
 
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 98)
@@ -46,10 +46,10 @@
 	@Override public void enterMode() {
 		super.enterMode();
-		mv.addMouseListener(this);
+		Main.map.mapView.addMouseListener(this);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		mv.removeMouseListener(this);
+		Main.map.mapView.removeMouseListener(this);
 	}
 
@@ -62,5 +62,5 @@
 		else
 			delete(Main.ds.getSelected(), false);
-		mv.repaint();
+		Main.map.repaint();
 	}
 
@@ -73,5 +73,5 @@
 			return;
 		
-		OsmPrimitive sel = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive sel = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 		if (sel == null)
 			return;
@@ -82,5 +82,5 @@
 			delete(Collections.singleton(sel), true);
 
-		mv.repaint();
+		Main.map.mapView.repaint();
 	}
 
@@ -107,5 +107,5 @@
 		v.data.addAll(selection);
 		if (!v.data.isEmpty())
-			mv.editLayer().add(new DeleteCommand(v.data));
+			Main.main.editLayer().add(new DeleteCommand(v.data));
 	}
 
@@ -125,5 +125,5 @@
 			if (!selection.containsAll(v.data)) {
 				if (msgBox) {
-					JOptionPane.showMessageDialog(Main.main, "This object is in use.");
+					JOptionPane.showMessageDialog(Main.parent, "This object is in use.");
 					return;
 				}
@@ -134,5 +134,5 @@
 		}
 		if (!del.isEmpty())
-			mv.editLayer().add(new DeleteCommand(del));
+			Main.main.editLayer().add(new DeleteCommand(del));
 	}
 }
Index: src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 98)
@@ -8,7 +8,7 @@
 import javax.swing.KeyStroke;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -24,19 +24,8 @@
 
 	/**
-	 * The parent mapframe this mode belongs to.
-	 */
-	protected final MapFrame mapFrame;
-	/**
-	 * Shortcut to the MapView.
-	 */
-	protected final MapView mv;
-
-	/**
 	 * Constructor for mapmodes without an menu
 	 */
 	public MapMode(String name, String iconName, String tooltip, String keyname, int keystroke, MapFrame mapFrame) {
 		super(name, "mapmode/"+iconName, tooltip, keyname, KeyStroke.getKeyStroke(keystroke, 0));
-		this.mapFrame = mapFrame;
-		mv = mapFrame.mapView;
 		putValue("active", false);
 	}
@@ -49,6 +38,4 @@
 		putValue(SMALL_ICON, ImageProvider.get("mapmode", iconName));
 		putValue(SHORT_DESCRIPTION, tooltip);
-		this.mapFrame = mapFrame;
-		mv = mapFrame.mapView;
 	}
 
@@ -64,5 +51,5 @@
 	 */
 	public void actionPerformed(ActionEvent e) {
-		mapFrame.selectMapMode(this);
+		Main.map.selectMapMode(this);
 	}
 
Index: src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 98)
@@ -53,12 +53,12 @@
 	@Override public void enterMode() {
 		super.enterMode();
-		mv.addMouseListener(this);
-		mv.addMouseMotionListener(this);
+		Main.map.mapView.addMouseListener(this);
+		Main.map.mapView.addMouseMotionListener(this);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		mv.removeMouseListener(this);
-		mv.removeMouseMotionListener(this);
+		Main.map.mapView.removeMouseListener(this);
+		Main.map.mapView.removeMouseMotionListener(this);
 	}
 
@@ -77,6 +77,6 @@
 		}
 
-		EastNorth mouseGeo = mv.getEastNorth(e.getX(), e.getY());
-		EastNorth mouseStartGeo = mv.getEastNorth(mousePos.x, mousePos.y);
+		EastNorth mouseGeo = Main.map.mapView.getEastNorth(e.getX(), e.getY());
+		EastNorth mouseStartGeo = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
 		double dx = mouseGeo.east() - mouseStartGeo.east();
 		double dy = mouseGeo.north() - mouseStartGeo.north();
@@ -90,16 +90,16 @@
 		for (OsmPrimitive osm : affectedNodes) {
 			if (osm instanceof Node && ((Node)osm).coor.isOutSideWorld()) {
-				JOptionPane.showMessageDialog(Main.main, "Cannot move objects outside of the world.");
+				JOptionPane.showMessageDialog(Main.parent, "Cannot move objects outside of the world.");
 				return;
 			}
 		}
 		
-		Command c = !mv.editLayer().commands.isEmpty() ? mv.editLayer().commands.getLast() : null;
+		Command c = !Main.main.editLayer().commands.isEmpty() ? Main.main.editLayer().commands.getLast() : null;
 		if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).objects))
 			((MoveCommand)c).moveAgain(dx,dy);
 		else
-			mv.editLayer().add(new MoveCommand(selection, dx, dy));
+			Main.main.editLayer().add(new MoveCommand(selection, dx, dy));
 		
-		mv.repaint();
+		Main.map.mapView.repaint();
 		mousePos = e.getPoint();
 	}
@@ -119,15 +119,15 @@
 
 		if (Main.ds.getSelected().size() == 0) {
-			OsmPrimitive osm = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+			OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 			if (osm != null)
 				Main.ds.setSelected(osm);
 			singleOsmPrimitive = osm;
-			mv.repaint();
+			Main.map.mapView.repaint();
 		} else
 			singleOsmPrimitive = null;
 		
 		mousePos = e.getPoint();
-		oldCursor = mv.getCursor();
-		mv.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+		oldCursor = Main.map.mapView.getCursor();
+		Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
 	}
 	
@@ -136,8 +136,8 @@
 	 */
 	@Override public void mouseReleased(MouseEvent e) {
-		mv.setCursor(oldCursor);
+		Main.map.mapView.setCursor(oldCursor);
 		if (singleOsmPrimitive != null) {
 			Main.ds.clearSelection();
-			mv.repaint();
+			Main.map.mapView.repaint();
 		}
 	}
Index: src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 97)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 98)
@@ -65,15 +65,15 @@
 	public SelectionAction(MapFrame mapFrame) {
 		super("Selection", "selection", "Select objects by dragging or clicking.", "S", KeyEvent.VK_S, mapFrame);
-		this.selectionManager = new SelectionManager(this, false, mv);
+		this.selectionManager = new SelectionManager(this, false, mapFrame.mapView);
 	}
 
 	@Override public void enterMode() {
 		super.enterMode();
-		selectionManager.register(mv);
+		selectionManager.register(Main.map.mapView);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		selectionManager.unregister(mv);
+		selectionManager.unregister(Main.map.mapView);
 	}
 
@@ -99,5 +99,5 @@
 				curSel.add(osm);
 		Main.ds.setSelected(curSel);
-		mv.repaint();
+		Main.map.mapView.repaint();
 	}
 }
Index: src/org/openstreetmap/josm/command/Command.java
===================================================================
--- src/org/openstreetmap/josm/command/Command.java	(revision 97)
+++ src/org/openstreetmap/josm/command/Command.java	(revision 98)
@@ -16,5 +16,5 @@
  *
  * Remember, that the command must be executable and undoable, even if the 
- * Main.main.ds has changed, so the command must save the dataset it operates on
+ * Main.ds has changed, so the command must save the dataset it operates on
  * if necessary.
  *
Index: src/org/openstreetmap/josm/command/ConflictResolveCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 97)
+++ src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 98)
@@ -30,5 +30,5 @@
 		this.conflicts = conflicts;
 		this.resolved = resolved;
-		conflictDialog = Main.main.getMapFrame().conflictDialog;
+		conflictDialog = Main.map.conflictDialog;
 	}
 
@@ -53,5 +53,5 @@
 				conflictDialog.conflicts.remove(k);
 			conflictDialog.rebuildList();
-			Main.main.getMapFrame().mapView.recalculateCenterScale(); // in case of auto-zoom
+			Main.map.mapView.recalculateCenterScale(); // in case of auto-zoom
  		}
 	}
@@ -59,7 +59,7 @@
 	@Override public void undoCommand() {
 		super.undoCommand();
-		Main.main.getMapFrame().conflictDialog.conflicts.clear();
-		Main.main.getMapFrame().conflictDialog.conflicts.putAll(origAllConflicts);
-		Main.main.getMapFrame().conflictDialog.rebuildList();
+		Main.map.conflictDialog.conflicts.clear();
+		Main.map.conflictDialog.conflicts.putAll(origAllConflicts);
+		Main.map.conflictDialog.rebuildList();
 	}
 
Index: src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- src/org/openstreetmap/josm/data/Preferences.java	(revision 97)
+++ src/org/openstreetmap/josm/data/Preferences.java	(revision 98)
@@ -31,54 +31,45 @@
 	}
 	
-	ArrayList<PreferenceChangedListener> listener = new ArrayList<PreferenceChangedListener>();
+	public final ArrayList<PreferenceChangedListener> listener = new ArrayList<PreferenceChangedListener>();
 	
 	/**
 	 * Map the property name to the property object.
 	 */
-	private SortedMap<String, String> properties = new TreeMap<String, String>();
+	private final SortedMap<String, String> properties = new TreeMap<String, String>();
 	
 	/**
 	 * Return the location of the preferences file
 	 */
-	public static String getPreferencesDir() {
+	public String getPreferencesDir() {
 		return System.getProperty("user.home")+"/.josm/";
 	}
 
-
-	public void addPreferenceChangedListener(PreferenceChangedListener listener) {
-		this.listener.add(listener);
-	}
-	public void removePreferenceChangedListener(PreferenceChangedListener listener) {
-		this.listener.remove(listener);
-	}
-
-
-	synchronized public String get(String key) {
+	synchronized final public String get(final String key) {
 		if (!properties.containsKey(key))
 			return "";
 		return properties.get(key);
 	}
-	synchronized public String get(String key, String def) {
-		String prop = properties.get(key);
+	synchronized final public String get(final String key, final String def) {
+		final String prop = properties.get(key);
 		if (prop == null || prop.equals(""))
 			return def;
 		return prop;
 	}
-	synchronized public Map<String, String> getAllPrefix(String prefix) {
-		Map<String,String> all = new TreeMap<String,String>();
-		for (Entry<String,String> e : properties.entrySet())
+	synchronized final public Map<String, String> getAllPrefix(final String prefix) {
+		final Map<String,String> all = new TreeMap<String,String>();
+		for (final Entry<String,String> e : properties.entrySet())
 			if (e.getKey().startsWith(prefix))
 				all.put(e.getKey(), e.getValue());
 		return all;
 	}
-	synchronized public boolean getBoolean(String key) {
+	synchronized final public boolean getBoolean(final String key) {
 		return getBoolean(key, false);
 	}
-	synchronized public boolean getBoolean(String key, boolean def) {
+	synchronized final public boolean getBoolean(final String key, final boolean def) {
 		return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : def;
 	}
 
 
-	synchronized public void put(String key, String value) {
+	synchronized final public void put(final String key, final String value) {
 		if (value == null)
 			properties.remove(key);
@@ -88,5 +79,5 @@
 		firePreferenceChanged(key, value);
 	}
-	synchronized public void put(String key, boolean value) {
+	synchronized final public void put(final String key, final boolean value) {
 		properties.put(key, Boolean.toString(value));
 		save();
@@ -94,6 +85,6 @@
 	}
 
-	private void firePreferenceChanged(String key, String value) {
-		for (PreferenceChangedListener l : listener)
+	private final void firePreferenceChanged(final String key, final String value) {
+		for (final PreferenceChangedListener l : listener)
 			l.preferenceChanged(key, value);
 	}
@@ -104,13 +95,13 @@
 	 * in log.
 	 */
-	private void save() {
+	protected void save() {
 		try {
-			PrintWriter out = new PrintWriter(new FileWriter(
+			final PrintWriter out = new PrintWriter(new FileWriter(
 					getPreferencesDir() + "preferences"));
-			for (Entry<String, String> e : properties.entrySet())
+			for (final Entry<String, String> e : properties.entrySet())
 				if (!e.getValue().equals(""))
 					out.println(e.getKey() + "=" + e.getValue());
 			out.close();
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			e.printStackTrace();
 			// do not message anything, since this can be called from strange
@@ -122,8 +113,8 @@
 	public void load() throws IOException {
 		properties.clear();
-		BufferedReader in = new BufferedReader(new FileReader(getPreferencesDir()+"preferences"));
+		final BufferedReader in = new BufferedReader(new FileReader(getPreferencesDir()+"preferences"));
 		int lineNumber = 0;
 		for (String line = in.readLine(); line != null; line = in.readLine(), lineNumber++) {
-			int i = line.indexOf('=');
+			final int i = line.indexOf('=');
 			if (i == -1 || i == 0)
 				throw new IOException("Malformed config file at line "+lineNumber);
@@ -132,5 +123,5 @@
 	}
 
-	public void resetToDefault() {
+	public final void resetToDefault() {
 		properties.clear();
 		properties.put("laf", "javax.swing.plaf.metal.MetalLookAndFeel");
Index: src/org/openstreetmap/josm/data/ServerSidePreferences.java
===================================================================
--- src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 98)
+++ src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 98)
@@ -0,0 +1,32 @@
+package org.openstreetmap.josm.data;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * This class tweak the Preferences class to provide server side preference settings, as example
+ * used in the applet version.
+ * 
+ * @author Imi
+ */
+public class ServerSidePreferences extends Preferences {
+
+	private final URL serverUrl;
+	private final String userName;
+
+	public ServerSidePreferences(URL serverUrl, String userName) {
+		this.serverUrl = serverUrl;
+		this.userName = userName;
+    }
+	
+	@Override public String getPreferencesDir() {
+	    return serverUrl+"/user/"+userName+"/preferences";
+    }
+
+	@Override public void load() throws IOException {
+		resetToDefault();
+    }
+
+	@Override protected void save() {
+    }
+}
Index: src/org/openstreetmap/josm/gui/BookmarkList.java
===================================================================
--- src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 98)
@@ -17,5 +17,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -38,5 +37,5 @@
 		}
 	}
-	
+
 	/**
 	 * Create a bookmark list as well as the Buttons add and remove.
@@ -64,10 +63,10 @@
 		DefaultListModel model = (DefaultListModel)getModel();
 		model.removeAllElements();
-		File bookmarkFile = new File(Preferences.getPreferencesDir()+"bookmarks");
+		File bookmarkFile = new File(Main.pref.getPreferencesDir()+"bookmarks");
 		try {
 			if (!bookmarkFile.exists())
 				bookmarkFile.createNewFile();
 			BufferedReader in = new BufferedReader(new FileReader(bookmarkFile));
-			
+
 			for (String line = in.readLine(); line != null; line = in.readLine()) {
 				StringTokenizer st = new StringTokenizer(line, ",");
@@ -87,5 +86,5 @@
 			in.close();
 		} catch (IOException e) {
-			JOptionPane.showMessageDialog(Main.main, "Could not read bookmarks.\n"+e.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "Could not read bookmarks.\n"+e.getMessage());
 		}
 	}
@@ -95,5 +94,5 @@
 	 */
 	public void save() {
-		File bookmarkFile = new File(Preferences.getPreferencesDir()+"bookmarks");
+		File bookmarkFile = new File(Main.pref.getPreferencesDir()+"bookmarks");
 		try {
 			if (!bookmarkFile.exists())
@@ -111,5 +110,5 @@
 			out.close();
 		} catch (IOException e) {
-			JOptionPane.showMessageDialog(Main.main, "Could not write bookmark.\n"+e.getMessage());
+			JOptionPane.showMessageDialog(Main.parent, "Could not write bookmark.\n"+e.getMessage());
 		}
 	}
Index: src/org/openstreetmap/josm/gui/MainApplet.java
===================================================================
--- src/org/openstreetmap/josm/gui/MainApplet.java	(revision 98)
+++ src/org/openstreetmap/josm/gui/MainApplet.java	(revision 98)
@@ -0,0 +1,91 @@
+package org.openstreetmap.josm.gui;
+
+import java.awt.GridBagLayout;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.swing.JApplet;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.ServerSidePreferences;
+import org.openstreetmap.josm.tools.GBC;
+
+public class MainApplet extends JApplet {
+
+	private final class MainCaller extends Main {
+		private MainCaller() {
+			setContentPane(contentPane);
+			setJMenuBar(mainMenu);
+			setBounds(bounds);
+		}
+	}
+
+	private final static String[][] paramInfo = {
+		{"username", "string", "Name of the user."},
+		{"password", "string", "OSM Password."},
+		{"geometry", "string", "Size the applet to the given geometry (format: WIDTHxHEIGHT)"},
+		{"download", "string;string;...", "Download each. Can be x1,y1,x2,y2 an url containing lat=y&lon=x&zoom=z or a filename"},
+		{"downloadgps", "string;string;...", "Download each as raw gps. Can be x1,y1,x2,y2 an url containing lat=y&lon=x&zoom=z or a filename"},
+		{"selection", "string;string;...", "Add each to the initial selection. Can be a google-like search string or an url which returns osm-xml"},
+		{"reset-preferences", "any", "If specified, reset the configuration instead of reading it."}
+	};
+	
+	private Map<String, Collection<String>> args = new HashMap<String, Collection<String>>(); 
+
+	@Override public String[][] getParameterInfo() {
+		return paramInfo;
+	}
+
+	@Override public void init() {
+		for (String[] s : paramInfo) {
+			Collection<String> p = readParameter(s[0], args.get(s[0]));
+			if (p != null)
+				args.put(s[0], p);
+		}
+		if (!args.containsKey("geometry") && getParameter("width") != null && getParameter("height") != null) {
+			args.put("geometry", Arrays.asList(new String[]{getParameter("width")+"x"+getParameter("height")}));
+		}
+	}
+
+	@Override public void start() {
+		String username = args.containsKey("username") ? args.get("username").iterator().next() : null;
+		String password = args.containsKey("password") ? args.get("password").iterator().next() : null;
+		if (username == null || password == null) {
+			JPanel p = new JPanel(new GridBagLayout());
+			p.add(new JLabel("Username"), GBC.std().insets(0,0,20,0));
+			JTextField user = new JTextField(username == null ? "" : username);
+			p.add(user, GBC.eol().fill(GBC.HORIZONTAL));
+			p.add(new JLabel("Password"), GBC.std().insets(0,0,20,0));
+			JPasswordField pass = new JPasswordField(password == null ? "" : password);
+			p.add(pass, GBC.eol().fill(GBC.HORIZONTAL));
+			JOptionPane.showMessageDialog(null, p);
+			username = user.getText();
+			password = new String(pass.getPassword());
+			args.put("password", Arrays.asList(new String[]{password}));
+		}
+
+		Main.pref = new ServerSidePreferences(getCodeBase(), username);
+		
+		Main.preConstructorInit(args);
+		Main.parent = this;
+		new MainCaller().postConstructorProcessCmdLine(args);
+    }
+
+	private Collection<String> readParameter(String s, Collection<String> v) {
+		String param = getParameter(s);
+		if (param != null) {
+			if (v == null)
+				v = new LinkedList<String>();
+			v.addAll(Arrays.asList(param.split(";")));
+		}
+		return v;
+	}
+}
Index: src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- src/org/openstreetmap/josm/gui/MainApplication.java	(revision 98)
+++ src/org/openstreetmap/josm/gui/MainApplication.java	(revision 98)
@@ -0,0 +1,138 @@
+//Licence: GPL
+package org.openstreetmap.josm.gui;
+
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.BugReportExceptionHandler;
+
+/**
+ * Main window class application.
+ *  
+ * @author imi
+ */
+public class MainApplication extends Main {
+
+	/**
+	 * Construct an main frame, ready sized and operating. Does not 
+	 * display the frame.
+	 */
+	public MainApplication(JFrame mainFrame) {
+		mainFrame.setContentPane(contentPane);
+		mainFrame.setJMenuBar(mainMenu);
+		mainFrame.setBounds(bounds);
+		mainFrame.addWindowListener(new WindowAdapter(){
+			@Override public void windowClosing(final WindowEvent arg0) {
+				if (Main.map != null) {
+					boolean modified = false;
+					boolean uploadedModified = false;
+					for (final Layer l : Main.map.mapView.getAllLayers()) {
+						if (l instanceof OsmDataLayer && ((OsmDataLayer)l).isModified()) {
+							modified = true;
+							uploadedModified = ((OsmDataLayer)l).uploadedModified;
+							break;
+						}
+					}
+					if (modified) {
+						final String msg = uploadedModified ? "\nHint: Some changes came from uploading new data to the server." : "";
+						final int answer = JOptionPane.showConfirmDialog(
+								Main.parent, "There are unsaved changes. Really quit?"+msg,
+								"Unsaved Changes", JOptionPane.YES_NO_OPTION);
+						if (answer != JOptionPane.YES_OPTION)
+							return;
+					}
+				}
+				System.exit(0);
+			}
+		});
+		mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+	}
+
+	/**
+	 * Main application Startup
+	 * @param args	No parameters accepted.
+	 */
+	public static void main(final String[] argArray) {
+		Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
+
+		List<String> argList = Arrays.asList(argArray);
+		if (argList.contains("--help") || argList.contains("-?") || argList.contains("-h")) {
+			System.out.println("Java OpenStreetMap Editor");
+			System.out.println();
+			System.out.println("usage:");
+			System.out.println("\tjava -jar josm.jar <option> <option> <option>...");
+			System.out.println();
+			System.out.println("options:");
+			System.out.println("\t--help|-?|-h                              Show this help");
+			System.out.println("\t--geometry=widthxheight(+|-)x(+|-)y       Standard unix geometry argument");
+			System.out.println("\t[--download=]minlat,minlon,maxlat,maxlon  Download the bounding box");
+			System.out.println("\t[--download=]<url>                        Download the location at the url (with lat=x&lon=y&zoom=z)");
+			System.out.println("\t[--download=]<filename>                   Open file (as raw gps, if .gpx or .csv)");
+			System.out.println("\t--downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box as raw gps");
+			System.out.println("\t--selection=<searchstring>                Select with the given search");
+			System.out.println("\t--no-fullscreen                           Don't launch in fullscreen mode");
+			System.out.println("\t--reset-preferences                       Reset the preferences to default");
+			System.out.println();
+			System.out.println("examples:");
+			System.out.println("\tjava -jar josm.jar track1.gpx track2.gpx london.osm");
+			System.out.println("\tjava -jar josm.jar http://www.openstreetmap.org/index.html?lat=43.2&lon=11.1&zoom=13");
+			System.out.println("\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml");
+			System.out.println("\tjava -jar josm.jar 43.2,11.1,43.4,11.4");
+			System.out.println();
+			System.out.println("Parameters are read in the order they are specified, so make sure you load");
+			System.out.println("some data before --selection");
+			System.out.println();
+			System.out.println("Instead of --download=<bbox> you may specify osm://<bbox>");
+			System.exit(0);
+		}
+
+		final File prefDir = new File(Main.pref.getPreferencesDir());
+		if (prefDir.exists() && !prefDir.isDirectory()) {
+			JOptionPane.showMessageDialog(null, "Cannot open preferences directory: "+Main.pref.getPreferencesDir());
+			return;
+		}
+		if (!prefDir.exists())
+			prefDir.mkdirs();
+
+		// construct argument table
+		Map<String, Collection<String>> args = new HashMap<String, Collection<String>>();
+		for (String arg : argArray) {
+			if (!arg.startsWith("--"))
+				arg = "--download="+arg;
+			int i = arg.indexOf('=');
+			String key = i == -1 ? arg.substring(2) : arg.substring(2,i);
+			String value = i == -1 ? "" : arg.substring(i+1);
+			Collection<String> v = args.get(key);
+			if (v == null)
+				v = new LinkedList<String>();
+			v.add(value);
+			args.put(key, v);
+		}
+
+		preConstructorInit(args);
+		JFrame mainFrame = new JFrame("Java Open Street Map - Editor");
+		Main.parent = mainFrame;
+		Main main = new MainApplication(mainFrame);
+
+		mainFrame.setVisible(true);
+
+		if (!args.containsKey("no-fullscreen") && !args.containsKey("geometry") && Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH))
+			mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+
+		main.postConstructorProcessCmdLine(args);
+	}
+}
Index: src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapFrame.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/MapFrame.java	(revision 98)
@@ -59,4 +59,5 @@
 	
 	public ConflictDialog conflictDialog;
+	private JPanel toggleDialogs = new JPanel();
 	
 	/**
@@ -115,8 +116,7 @@
 		});
 
-		JPanel toggleDialogs = new JPanel();
 		add(toggleDialogs, BorderLayout.EAST);
+		toggleDialogs.setLayout(new BoxLayout(toggleDialogs, BoxLayout.Y_AXIS));
 
-		toggleDialogs.setLayout(new BoxLayout(toggleDialogs, BoxLayout.Y_AXIS));
 		addIconToggle(toggleDialogs, new LayerList(this));
 		addIconToggle(toggleDialogs, new PropertiesDialog(this));
@@ -129,4 +129,12 @@
 	}
 
+	/**
+	 * Open all ToggleDialogs that have their preferences property set. Close all others.
+	 */
+	public void setVisibleDialogs() {
+		for (Component c : toggleDialogs.getComponents())
+			if (c instanceof ToggleDialog)
+				c.setVisible(Main.pref.getBoolean(((ToggleDialog)c).prefName+".visible"));
+	}
 
 	private void addIconToggle(JPanel toggleDialogs, ToggleDialog dlg) {
@@ -135,6 +143,4 @@
 		toolBarActions.add(button);
 		toggleDialogs.add(dlg);
-		if (Main.pref.getBoolean(dlg.action.prefname+".visible"))
-			dlg.action.actionPerformed(new ActionEvent(this, 0, ""));
 	}
 
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 98)
@@ -10,4 +10,6 @@
 import java.util.Collections;
 import java.util.LinkedList;
+
+import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
@@ -62,5 +64,5 @@
 	 * Direct link to the edit layer (if any) in the layers list.
 	 */
-	private OsmDataLayer editLayer;
+	public OsmDataLayer editLayer;
 	/**
 	 * The layer from the layers list that is currently active.
@@ -108,5 +110,5 @@
 			dataLayer.listenerModified.add(new ModifiedChangedListener(){
             	public void modifiedChanged(boolean value, OsmDataLayer source) {
-            		Main.main.setTitle((value?"*":"")+"Java Open Street Map - Editor");
+            		JOptionPane.getFrameForComponent(Main.parent).setTitle((value?"*":"")+"Java Open Street Map - Editor");
             	}
             });
@@ -290,14 +292,4 @@
 
 	/**
-	 * @return The current edit layer. If no edit layer exist, one is created.
-	 * 		So editLayer does never return <code>null</code>.
-	 */
-	public OsmDataLayer editLayer() {
-		if (editLayer == null)
-			addLayer(new OsmDataLayer(Main.ds, "unnamed", false));
-		return editLayer;
-	}
-
-	/**
 	 * In addition to the base class funcitonality, this keep trak of the autoscale
 	 * feature.
Index: src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 98)
@@ -44,5 +44,5 @@
 	 */
 	public PleaseWaitRunnable(String msg) {
-		pleaseWaitDlg = new JDialog(Main.main, msg, true);
+		pleaseWaitDlg = new JDialog(JOptionPane.getFrameForComponent(Main.parent), msg, true);
 		pleaseWaitDlg.setLayout(new GridBagLayout());
 		JPanel pane = new JPanel(new GridBagLayout());
@@ -54,5 +54,5 @@
 		pleaseWaitDlg.setContentPane(pane);
 		pleaseWaitDlg.setSize(350,100);
-		pleaseWaitDlg.setLocationRelativeTo(Main.main);
+		pleaseWaitDlg.setLocationRelativeTo(Main.parent);
 
 		cancel.addActionListener(new ActionListener(){
@@ -122,5 +122,5 @@
 				pleaseWaitDlg.dispose();
 				if (errorMessage != null)
-					JOptionPane.showMessageDialog(Main.main, errorMessage);
+					JOptionPane.showMessageDialog(Main.parent, errorMessage);
 			}
 		});
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 98)
@@ -86,5 +86,5 @@
 			if (requiresRestart)
 				JOptionPane.showMessageDialog(PreferenceDialog.this, "You have to restart JOSM for some settings to take effect.");
-			Main.main.repaint();
+			Main.parent.repaint();
 			setVisible(false);
 		}
@@ -166,5 +166,5 @@
 	 */
 	public PreferenceDialog() {
-		super(Main.main, "Preferences");
+		super(JOptionPane.getFrameForComponent(Main.parent), "Preferences");
 
 		// look and feel combo box
@@ -346,5 +346,5 @@
 		setModal(true);
 		pack();
-		setLocationRelativeTo(Main.main);
+		setLocationRelativeTo(Main.parent);
 	}
 
Index: src/org/openstreetmap/josm/gui/ShowModifiers.java
===================================================================
--- src/org/openstreetmap/josm/gui/ShowModifiers.java	(revision 97)
+++ 	(revision )
@@ -1,137 +1,0 @@
-package org.openstreetmap.josm.gui;
-import java.awt.AWTEvent;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.GridLayout;
-import java.awt.Toolkit;
-import java.awt.event.AWTEventListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.JComponent;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-public class ShowModifiers extends JFrame implements AWTEventListener, Runnable {
-
-	private JLabel ctrl, alt, shift;
-
-	private int mouseMod = -1;
-	private int wheelMod = 0;
-
-	public ShowModifiers(int x, int y) {
-		Toolkit.getDefaultToolkit().addAWTEventListener(this, 
-				AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
-
-		setDefaultCloseOperation(EXIT_ON_CLOSE);
-		setUndecorated(true);
-		setAlwaysOnTop(true);
-		Box v = Box.createHorizontalBox();
-		//v.add(mouse);
-		JComponent mouseSpace = new JLabel();
-		mouseSpace.setPreferredSize(new Dimension(63,103));
-		v.add(mouseSpace);
-		setContentPane(v);
-
-		JPanel p = new JPanel(new GridLayout(3,1));
-		v.add(p);
-		p.add(ctrl = createLabel("Ctrl"));
-		p.add(alt = createLabel("Alt"));
-		p.add(shift = createLabel("Shift"));
-		pack();
-		setLocation(x-getWidth(),y-getHeight());
-		setVisible(true);
-	}
-
-	private JLabel createLabel(String name) {
-		JLabel l = new JLabel(name);
-		l.setHorizontalAlignment(JLabel.CENTER);
-		l.setBorder(BorderFactory.createCompoundBorder(
-				BorderFactory.createLineBorder(Color.BLACK),
-				BorderFactory.createEmptyBorder(3,3,3,3)));
-		l.setFont(l.getFont().deriveFont(Font.PLAIN));
-		l.setOpaque(true);
-		return l;
-	}
-
-	public void eventDispatched(AWTEvent event) {
-		int keyMod = -1;
-		if (event instanceof InputEvent) {
-			InputEvent e = (InputEvent)event;
-			keyMod = e.getModifiersEx();
-			ctrl.setBackground((keyMod & KeyEvent.CTRL_DOWN_MASK) != 0 ? Color.RED : null);
-			alt.setBackground((keyMod & KeyEvent.ALT_DOWN_MASK) != 0 ? Color.RED : null);
-			shift.setBackground((keyMod & KeyEvent.SHIFT_DOWN_MASK) != 0 ? Color.RED : null);
-		}
-		if (event instanceof MouseWheelEvent) {
-			wheelMod = ((MouseWheelEvent)event).getWheelRotation();
-			repaint();
-		}
-		if (event instanceof MouseEvent) {
-			MouseEvent e = (MouseEvent)event;
-			mouseMod = e.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK);
-			repaint();
-		}
-		new Thread(this).start();
-	}
-
-	public static void main(String[] args) {
-		new ShowModifiers(0,0);
-	}
-
-	public void run() {
-		try {Thread.sleep(250);} catch (InterruptedException e) {}
-		wheelMod = 0;
-		Graphics g = getGraphics();
-		if (g != null) {
-			paint(g);
-			g.dispose();
-		}
-	}
-	
-	private void paintMouse(Graphics g) {
-		g.setColor(getBackground());
-		g.fillRect(0,0,60,100);
-		g.setColor(Color.BLACK);
-		
-		g.drawLine(5,5,55,5);
-		g.drawLine(5,5,5,75);
-		g.drawLine(55,5,55,75);
-		g.drawArc(5,55,50,40,180,180);
-		
-		g.drawLine(5,30,55,30);
-		g.drawLine(25,5,25,30);
-		g.drawLine(35,5,35,30);
-		g.drawLine(25,12,35,12);
-		g.drawLine(25,23,35,23);
-		
-		if (mouseMod == -1)
-			return;
-		g.setColor(Color.RED);
-		if ((mouseMod & MouseEvent.BUTTON1_DOWN_MASK) != 0)
-			g.fillRect(6,6,19,24);
-		if ((mouseMod & MouseEvent.BUTTON2_DOWN_MASK) != 0)
-			g.fillRect(26,13,9,10);
-		if ((mouseMod & MouseEvent.BUTTON3_DOWN_MASK) != 0)
-			g.fillRect(36,6,19,24);
-		
-		if (wheelMod == 0)
-			return;
-		if (wheelMod < 0)
-			g.fillRect(26,6,9,6);
-		else
-			g.fillRect(26,24,9,6);
-	}
-
-	@Override public void paint(Graphics g) {
-		super.paint(g);
-		paintMouse(g);
-	}
-}
Index: src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java	(revision 98)
@@ -14,6 +14,10 @@
 import javax.swing.tree.DefaultTreeModel;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
 
@@ -22,11 +26,16 @@
 	private DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode());
     private JTree tree = new JTree(treeModel);
-	private final MapFrame mapFrame;
 
-	public CommandStackDialog(MapFrame mapFrame) {
+	public CommandStackDialog(final MapFrame mapFrame) {
 		super("Command Stack", "commandstack", "Open a list of all commands (undo buffer).", KeyEvent.VK_C);
-		this.mapFrame = mapFrame;
 		setPreferredSize(new Dimension(320,100));
-		mapFrame.mapView.editLayer().listenerCommands.add(this);
+		mapFrame.mapView.addLayerChangeListener(new LayerChangeListener(){
+			public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
+			public void layerAdded(Layer newLayer) {
+				if (newLayer instanceof OsmDataLayer)
+					Main.main.editLayer().listenerCommands.add(CommandStackDialog.this);
+			}
+			public void layerRemoved(Layer oldLayer) {}
+		});
 		tree.setRootVisible(false);
 		tree.setShowsRootHandles(true);
@@ -57,5 +66,5 @@
 
 	private void buildList() {
-		Collection<Command> commands = mapFrame.mapView.editLayer().commands;
+		Collection<Command> commands = Main.main.editLayer().commands;
 		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
 		for (Command c : commands)
@@ -64,5 +73,5 @@
 	}
 
-	public void commandChanged() {
+	public void commandChanged(int queueSize, int redoSize) {
 		if (!isVisible())
 			return;
Index: src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 98)
@@ -36,5 +36,4 @@
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.ConflictResolver;
-import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
@@ -96,5 +95,5 @@
 		displaylist.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
 			public void valueChanged(ListSelectionEvent e) {
-				Main.main.getMapFrame().mapView.repaint();
+				Main.map.mapView.repaint();
 			}
 		});
@@ -103,5 +102,5 @@
 	private final void resolve() {
 		if (displaylist.getSelectedIndex() == -1) {
-			JOptionPane.showMessageDialog(Main.main, "Please select something from the conflict list.");
+			JOptionPane.showMessageDialog(Main.parent, "Please select something from the conflict list.");
 			return;
 		}
@@ -112,10 +111,9 @@
 		}
 		ConflictResolver resolver = new ConflictResolver(sel);
-		int answer = JOptionPane.showConfirmDialog(Main.main, resolver, "Resolve Conflicts", JOptionPane.OK_CANCEL_OPTION);
+		int answer = JOptionPane.showConfirmDialog(Main.parent, resolver, "Resolve Conflicts", JOptionPane.OK_CANCEL_OPTION);
 		if (answer != JOptionPane.OK_OPTION)
 			return;
-		MapView mv = Main.main.getMapFrame().mapView;
-		mv.editLayer().add(new ConflictResolveCommand(resolver.conflicts, sel));
-		mv.repaint();
+		Main.main.editLayer().add(new ConflictResolveCommand(resolver.conflicts, sel));
+		Main.map.mapView.repaint();
 	}
 
Index: src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 98)
@@ -28,5 +28,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -57,18 +56,13 @@
 
         public void actionPerformed(ActionEvent e) {
-        	if (layers.getModel().getSize() == 1) {
-        		Main.main.setMapFrame(null);
-        		Main.ds = new DataSet();
-        	} else {
-        	    int sel = layers.getSelectedIndex();
-                if (layer != null)
-                    Main.main.getMapFrame().mapView.removeLayer(layer);
-                else
-                    Main.main.getMapFrame().mapView.removeLayer((Layer)layers.getSelectedValue());
-                if (sel >= layers.getModel().getSize())
-                    sel = layers.getModel().getSize()-1;
-                if (layers.getSelectedValue() == null)
-                    layers.setSelectedIndex(sel);
-        	}
+    	    int sel = layers.getSelectedIndex();
+            if (layer != null)
+                Main.main.removeLayer(layer);
+            else
+                Main.main.removeLayer((Layer)layers.getSelectedValue());
+            if (sel >= layers.getModel().getSize())
+                sel = layers.getModel().getSize()-1;
+            if (layers.getSelectedValue() == null)
+                layers.setSelectedIndex(sel);
         }
     }
@@ -88,5 +82,5 @@
             Layer l = layer == null ? (Layer)layers.getSelectedValue() : layer;
             l.visible = !l.visible;
-        	Main.main.getMapFrame().mapView.repaint();
+        	Main.map.mapView.repaint();
         	layers.repaint();
         }
Index: src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 98)
@@ -24,5 +24,5 @@
 	    }
 	    public void actionPerformed(ActionEvent e) {
-	    	JOptionPane.showMessageDialog(Main.main, layer.getInfoComponent());
+	    	JOptionPane.showMessageDialog(Main.parent, layer.getInfoComponent());
 	    }
     }
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 98)
@@ -40,5 +40,4 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -95,5 +94,5 @@
 
 		final JOptionPane optionPane = new JOptionPane(p, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
-		final JDialog dlg = optionPane.createDialog(Main.main, "Change values?");
+		final JDialog dlg = optionPane.createDialog(Main.parent, "Change values?");
 		dlg.addWindowFocusListener(new WindowFocusListener(){
 			public void windowGainedFocus(WindowEvent e) {
@@ -124,5 +123,5 @@
 		if (value.equals(""))
 			value = null; // delete the key
-		mv.editLayer().add(new ChangePropertyCommand(sel, key, value));
+		Main.main.editLayer().add(new ChangePropertyCommand(sel, key, value));
 
 		if (value == null)
@@ -163,5 +162,5 @@
 		JTextField values = new JTextField();
 		p2.add(values, BorderLayout.CENTER);
-		int answer = JOptionPane.showConfirmDialog(Main.main, p, 
+		int answer = JOptionPane.showConfirmDialog(Main.parent, p, 
 				"Change values?", JOptionPane.OK_CANCEL_OPTION); 
 		if (answer != JOptionPane.OK_OPTION)
@@ -171,5 +170,5 @@
 		if (value.equals(""))
 			return;
-		mv.editLayer().add(new ChangePropertyCommand(sel, key, value));
+		Main.main.editLayer().add(new ChangePropertyCommand(sel, key, value));
 		selectionChanged(sel); // update table
 	}
@@ -182,5 +181,5 @@
 		String key = data.getValueAt(row, 0).toString();
 		Collection<OsmPrimitive> sel = Main.ds.getSelected();
-		mv.editLayer().add(new ChangePropertyCommand(sel, key, null));
+		Main.main.editLayer().add(new ChangePropertyCommand(sel, key, null));
 		selectionChanged(sel); // update table
 	}
@@ -201,8 +200,4 @@
 	 */
 	private final JTable propertyTable = new JTable(data);
-	/**
-	 * The map view this dialog operates on.
-	 */
-	private final MapView mv;
 	
 	/**
@@ -211,5 +206,4 @@
 	public PropertiesDialog(MapFrame mapFrame) {
 		super("Properties", "propertiesdialog", "Property for selected objects.", KeyEvent.VK_P);
-		mv = mapFrame.mapView;
 
 		setPreferredSize(new Dimension(320,150));
@@ -248,10 +242,10 @@
 				else if (e.getActionCommand().equals("Edit")) {
 					if (sel == -1)
-						JOptionPane.showMessageDialog(Main.main, "Please select the row to edit.");
+						JOptionPane.showMessageDialog(Main.parent, "Please select the row to edit.");
 					else
 						edit(sel);
 				} else if (e.getActionCommand().equals("Delete")) {
 					if (sel == -1)
-						JOptionPane.showMessageDialog(Main.main, "Please select the row to delete.");
+						JOptionPane.showMessageDialog(Main.parent, "Please select the row to delete.");
 					else
 						delete(sel);
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 98)
@@ -87,8 +87,8 @@
 	        } catch (IOException e) {
 		        e.printStackTrace();
-		        JOptionPane.showMessageDialog(Main.main, "Could not read from url: '"+url+"'");
+		        JOptionPane.showMessageDialog(Main.parent, "Could not read from url: '"+url+"'");
 	        } catch (SAXException e) {
 		        e.printStackTrace();
-		        JOptionPane.showMessageDialog(Main.main, "Parsing error in url: '"+url+"'");
+		        JOptionPane.showMessageDialog(Main.parent, "Parsing error in url: '"+url+"'");
 	        }
         }
@@ -185,5 +185,5 @@
                     }
 				};
-				pane.createDialog(Main.main, "Search").setVisible(true);
+				pane.createDialog(Main.parent, "Search").setVisible(true);
 				if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
 					return;
Index: src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 98)
@@ -44,6 +44,8 @@
 	 */
 	public ToggleDialogAction action;
+	public final String prefName;
 
 	public ToggleDialog(String name, String iconName, String tooltip, int shortCut) {
+		this.prefName = iconName;
 		action = new ToggleDialogAction(name, "dialogs/"+iconName, tooltip, ShortCutLabel.name(shortCut, KeyEvent.ALT_MASK), KeyStroke.getKeyStroke(shortCut, KeyEvent.ALT_MASK), iconName);
 		setLayout(new BorderLayout());
Index: src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 98)
@@ -50,5 +50,5 @@
 		public final String[] names = {"node", "segment", "way"};
 
-		private void inc(OsmPrimitive osm, int i) {
+		private void inc(final OsmPrimitive osm, final int i) {
 			normal[i]++;
 			if (osm.deleted)
@@ -56,13 +56,13 @@
 		}
 
-		public void visit(Node n) {
+		public void visit(final Node n) {
 			inc(n, 0);
 		}
 
-		public void visit(Segment ls) {
+		public void visit(final Segment ls) {
 			inc(ls, 1);
 		}
 
-		public void visit(Way w) {
+		public void visit(final Way w) {
 			inc(w, 2);
 		}
@@ -73,5 +73,5 @@
 	}
 	public interface CommandQueueListener {
-		void commandChanged();
+		void commandChanged(int queueSize, int redoSize);
 	}
 
@@ -103,5 +103,5 @@
 	 * The stack for redoing commands
 	 */
-	private Stack<Command> redoCommands = new Stack<Command>();
+	private final Stack<Command> redoCommands = new Stack<Command>();
 
 	public final LinkedList<ModifiedChangedListener> listenerModified = new LinkedList<ModifiedChangedListener>();
@@ -112,5 +112,5 @@
 	 * Construct a OsmDataLayer.
 	 */
-	public OsmDataLayer(DataSet data, String name, boolean fromDisk) {
+	public OsmDataLayer(final DataSet data, final String name, final boolean fromDisk) {
 		super(name);
 		this.data = data;
@@ -133,19 +133,19 @@
 	 * Draw nodes last to overlap the segments they belong to.
 	 */
-	@Override public void paint(Graphics g, MapView mv) {
-		SimplePaintVisitor visitor = new SimplePaintVisitor(g, mv);
-		for (OsmPrimitive osm : data.segments)
+	@Override public void paint(final Graphics g, final MapView mv) {
+		final SimplePaintVisitor visitor = new SimplePaintVisitor(g, mv);
+		for (final OsmPrimitive osm : data.segments)
 			if (!osm.deleted)
 				osm.visit(visitor);
-		for (OsmPrimitive osm : data.ways)
+		for (final OsmPrimitive osm : data.ways)
 			if (!osm.deleted)
 				osm.visit(visitor);
-		for (OsmPrimitive osm : data.nodes)
+		for (final OsmPrimitive osm : data.nodes)
 			if (!osm.deleted)
 				osm.visit(visitor);
-		for (OsmPrimitive osm : data.getSelected())
+		for (final OsmPrimitive osm : data.getSelected())
 			if (!osm.deleted)
 				osm.visit(visitor);
-		Main.main.getMapFrame().conflictDialog.paintConflicts(g, mv);
+		Main.map.conflictDialog.paintConflicts(g, mv);
 	}
 
@@ -156,24 +156,24 @@
 	}
 
-	@Override public void mergeFrom(Layer from) {
+	@Override public void mergeFrom(final Layer from) {
 		final MergeVisitor visitor = new MergeVisitor(data);
-		for (OsmPrimitive osm : ((OsmDataLayer)from).data.allPrimitives())
+		for (final OsmPrimitive osm : ((OsmDataLayer)from).data.allPrimitives())
 			osm.visit(visitor);
 		visitor.fixReferences();
 		if (visitor.conflicts.isEmpty())
 			return;
-		ConflictDialog dlg = Main.main.getMapFrame().conflictDialog;
+		final ConflictDialog dlg = Main.map.conflictDialog;
 		dlg.add(visitor.conflicts);
-		JOptionPane.showMessageDialog(Main.main, "There were conflicts during import.");
+		JOptionPane.showMessageDialog(Main.parent, "There were conflicts during import.");
 		if (!dlg.isVisible())
 			dlg.action.actionPerformed(new ActionEvent(this, 0, ""));
 	}
 
-	@Override public boolean isMergable(Layer other) {
+	@Override public boolean isMergable(final Layer other) {
 		return other instanceof OsmDataLayer;
 	}
 
-	@Override public void visitBoundingBox(BoundingXYVisitor v) {
-		for (Node n : data.nodes)
+	@Override public void visitBoundingBox(final BoundingXYVisitor v) {
+		for (final Node n : data.nodes)
 			if (!n.deleted)
 				v.visit(n);
@@ -184,14 +184,10 @@
 	 * primitives in the command as modified.
 	 */
-	public void add(Command c) {
+	public void add(final Command c) {
 		c.executeCommand();
 		commands.add(c);
 		redoCommands.clear();
-		// TODO: Replace with listener scheme
-		Main.main.undoAction.setEnabled(true);
-		Main.main.redoAction.setEnabled(false);
 		setModified(true);
-		for (CommandQueueListener l : listenerCommands)
-			l.commandChanged();
+		fireCommandsChanged();
 	}
 
@@ -202,15 +198,11 @@
 		if (commands.isEmpty())
 			return;
-		Command c = commands.removeLast();
+		final Command c = commands.removeLast();
 		c.undoCommand();
 		redoCommands.push(c);
 		//TODO: Replace with listener scheme
-		Main.main.undoAction.setEnabled(!commands.isEmpty());
-		Main.main.redoAction.setEnabled(true);
-		if (commands.isEmpty())
 			setModified(uploadedModified);
 		Main.ds.clearSelection();
-		for (CommandQueueListener l : listenerCommands)
-			l.commandChanged();
+		fireCommandsChanged();
 	}
 	/**
@@ -220,13 +212,9 @@
 		if (redoCommands.isEmpty())
 			return;
-		Command c = redoCommands.pop();
+		final Command c = redoCommands.pop();
 		c.executeCommand();
 		commands.add(c);
-		//TODO: Replace with listener scheme
-		Main.main.undoAction.setEnabled(true);
-		Main.main.redoAction.setEnabled(!redoCommands.isEmpty());
 		setModified(true);
-		for (CommandQueueListener l : listenerCommands)
-			l.commandChanged();
+		fireCommandsChanged();
 	}
 
@@ -240,5 +228,5 @@
 	 * 		saved to disk instead.
 	 */
-	public void cleanData(Collection<OsmPrimitive> processed, boolean dataAdded) {
+	public void cleanData(final Collection<OsmPrimitive> processed, boolean dataAdded) {
 		redoCommands.clear();
 		commands.clear();
@@ -246,10 +234,10 @@
 		// if uploaded, clean the modified flags as well
 		if (processed != null) {
-			Set<OsmPrimitive> processedSet = new HashSet<OsmPrimitive>(processed);
-			for (Iterator<Node> it = data.nodes.iterator(); it.hasNext();)
+			final Set<OsmPrimitive> processedSet = new HashSet<OsmPrimitive>(processed);
+			for (final Iterator<Node> it = data.nodes.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
-			for (Iterator<Segment> it = data.segments.iterator(); it.hasNext();)
+			for (final Iterator<Segment> it = data.segments.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
-			for (Iterator<Way> it = data.ways.iterator(); it.hasNext();)
+			for (final Iterator<Way> it = data.ways.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
 		}
@@ -263,8 +251,11 @@
 		uploadedModified = fromDisk && processed != null && dataAdded;
 		setModified(uploadedModified);
-		//TODO: Replace with listener scheme
-		Main.main.undoAction.setEnabled(false);
-		Main.main.redoAction.setEnabled(false);
-	}
+		fireCommandsChanged();
+	}
+
+	public void fireCommandsChanged() {
+	    for (final CommandQueueListener l : listenerCommands)
+			l.commandChanged(commands.size(), redoCommands.size());
+    }
 
 	/**
@@ -276,6 +267,6 @@
 	 * 		If the object in the iterator is not in the list, nothing will be changed on it.
 	 */
-	private void cleanIterator(Iterator<? extends OsmPrimitive> it, Collection<OsmPrimitive> processed) {
-		OsmPrimitive osm = it.next();
+	private void cleanIterator(final Iterator<? extends OsmPrimitive> it, final Collection<OsmPrimitive> processed) {
+		final OsmPrimitive osm = it.next();
 		if (!processed.remove(osm))
 			return;
@@ -289,9 +280,9 @@
 	}
 
-	public void setModified(boolean modified) {
+	public void setModified(final boolean modified) {
 		if (modified == this.modified)
 			return;
 		this.modified = modified;
-		for (ModifiedChangedListener l : listenerModified)
+		for (final ModifiedChangedListener l : listenerModified)
 			l.modifiedChanged(modified, this);
 	}
@@ -300,7 +291,7 @@
 	 * @return The number of not-deleted primitives in the list.
 	 */
-	private int undeletedSize(Collection<? extends OsmPrimitive> list) {
+	private int undeletedSize(final Collection<? extends OsmPrimitive> list) {
 		int size = 0;
-		for (OsmPrimitive osm : list)
+		for (final OsmPrimitive osm : list)
 			if (!osm.deleted)
 				size++;
@@ -309,8 +300,8 @@
 
 	@Override public Object getInfoComponent() {
-		DataCountVisitor counter = new DataCountVisitor();
-		for (OsmPrimitive osm : data.allPrimitives())
+		final DataCountVisitor counter = new DataCountVisitor();
+		for (final OsmPrimitive osm : data.allPrimitives())
 			osm.visit(counter);
-		JPanel p = new JPanel(new GridBagLayout());
+		final JPanel p = new JPanel(new GridBagLayout());
 		p.add(new JLabel(name+" consists of:"), GBC.eol());
 		for (int i = 0; i < counter.normal.length; ++i) {
@@ -323,5 +314,5 @@
 	}
 
-	@Override public void addMenuEntries(JPopupMenu menu) {
+	@Override public void addMenuEntries(final JPopupMenu menu) {
 		menu.add(new JMenuItem(new SaveAction()));
 		menu.add(new JMenuItem(new GpxExportAction(this)));
Index: src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 97)
+++ src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 98)
@@ -54,10 +54,10 @@
 		super(name);
 		this.data = data;
-		Main.pref.addPreferenceChangedListener(new PreferenceChangedListener(){
-			public void preferenceChanged(String key, String newValue) {
-				if (Main.main.getMapFrame() != null && (key.equals("drawRawGpsLines") || key.equals("forceRawGpsLines")))
-					Main.main.getMapFrame().repaint();
-			}
-		});
+		Main.pref.listener.add(new PreferenceChangedListener(){
+        	public void preferenceChanged(String key, String newValue) {
+        		if (Main.map != null && (key.equals("drawRawGpsLines") || key.equals("forceRawGpsLines")))
+        			Main.map.repaint();
+        	}
+        });
 	}
 
@@ -137,5 +137,5 @@
 				JColorChooser c = new JColorChooser(ColorHelper.html2color(col));
 				Object[] options = new Object[]{"OK", "Cancel", "Default"};
-				int answer = JOptionPane.showOptionDialog(Main.main, c, "Choose a color", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
+				int answer = JOptionPane.showOptionDialog(Main.parent, c, "Choose a color", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
 				switch (answer) {
 				case 0:
@@ -148,5 +148,5 @@
 					break;
 				}
-				Main.main.repaint();
+				Main.map.repaint();
 			}
 		});
Index: src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmConnection.java	(revision 97)
+++ src/org/openstreetmap/josm/io/OsmConnection.java	(revision 98)
@@ -66,5 +66,5 @@
     			warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
     			p.add(warning, GBC.eol());
-    			int choice = JOptionPane.showConfirmDialog(Main.main, p, "Enter Password", JOptionPane.OK_CANCEL_OPTION);
+    			int choice = JOptionPane.showConfirmDialog(Main.parent, p, "Enter Password", JOptionPane.OK_CANCEL_OPTION);
     			if (choice == JOptionPane.CANCEL_OPTION) {
     				authCancelled = true;
Index: src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java
===================================================================
--- src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 97)
+++ src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 98)
@@ -28,7 +28,7 @@
 	public void uncaughtException(Thread t, Throwable e) {
 		e.printStackTrace();
-		if (Main.main != null) {
+		if (Main.parent != null) {
 			Object[] options = new String[]{"Do nothing", "Report Bug"};
-			int answer = JOptionPane.showOptionDialog(Main.main, "An unexpected exception occoured.\n\n" +
+			int answer = JOptionPane.showOptionDialog(Main.parent, "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.",
@@ -69,5 +69,5 @@
 					p.add(new JScrollPane(info), GBC.eop());
 
-					JOptionPane.showMessageDialog(Main.main, p);
+					JOptionPane.showMessageDialog(Main.parent, p);
 				} catch (Exception e1) {
 					e1.printStackTrace();
Index: src/org/openstreetmap/josm/tools/TileCache.java
===================================================================
--- src/org/openstreetmap/josm/tools/TileCache.java	(revision 97)
+++ src/org/openstreetmap/josm/tools/TileCache.java	(revision 98)
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -153,5 +152,5 @@
      */
     public synchronized Image get(final int tileId, final int zoom) {
-        final File cacheDir = new File(Main.pref.get("cache.directory", Preferences.getPreferencesDir()+"cache")+"/"+Main.proj.getCacheDirectoryName()+"/"+zoom);
+        final File cacheDir = new File(Main.pref.get("cache.directory", Main.pref.getPreferencesDir()+"cache")+"/"+Main.proj.getCacheDirectoryName()+"/"+zoom);
         if (!cache.containsKey(zoom)) {
             HashMap<Integer, Image> map = new HashMap<Integer, Image>();
@@ -189,5 +188,5 @@
                             map.put(tileId, loading);
                             currentlyLoading.remove(tileId*256+zoom);
-                            Main.main.repaint();
+                            Main.map.repaint();
                         } catch (Exception e) {
                             e.printStackTrace();
