Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 21)
+++ src/org/openstreetmap/josm/Main.java	(revision 21)
@@ -0,0 +1,195 @@
+// Licence: GPL
+package org.openstreetmap.josm;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.JToolBar;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.actions.AboutAction;
+import org.openstreetmap.josm.actions.ExitAction;
+import org.openstreetmap.josm.actions.OpenGpxAction;
+import org.openstreetmap.josm.actions.OpenOsmServerAction;
+import org.openstreetmap.josm.actions.PreferencesAction;
+import org.openstreetmap.josm.actions.SaveGpxAction;
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.data.Preferences.PreferencesException;
+import org.openstreetmap.josm.gui.ImageProvider;
+import org.openstreetmap.josm.gui.MapFrame;
+
+/**
+ * Main window class consisting of the mainframe MDI application.
+ *  
+ * @author imi
+ */
+public class Main extends JFrame {
+
+	/**
+	 * Global application window. Use this as JOPtionPane-parent to center on application.
+	 */
+	public static Main main;
+
+	/**
+	 * Global application preferences
+	 */
+	public final static Preferences pref = new Preferences();
+	
+	/**
+	 * The main panel.
+	 */
+	private Container panel;
+	/**
+	 * The name of the current loaded mapFrame
+	 */
+	private String name;
+	/**
+	 * The mapFrame currently loaded.
+	 */
+	private MapFrame mapFrame;
+	
+	/**
+	 * Construct an main frame, ready sized and operating. Does not 
+	 * display the frame.
+	 */
+	public Main() {
+		super("Java Open Street Map - Editor");
+		setLayout(new BorderLayout());
+		panel = new JPanel(new BorderLayout());
+		getContentPane().add(panel, BorderLayout.CENTER);
+		setSize(1000,740); // some strange default size
+		setExtendedState(MAXIMIZED_BOTH); // some platform are able to maximize
+		
+		// creating actions
+		OpenOsmServerAction openServerAction = new OpenOsmServerAction();
+		OpenGpxAction openGpxAction = new OpenGpxAction();
+		SaveGpxAction saveGpxAction = new SaveGpxAction();
+		ExitAction exitAction = new ExitAction();
+		PreferencesAction preferencesAction = new PreferencesAction();
+		AboutAction aboutAction = new AboutAction();
+
+		// creating menu
+		JMenuBar mainMenu = new JMenuBar();
+		setJMenuBar(mainMenu);
+
+		JMenu fileMenu = new JMenu("Files");
+		fileMenu.setMnemonic('F');
+		fileMenu.add(openGpxAction);
+		fileMenu.add(saveGpxAction);
+		fileMenu.addSeparator();
+		fileMenu.add(exitAction);
+		mainMenu.add(fileMenu);
+		
+		JMenu connectionMenu = new JMenu("Connection");
+		connectionMenu.setMnemonic('C');
+		connectionMenu.add(openServerAction);
+		mainMenu.add(connectionMenu);
+		
+		JMenu editMenu = new JMenu("Edit");
+		editMenu.setMnemonic('E');
+		editMenu.add(preferencesAction);
+		mainMenu.add(editMenu);
+		
+		mainMenu.add(new JSeparator());
+		JMenu helpMenu = new JMenu("Help");
+		helpMenu.setMnemonic('H');
+		helpMenu.add(aboutAction);
+		mainMenu.add(helpMenu);
+
+		// creating toolbar
+		JToolBar toolBar = new JToolBar();
+		toolBar.setFloatable(false);
+		toolBar.add(openServerAction);
+		toolBar.add(openGpxAction);
+		toolBar.add(saveGpxAction);
+		toolBar.addSeparator();
+		toolBar.add(preferencesAction);
+		
+		getContentPane().add(toolBar, BorderLayout.NORTH);
+	}
+
+	/**
+	 * Main application Startup
+	 * @param args	No parameters accepted.
+	 */
+	public static void main(String[] args) {
+		setupUiDefaults();
+		
+		// load preferences
+		String errMsg = null;
+		try {
+			pref.load();
+		} catch (PreferencesException e1) {
+			e1.printStackTrace();
+			errMsg = "Preferences could not be loaded. Write default preference file to '"+Preferences.getPreferencesDir()+"preferences'.";
+			try {
+				pref.save();
+			} catch (PreferencesException e) {
+				e.printStackTrace();
+				errMsg = "Preferences could not be loaded. Reverting to default.";
+			}
+		}
+		if (errMsg != null)
+			JOptionPane.showMessageDialog(null, errMsg);
+		
+		try {
+			UIManager.setLookAndFeel(pref.laf.getClassName());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		main = new Main();
+		main.setDefaultCloseOperation(EXIT_ON_CLOSE);
+		main.setVisible(true);
+	}
+
+
+	/**
+	 * Set the main's mapframe. If a changed old mapFrame is already set, 
+	 * ask the user whether he want to save, discard or abort. If the user
+	 * aborts, nothing happens. 
+	 */
+	public void setMapFrame(String name, MapFrame mapFrame) {
+		//TODO: Check for changes and ask user
+		this.name = name;
+		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 name.
+	 */
+	public String getNameOfLoadedMapFrame() {
+		return name;
+	}
+	/**
+	 * @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"));
+	}
+}
Index: src/org/openstreetmap/josm/actions/AboutAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AboutAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/AboutAction.java	(revision 21)
@@ -24,7 +24,7 @@
 import javax.swing.event.HyperlinkListener;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.GBC;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 
 /**
Index: src/org/openstreetmap/josm/actions/OpenGpxAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/OpenGpxAction.java	(revision 21)
@@ -17,8 +17,8 @@
 import javax.swing.filechooser.FileFilter;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.gui.GBC;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.layer.Layer;
Index: src/org/openstreetmap/josm/actions/OpenOsmServerAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenOsmServerAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/OpenOsmServerAction.java	(revision 21)
@@ -19,10 +19,10 @@
 import javax.swing.event.ListSelectionListener;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.BookmarkList;
 import org.openstreetmap.josm.gui.GBC;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
Index: src/org/openstreetmap/josm/actions/SaveGpxAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveGpxAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/SaveGpxAction.java	(revision 21)
@@ -11,6 +11,6 @@
 import javax.swing.JOptionPane;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.io.GpxWriter;
 
Index: src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 21)
@@ -10,10 +10,10 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 
Index: src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java	(revision 21)
@@ -6,5 +6,5 @@
 import java.util.LinkedList;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
Index: src/org/openstreetmap/josm/actions/mapmode/CombineAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/CombineAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/CombineAction.java	(revision 21)
@@ -9,10 +9,10 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 21)
@@ -10,5 +10,6 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.Key;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -16,5 +17,4 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 
Index: src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 21)
@@ -8,5 +8,5 @@
 import java.util.HashSet;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
Index: src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 20)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 21)
@@ -5,5 +5,5 @@
 import java.util.Collection;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.MapFrame;
Index: src/org/openstreetmap/josm/command/AddCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/AddCommand.java	(revision 21)
+++ src/org/openstreetmap/josm/command/AddCommand.java	(revision 21)
@@ -0,0 +1,84 @@
+package org.openstreetmap.josm.command;
+
+import java.awt.Component;
+import java.util.Iterator;
+
+import javax.swing.JLabel;
+
+import org.openstreetmap.josm.data.osm.Key;
+import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Track;
+import org.openstreetmap.josm.data.osm.visitor.SelectionComponentVisitor;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+
+/**
+ * A command that adds an osm primitive to a dataset. Keys cannot be added this
+ * way. Use ChangeKeyValueCommand instead.
+ * 
+ * @author imi
+ */
+public class AddCommand implements Command, Visitor {
+
+	/**
+	 * The primitive to add to the dataset.
+	 */
+	private final OsmPrimitive osm;
+	/**
+	 * The dataset to add the primitive to.
+	 */
+	private final DataSet ds;
+
+	/**
+	 * Create the command and specify the element to add.
+	 */
+	public AddCommand(OsmPrimitive osm, DataSet dataSet) {
+		this.osm = osm;
+		this.ds = dataSet;
+	}
+
+	public void executeCommand() {
+		osm.visit(this);
+	}
+
+	public Component commandDescription() {
+		SelectionComponentVisitor v = new SelectionComponentVisitor();
+		osm.visit(v);
+		return new JLabel(v.name, v.icon, JLabel.LEADING);
+	}
+
+	/**
+	 * Add the node to the nodes - list only.
+	 * @param n The node to add.
+	 */
+	public void visit(Node n) {
+		ds.nodes.add(n);
+	}
+
+	/**
+	 * Add the line segment to the list of pending line segments.
+	 * @param ls The line segment to add.
+	 */
+	public void visit(LineSegment ls) {
+		ds.pendingLineSegments.add(ls);
+	}
+
+	/**
+	 * Add the track to the dataset. Remove all line segments that were pending
+	 * from the dataset.
+	 */
+	public void visit(Track t) {
+		ds.addTrack(t);
+		for (Iterator<LineSegment> it =  ds.pendingLineSegments.iterator(); it.hasNext();)
+			if (t.segments().contains(it.next()))
+				it.remove();
+	}
+
+	/**
+	 * Add the key to the parent specified by the constructor
+	 */
+	public void visit(Key k) {
+		throw new IllegalStateException("Keys are added by using ChangeKeyValueCommand");
+	}
+}
Index: src/org/openstreetmap/josm/command/Command.java
===================================================================
--- src/org/openstreetmap/josm/command/Command.java	(revision 21)
+++ src/org/openstreetmap/josm/command/Command.java	(revision 21)
@@ -0,0 +1,23 @@
+package org.openstreetmap.josm.command;
+
+import java.awt.Component;
+
+
+/**
+ * Classes implementing Command modify a dataset in a specific way. A command is
+ * one atomic action on a dataset, such as move or delete.
+ *
+ * @author imi
+ */
+public interface Command {
+
+	/**
+	 * Executes the command on the dataset.
+	 */
+	void executeCommand();
+	
+	/**
+	 * Give a description of the command as component to draw
+	 */
+	Component commandDescription();
+}
Index: src/org/openstreetmap/josm/command/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/command/DataSet.java	(revision 21)
+++ src/org/openstreetmap/josm/command/DataSet.java	(revision 21)
@@ -0,0 +1,289 @@
+package org.openstreetmap.josm.command;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.SelectionTracker;
+import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Track;
+
+/**
+ * DataSet is the data behind one window in the application. It can consist of only a few
+ * points up to the whole osm database. DataSet's can be merged together, split up into
+ * several different ones, saved, (up/down/disk)loaded etc.
+ *
+ * Note, that DataSet is not an osm-primitive, it is not within 
+ * org.openstreetmap.josm.data.osm and has no key association but a few
+ * members to store some information.
+ * 
+ * @author imi
+ */
+public class DataSet extends SelectionTracker implements Cloneable {
+
+	/**
+	 * All nodes goes here, even when included in other data (tracks etc).
+	 * This enables the instant conversion of the whole DataSet by iterating over
+	 * this data structure.
+	 */
+	public Collection<Node> nodes = new LinkedList<Node>();
+
+	/**
+	 * All pending line segments goes here. Pending line segments are those, that 
+	 * are in this list but are in no track.
+	 */
+	Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();
+
+	/**
+	 * All tracks (Streets etc.) in the DataSet. 
+	 * 
+	 * The nodes of the track segments of this track must be objects from 
+	 * the nodes list, however the track segments are stored only in the 
+	 * track list.
+	 */
+	Collection<Track> tracks = new LinkedList<Track>();
+
+	/**
+	 * Add the track to the tracklist.
+	 */
+	public void addTrack(Track t) {
+		tracks.add(t);
+	}
+	/**
+	 * Remove the track from the tracklist.
+	 */
+	public void removeTrack(Track t) {
+		t.destroy();
+		tracks.remove(t);
+	}
+	/**
+	 * Return a read-only collection of all tracks
+	 */
+	public Collection<Track> tracks() {
+		return Collections.unmodifiableCollection(tracks);
+	}
+
+	/**
+	 * Add a newly created line segment to the pending lines list.
+	 */
+	public void addPendingLineSegment(LineSegment ls) {
+		pendingLineSegments.add(ls);
+	}
+	/**
+	 * Remove a line segment from the pending lines list, because it has been
+	 * assigned to the track.
+	 * @param ls The line segment from the pending list
+	 * @param t The track, that will hold the line segment
+	 * @param end <code>true</code> to attach on the end. <code>false</code>
+	 * 		to attach on the beginning.
+	 */
+	public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) {
+		pendingLineSegments.remove(ls);
+		if (end)
+			t.add(ls);
+		else
+			t.addStart(ls);
+	}
+	/**
+	 * Delete the pending line segment without moving it anywhere.
+	 */
+	public void destroyPendingLineSegment(LineSegment ls) {
+		pendingLineSegments.remove(ls);
+		ls.destroy();
+	}
+	/**
+	 * Return an read-only iterator over all pending line segments.
+	 */
+	public Collection<LineSegment> pendingLineSegments() {
+		return Collections.unmodifiableCollection(pendingLineSegments);
+	}
+
+	/**
+	 * Return the bounds of this DataSet, depending on X/Y values.
+	 * The min of the return value is the upper left GeoPoint, the max the lower
+	 * down GeoPoint, regarding to the X/Y values.
+	 * 
+	 * Return null, if any point not converted yet or if there are no points at all.
+	 * 
+	 * @return Bounding coordinate structure.
+	 */
+	public Bounds getBoundsXY() {
+		if (nodes.isEmpty())
+			return null;
+
+		Node first = nodes.iterator().next();
+		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
+		for (Node w : nodes)
+		{
+			if (Double.isNaN(w.coor.x) || Double.isNaN(w.coor.y))
+				return null;
+			if (w.coor.x < b.min.x)
+				b.min.x = w.coor.x;
+			if (w.coor.y < b.min.y)
+				b.min.y = w.coor.y;
+			if (w.coor.x > b.max.x)
+				b.max.x = w.coor.x;
+			if (w.coor.y > b.max.y)
+				b.max.y = w.coor.y;
+		}
+		return b;
+	}
+
+	/**
+	 * Return the bounds of this DataSet, depending on lat/lon values.
+	 * The min of the return value is the upper left GeoPoint, the max the lower
+	 * down GeoPoint.
+	 * 
+	 * Return null, if any point does not have lat/lon or if there are no 
+	 * points at all.
+	 * 
+	 * @return Bounding coordinate structure.
+	 */
+	public Bounds getBoundsLatLon() {
+		if (nodes.isEmpty())
+			return null;
+
+		Node first = nodes.iterator().next();
+		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
+		for (Node w : nodes)
+		{
+			if (Double.isNaN(w.coor.lat) || Double.isNaN(w.coor.lon))
+				return null;
+			if (w.coor.lat < b.min.lat)
+				b.min.lat = w.coor.lat;
+			if (w.coor.lon < b.min.lon)
+				b.min.lon = w.coor.lon;
+			if (w.coor.lat > b.max.lat)
+				b.max.lat = w.coor.lat;
+			if (w.coor.lon > b.max.lon)
+				b.max.lon = w.coor.lon;
+		}
+		return b;
+	}
+
+	/**
+	 * Remove the selection of the whole dataset.
+	 */
+	public void clearSelection() {
+		clearSelection(nodes);
+		clearSelection(tracks);
+		for (Track t : tracks)
+			clearSelection(t.segments());
+	}
+
+	/**
+	 * Return a list of all selected objects. Even keys are returned.
+	 * @return List of all selected objects.
+	 */
+	@Override
+	public Collection<OsmPrimitive> getSelected() {
+		Collection<OsmPrimitive> sel = getSelected(nodes);
+		sel.addAll(getSelected(pendingLineSegments));
+		sel.addAll(getSelected(tracks));
+		for (Track t : tracks)
+			sel.addAll(getSelected(t.segments()));
+		return sel;
+	}
+
+	/**
+	 * Import the given dataset by merging all data with this dataset.
+	 * The objects imported are not cloned, so from now on, these data belong
+	 * to both datasets. So use mergeFrom only if you are about to abandon the
+	 * other dataset or this dataset.
+	 * 
+	 * @param ds	The DataSet to merge into this one.
+	 * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon
+	 * 		are merged together.
+	 */
+	public void mergeFrom(DataSet ds, boolean mergeEqualNodes) {
+		System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
+		if (mergeEqualNodes) {
+			Map<Node, Node> mergeMap = new HashMap<Node, Node>();
+			Set<Node> nodesToAdd = new HashSet<Node>();
+			for (Node n : nodes) {
+				for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) {
+					Node dsn = it.next();
+					if (n.coor.equalsLatLon(dsn.coor)) {
+						mergeMap.put(dsn, n);
+						n.mergeFrom(dsn);
+						it.remove();
+					} else {
+						nodesToAdd.add(dsn);
+					}
+				}
+			}
+			nodes.addAll(nodesToAdd);
+			for (Track t : ds.tracks) {
+				for (LineSegment ls : t.segments()) {
+					Node n = mergeMap.get(ls.getStart());
+					if (n != null)
+						ls.start = n;
+					n = mergeMap.get(ls.getEnd());
+					if (n != null)
+						ls.end = n;
+				}
+			}
+			tracks.addAll(ds.tracks);
+			for (LineSegment ls : ds.pendingLineSegments) {
+				Node n = mergeMap.get(ls.getStart());
+				if (n != null)
+					ls.start = n;
+				n = mergeMap.get(ls.getEnd());
+				if (n != null)
+					ls.end = n;
+			}
+			pendingLineSegments.addAll(ds.pendingLineSegments);
+		} else {
+			nodes.addAll(ds.nodes);
+			tracks.addAll(ds.tracks);
+			pendingLineSegments.addAll(ds.pendingLineSegments);
+		}
+		System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
+	}
+
+	/**
+	 * Remove the selection from every value in the collection.
+	 * @param list The collection to remove the selection from.
+	 */
+	private void clearSelection(Collection<? extends OsmPrimitive> list) {
+		if (list == null)
+			return;
+		for (OsmPrimitive osm : list) {
+			osm.setSelected(false, this);
+			if (osm.keys != null)
+				clearSelection(osm.keys.keySet());
+		}
+	}
+
+	/**
+	 * Return all selected items in the collection.
+	 * @param list The collection from which the selected items are returned.
+	 */
+	private Collection<OsmPrimitive> getSelected(Collection<? extends OsmPrimitive> list) {
+		Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
+		if (list == null)
+			return sel;
+		for (OsmPrimitive osm : list) {
+			if (osm.isSelected())
+				sel.add(osm);
+			if (osm.keys != null)
+				sel.addAll(getSelected(osm.keys.keySet()));
+		}
+		return sel;
+	}
+
+
+	@Override
+	public DataSet clone() {
+		try {return (DataSet)super.clone();} catch (CloneNotSupportedException e) {}
+		return null;
+	}
+}
Index: src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/MoveCommand.java	(revision 21)
+++ src/org/openstreetmap/josm/command/MoveCommand.java	(revision 21)
@@ -0,0 +1,65 @@
+package org.openstreetmap.josm.command;
+
+import java.awt.Component;
+import java.util.Collection;
+import java.util.HashSet;
+
+import javax.swing.JLabel;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+/**
+ * MoveCommand moves a set of OsmPrimitives along the map. It can be moved again
+ * to collect several MoveCommands into one command.
+ * 
+ * @author imi
+ */
+public class MoveCommand implements Command {
+
+	/**
+	 * The objects that should be moved.
+	 */
+	private Collection<OsmPrimitive> objects;
+	/**
+	 * x difference movement. Coordinates are in northern/eastern 
+	 */
+	private double x;
+	/**
+	 * y difference movement. Coordinates are in northern/eastern 
+	 */
+	private double y;
+
+	/**
+	 * Create a MoveCommand and assign the initial object set and movement vector.
+	 */
+	public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) {
+		this.objects = objects;
+		this.x = x;
+		this.y = y;
+	}
+
+	/**
+	 * Move the objects additional to the current movement.
+	 */
+	public void move(double x, double y) {
+		this.x += x;
+		this.y += y;
+	}
+
+	public void executeCommand() {
+		Collection<Node> movingNodes = new HashSet<Node>();
+		for (OsmPrimitive osm : objects)
+			movingNodes.addAll(osm.getAllNodes());
+		for (Node n : movingNodes) {
+			n.coor.x += x;
+			n.coor.y += y;
+		}
+	}
+
+	public Component commandDescription() {
+		String xstr = Math.abs(x) + (x < 0 ? "W" : "E");
+		String ystr = Math.abs(y) + (y < 0 ? "S" : "N");
+		return new JLabel("Move "+objects.size()+" primitives "+xstr+" "+ystr);
+	}
+}
Index: src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 20)
+++ 	(revision )
@@ -1,284 +1,0 @@
-package org.openstreetmap.josm.data.osm;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.SelectionTracker;
-
-/**
- * DataSet is the data behind one window in the application. It can consist of only a few
- * points up to the whole osm database. DataSet's can be merged together, split up into
- * several different ones, saved, (up/down/disk)loaded etc.
- *
- * Note, that DataSet is not an osm-primitive, so it has no key association but a few
- * members to store some information.
- * 
- * @author imi
- */
-public class DataSet extends SelectionTracker implements Cloneable {
-
-	/**
-	 * All nodes goes here, even when included in other data (tracks etc).
-	 * This enables the instant conversion of the whole DataSet by iterating over
-	 * this data structure.
-	 */
-	public Collection<Node> nodes = new LinkedList<Node>();
-
-	/**
-	 * All pending line segments goes here. Pending line segments are those, that 
-	 * are in this list but are in no track.
-	 */
-	private Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();
-
-	/**
-	 * All tracks (Streets etc.) in the DataSet. 
-	 * 
-	 * The nodes of the track segments of this track must be objects from 
-	 * the nodes list, however the track segments are stored only in the 
-	 * track list.
-	 */
-	private Collection<Track> tracks = new LinkedList<Track>();
-
-	/**
-	 * Add the track to the tracklist.
-	 */
-	public void addTrack(Track t) {
-		tracks.add(t);
-	}
-	/**
-	 * Remove the track from the tracklist.
-	 */
-	public void removeTrack(Track t) {
-		t.destroy();
-		tracks.remove(t);
-	}
-	/**
-	 * Return a read-only collection of all tracks
-	 */
-	public Collection<Track> tracks() {
-		return Collections.unmodifiableCollection(tracks);
-	}
-
-	/**
-	 * Add a newly created line segment to the pending lines list.
-	 */
-	public void addPendingLineSegment(LineSegment ls) {
-		pendingLineSegments.add(ls);
-	}
-	/**
-	 * Remove a line segment from the pending lines list, because it has been
-	 * assigned to the track.
-	 * @param ls The line segment from the pending list
-	 * @param t The track, that will hold the line segment
-	 * @param end <code>true</code> to attach on the end. <code>false</code>
-	 * 		to attach on the beginning.
-	 */
-	public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) {
-		pendingLineSegments.remove(ls);
-		if (end)
-			t.add(ls);
-		else
-			t.addStart(ls);
-	}
-	/**
-	 * Delete the pending line segment without moving it anywhere.
-	 */
-	public void destroyPendingLineSegment(LineSegment ls) {
-		pendingLineSegments.remove(ls);
-		ls.destroy();
-	}
-	/**
-	 * Return an read-only iterator over all pending line segments.
-	 */
-	public Collection<LineSegment> pendingLineSegments() {
-		return Collections.unmodifiableCollection(pendingLineSegments);
-	}
-
-	/**
-	 * Return the bounds of this DataSet, depending on X/Y values.
-	 * The min of the return value is the upper left GeoPoint, the max the lower
-	 * down GeoPoint, regarding to the X/Y values.
-	 * 
-	 * Return null, if any point not converted yet or if there are no points at all.
-	 * 
-	 * @return Bounding coordinate structure.
-	 */
-	public Bounds getBoundsXY() {
-		if (nodes.isEmpty())
-			return null;
-
-		Node first = nodes.iterator().next();
-		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
-		for (Node w : nodes)
-		{
-			if (Double.isNaN(w.coor.x) || Double.isNaN(w.coor.y))
-				return null;
-			if (w.coor.x < b.min.x)
-				b.min.x = w.coor.x;
-			if (w.coor.y < b.min.y)
-				b.min.y = w.coor.y;
-			if (w.coor.x > b.max.x)
-				b.max.x = w.coor.x;
-			if (w.coor.y > b.max.y)
-				b.max.y = w.coor.y;
-		}
-		return b;
-	}
-
-	/**
-	 * Return the bounds of this DataSet, depending on lat/lon values.
-	 * The min of the return value is the upper left GeoPoint, the max the lower
-	 * down GeoPoint.
-	 * 
-	 * Return null, if any point does not have lat/lon or if there are no 
-	 * points at all.
-	 * 
-	 * @return Bounding coordinate structure.
-	 */
-	public Bounds getBoundsLatLon() {
-		if (nodes.isEmpty())
-			return null;
-
-		Node first = nodes.iterator().next();
-		Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
-		for (Node w : nodes)
-		{
-			if (Double.isNaN(w.coor.lat) || Double.isNaN(w.coor.lon))
-				return null;
-			if (w.coor.lat < b.min.lat)
-				b.min.lat = w.coor.lat;
-			if (w.coor.lon < b.min.lon)
-				b.min.lon = w.coor.lon;
-			if (w.coor.lat > b.max.lat)
-				b.max.lat = w.coor.lat;
-			if (w.coor.lon > b.max.lon)
-				b.max.lon = w.coor.lon;
-		}
-		return b;
-	}
-
-	/**
-	 * Remove the selection of the whole dataset.
-	 */
-	public void clearSelection() {
-		clearSelection(nodes);
-		clearSelection(tracks);
-		for (Track t : tracks)
-			clearSelection(t.segments());
-	}
-
-	/**
-	 * Return a list of all selected objects. Even keys are returned.
-	 * @return List of all selected objects.
-	 */
-	@Override
-	public Collection<OsmPrimitive> getSelected() {
-		Collection<OsmPrimitive> sel = getSelected(nodes);
-		sel.addAll(getSelected(pendingLineSegments));
-		sel.addAll(getSelected(tracks));
-		for (Track t : tracks)
-			sel.addAll(getSelected(t.segments()));
-		return sel;
-	}
-
-	/**
-	 * Import the given dataset by merging all data with this dataset.
-	 * The objects imported are not cloned, so from now on, these data belong
-	 * to both datasets. So use mergeFrom only if you are about to abandon the
-	 * other dataset or this dataset.
-	 * 
-	 * @param ds	The DataSet to merge into this one.
-	 * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon
-	 * 		are merged together.
-	 */
-	public void mergeFrom(DataSet ds, boolean mergeEqualNodes) {
-		System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
-		if (mergeEqualNodes) {
-			Map<Node, Node> mergeMap = new HashMap<Node, Node>();
-			Set<Node> nodesToAdd = new HashSet<Node>();
-			for (Node n : nodes) {
-				for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) {
-					Node dsn = it.next();
-					if (n.coor.equalsLatLon(dsn.coor)) {
-						mergeMap.put(dsn, n);
-						n.mergeFrom(dsn);
-						it.remove();
-					} else {
-						nodesToAdd.add(dsn);
-					}
-				}
-			}
-			nodes.addAll(nodesToAdd);
-			for (Track t : ds.tracks) {
-				for (LineSegment ls : t.segments()) {
-					Node n = mergeMap.get(ls.getStart());
-					if (n != null)
-						ls.start = n;
-					n = mergeMap.get(ls.getEnd());
-					if (n != null)
-						ls.end = n;
-				}
-			}
-			tracks.addAll(ds.tracks);
-			for (LineSegment ls : ds.pendingLineSegments) {
-				Node n = mergeMap.get(ls.getStart());
-				if (n != null)
-					ls.start = n;
-				n = mergeMap.get(ls.getEnd());
-				if (n != null)
-					ls.end = n;
-			}
-			pendingLineSegments.addAll(ds.pendingLineSegments);
-		} else {
-			nodes.addAll(ds.nodes);
-			tracks.addAll(ds.tracks);
-			pendingLineSegments.addAll(ds.pendingLineSegments);
-		}
-		System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
-	}
-
-	/**
-	 * Remove the selection from every value in the collection.
-	 * @param list The collection to remove the selection from.
-	 */
-	private void clearSelection(Collection<? extends OsmPrimitive> list) {
-		if (list == null)
-			return;
-		for (OsmPrimitive osm : list) {
-			osm.setSelected(false, this);
-			if (osm.keys != null)
-				clearSelection(osm.keys.keySet());
-		}
-	}
-
-	/**
-	 * Return all selected items in the collection.
-	 * @param list The collection from which the selected items are returned.
-	 */
-	private Collection<OsmPrimitive> getSelected(Collection<? extends OsmPrimitive> list) {
-		Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
-		if (list == null)
-			return sel;
-		for (OsmPrimitive osm : list) {
-			if (osm.isSelected())
-				sel.add(osm);
-			if (osm.keys != null)
-				sel.addAll(getSelected(osm.keys.keySet()));
-		}
-		return sel;
-	}
-
-
-	@Override
-	public DataSet clone() {
-		try {return (DataSet)super.clone();} catch (CloneNotSupportedException e) {}
-		return null;
-	}
-}
Index: src/org/openstreetmap/josm/data/osm/LineSegment.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/LineSegment.java	(revision 20)
+++ src/org/openstreetmap/josm/data/osm/LineSegment.java	(revision 21)
@@ -18,10 +18,10 @@
 	 * The starting node of the line segment
 	 */
-	Node start;
+	public Node start;
 	
 	/**
 	 * The ending node of the line segment
 	 */
-	Node end;
+	public Node end;
 
 	/**
@@ -69,5 +69,5 @@
 	 * The LineSegment is going to be destroyed. Unlink all back references.
 	 */
-	void destroy() {
+	public void destroy() {
 		start.parentSegment.remove(this);
 		end.parentSegment.remove(this);
Index: src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 20)
+++ src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 21)
@@ -4,4 +4,5 @@
 import java.util.Map;
 
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
Index: src/org/openstreetmap/josm/data/osm/Track.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/Track.java	(revision 20)
+++ src/org/openstreetmap/josm/data/osm/Track.java	(revision 21)
@@ -80,5 +80,5 @@
 	 * The track is going to be destroyed. Unlink all back references.
 	 */
-	void destroy() {
+	public void destroy() {
 		for (LineSegment ls : segments) {
 			ls.parent.remove(this);
Index: src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 20)
+++ src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 21)
@@ -19,5 +19,5 @@
  * @author imi
  */
-public class SelectionComponentVisitor extends Visitor {
+public class SelectionComponentVisitor implements Visitor {
 
 	/**
@@ -34,5 +34,4 @@
 	 * A key icon and the name of the key.
 	 */
-	@Override
 	public void visit(Key k) {
 		name = k.name;
@@ -45,5 +44,4 @@
 	 * "(x1,y1) -> (x2,y2)" is displayed with the nodes coordinates.
 	 */
-	@Override
 	public void visit(LineSegment ls) {
 		String name = getName(ls.keys);
@@ -59,5 +57,4 @@
 	 * is displayed.
 	 */
-	@Override
 	public void visit(Node n) {
 		String name = getName(n.keys);
@@ -73,5 +70,4 @@
 	 * is displayed with x beeing the number of nodes in the track.
 	 */
-	@Override
 	public void visit(Track t) {
 		String name = getName(t.keys);
Index: src/org/openstreetmap/josm/data/osm/visitor/Visitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 20)
+++ src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 21)
@@ -12,8 +12,8 @@
  * @author imi
  */
-abstract public class Visitor {
-	public void visit(Node n) {}
-	public void visit(LineSegment ls) {}
-	public void visit(Track t) {}
-	public void visit(Key k) {}
+public interface Visitor {
+	void visit(Node n);
+	void visit(LineSegment ls);
+	void visit(Track t);
+	void visit(Key k);
 }
Index: src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Projection.java	(revision 20)
+++ src/org/openstreetmap/josm/data/projection/Projection.java	(revision 21)
@@ -8,6 +8,6 @@
 import javax.swing.event.ChangeListener;
 
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
 
 /**
Index: src/org/openstreetmap/josm/data/projection/UTM.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/UTM.java	(revision 20)
+++ src/org/openstreetmap/josm/data/projection/UTM.java	(revision 21)
@@ -15,9 +15,9 @@
 import javax.swing.SpinnerNumberModel;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.GBC;
-import org.openstreetmap.josm.gui.Main;
 
 /**
Index: src/org/openstreetmap/josm/gui/BookmarkList.java
===================================================================
--- src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 21)
@@ -16,4 +16,5 @@
 import javax.swing.JOptionPane;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
 
Index: src/org/openstreetmap/josm/gui/ImageProvider.java
===================================================================
--- src/org/openstreetmap/josm/gui/ImageProvider.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/ImageProvider.java	(revision 21)
@@ -12,4 +12,6 @@
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.Main;
 
 /**
Index: src/org/openstreetmap/josm/gui/Main.java
===================================================================
--- src/org/openstreetmap/josm/gui/Main.java	(revision 20)
+++ 	(revision )
@@ -1,193 +1,0 @@
-// Licence: GPL
-package org.openstreetmap.josm.gui;
-
-import java.awt.BorderLayout;
-import java.awt.Container;
-
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JSeparator;
-import javax.swing.JToolBar;
-import javax.swing.UIManager;
-
-import org.openstreetmap.josm.actions.AboutAction;
-import org.openstreetmap.josm.actions.ExitAction;
-import org.openstreetmap.josm.actions.OpenGpxAction;
-import org.openstreetmap.josm.actions.OpenOsmServerAction;
-import org.openstreetmap.josm.actions.PreferencesAction;
-import org.openstreetmap.josm.actions.SaveGpxAction;
-import org.openstreetmap.josm.data.Preferences;
-import org.openstreetmap.josm.data.Preferences.PreferencesException;
-
-/**
- * Main window class consisting of the mainframe MDI application.
- *  
- * @author imi
- */
-public class Main extends JFrame {
-
-	/**
-	 * Global application window. Use this as JOPtionPane-parent to center on application.
-	 */
-	public static Main main;
-
-	/**
-	 * Global application preferences
-	 */
-	public final static Preferences pref = new Preferences();
-	
-	/**
-	 * The main panel.
-	 */
-	private Container panel;
-	/**
-	 * The name of the current loaded mapFrame
-	 */
-	private String name;
-	/**
-	 * The mapFrame currently loaded.
-	 */
-	private MapFrame mapFrame;
-	
-	/**
-	 * Construct an main frame, ready sized and operating. Does not 
-	 * display the frame.
-	 */
-	public Main() {
-		super("Java Open Street Map - Editor");
-		setLayout(new BorderLayout());
-		panel = new JPanel(new BorderLayout());
-		getContentPane().add(panel, BorderLayout.CENTER);
-		setSize(1000,740); // some strange default size
-		setExtendedState(MAXIMIZED_BOTH); // some platform are able to maximize
-		
-		// creating actions
-		OpenOsmServerAction openServerAction = new OpenOsmServerAction();
-		OpenGpxAction openGpxAction = new OpenGpxAction();
-		SaveGpxAction saveGpxAction = new SaveGpxAction();
-		ExitAction exitAction = new ExitAction();
-		PreferencesAction preferencesAction = new PreferencesAction();
-		AboutAction aboutAction = new AboutAction();
-
-		// creating menu
-		JMenuBar mainMenu = new JMenuBar();
-		setJMenuBar(mainMenu);
-
-		JMenu fileMenu = new JMenu("Files");
-		fileMenu.setMnemonic('F');
-		fileMenu.add(openGpxAction);
-		fileMenu.add(saveGpxAction);
-		fileMenu.addSeparator();
-		fileMenu.add(exitAction);
-		mainMenu.add(fileMenu);
-		
-		JMenu connectionMenu = new JMenu("Connection");
-		connectionMenu.setMnemonic('C');
-		connectionMenu.add(openServerAction);
-		mainMenu.add(connectionMenu);
-		
-		JMenu editMenu = new JMenu("Edit");
-		editMenu.setMnemonic('E');
-		editMenu.add(preferencesAction);
-		mainMenu.add(editMenu);
-		
-		mainMenu.add(new JSeparator());
-		JMenu helpMenu = new JMenu("Help");
-		helpMenu.setMnemonic('H');
-		helpMenu.add(aboutAction);
-		mainMenu.add(helpMenu);
-
-		// creating toolbar
-		JToolBar toolBar = new JToolBar();
-		toolBar.setFloatable(false);
-		toolBar.add(openServerAction);
-		toolBar.add(openGpxAction);
-		toolBar.add(saveGpxAction);
-		toolBar.addSeparator();
-		toolBar.add(preferencesAction);
-		
-		getContentPane().add(toolBar, BorderLayout.NORTH);
-	}
-
-	/**
-	 * Main application Startup
-	 * @param args	No parameters accepted.
-	 */
-	public static void main(String[] args) {
-		setupUiDefaults();
-		
-		// load preferences
-		String errMsg = null;
-		try {
-			pref.load();
-		} catch (PreferencesException e1) {
-			e1.printStackTrace();
-			errMsg = "Preferences could not be loaded. Write default preference file to '"+Preferences.getPreferencesDir()+"preferences'.";
-			try {
-				pref.save();
-			} catch (PreferencesException e) {
-				e.printStackTrace();
-				errMsg = "Preferences could not be loaded. Reverting to default.";
-			}
-		}
-		if (errMsg != null)
-			JOptionPane.showMessageDialog(null, errMsg);
-		
-		try {
-			UIManager.setLookAndFeel(pref.laf.getClassName());
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		
-		main = new Main();
-		main.setDefaultCloseOperation(EXIT_ON_CLOSE);
-		main.setVisible(true);
-	}
-
-
-	/**
-	 * Set the main's mapframe. If a changed old mapFrame is already set, 
-	 * ask the user whether he want to save, discard or abort. If the user
-	 * aborts, nothing happens. 
-	 */
-	public void setMapFrame(String name, MapFrame mapFrame) {
-		//TODO: Check for changes and ask user
-		this.name = name;
-		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 name.
-	 */
-	public String getNameOfLoadedMapFrame() {
-		return name;
-	}
-	/**
-	 * @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"));
-	}
-}
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 21)
@@ -17,7 +17,8 @@
 import javax.swing.event.ChangeListener;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
@@ -86,5 +87,5 @@
 	 */
 	public MapView(Layer layer) {
-		if (layer.getDataSet() == null)
+		if (layer.dataSet == null)
 			throw new IllegalArgumentException("Initial layer must have a dataset.");
 
@@ -114,13 +115,11 @@
 		layers.add(0,layer);
 
-		DataSet ds = layer.getDataSet();
-
-		if (ds != null) {
+		if (layer.dataSet != null) {
 			// initialize the projection if it was the first layer
 			if (layers.size() == 1)
-				Main.pref.getProjection().init(ds);
+				Main.pref.getProjection().init(layer.dataSet);
 			
 			// initialize the dataset in the new layer
-			for (Node n : ds.nodes)
+			for (Node n : layer.dataSet.nodes)
 				Main.pref.getProjection().latlon2xy(n.coor);
 		}
@@ -320,5 +319,5 @@
 		for (int i = layers.size()-1; i >= 0; --i) {
 			Layer l = layers.get(i);
-			if (l.isVisible())
+			if (l.visible)
 				l.paint(g, this);
 		}
@@ -333,5 +332,5 @@
 		Projection p = Main.pref.getProjection();
 		for (Layer l : layers) {
-			DataSet ds = l.getDataSet();
+			DataSet ds = l.dataSet;
 			if (ds != null)
 				for (Node n : ds.nodes)
@@ -382,11 +381,9 @@
 	 */
 	public DataSet getActiveDataSet() {
-		if (activeLayer.getDataSet() != null)
-			return activeLayer.getDataSet();
-		for (Layer l : layers) {
-			DataSet ds = l.getDataSet();
-			if (ds != null)
-				return ds;
-		}
+		if (activeLayer.dataSet != null)
+			return activeLayer.dataSet;
+		for (Layer l : layers)
+			if (l.dataSet != null)
+				return l.dataSet;
 		throw new IllegalStateException("No dataset found.");
 	}
@@ -486,6 +483,6 @@
 		activeLayer = layer;
 		if (old != layer) {
-			if (old != null && old.getDataSet() != null)
-				old.getDataSet().clearSelection();
+			if (old != null && old.dataSet != null)
+				old.dataSet.clearSelection();
 			for (LayerChangeListener l : listeners)
 				l.activeLayerChange(old, layer);
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 21)
@@ -28,4 +28,5 @@
 import javax.swing.UIManager.LookAndFeelInfo;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.Preferences.PreferencesException;
Index: src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 21)
@@ -15,5 +15,5 @@
 import java.util.LinkedList;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
Index: src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 21)
@@ -23,7 +23,7 @@
 import javax.swing.event.ListSelectionListener;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -84,11 +84,11 @@
 				Layer layer = (Layer)value;
 				JLabel label = (JLabel)super.getListCellRendererComponent(list, 
-						layer.getName(), index, isSelected, cellHasFocus);
+						layer.name, index, isSelected, cellHasFocus);
 				Icon icon = layer.getIcon();
-				if (!layer.isVisible())
+				if (!layer.visible)
 					icon = ImageProvider.overlay(icon, invisible, ImageProvider.OverlayPosition.SOUTHEAST);
 				label.setIcon(icon);
 				
-				DataSet ds = layer.getDataSet();
+				DataSet ds = layer.dataSet;
 				if (ds != null) {
 					label.setToolTipText(ds.nodes.size()+" nodes, "+
@@ -148,5 +148,5 @@
 			public void actionPerformed(ActionEvent e) {
 				Layer l = (Layer)layers.getSelectedValue();
-				l.setVisible(!l.isVisible());
+				l.visible = !l.visible;
 				mapView.repaint();
 				layers.repaint();
@@ -175,7 +175,7 @@
 				public void actionPerformed(ActionEvent e) {
 					Layer lFrom = (Layer)layers.getSelectedValue();
-					DataSet dsFrom = lFrom.getDataSet();
+					DataSet dsFrom = lFrom.dataSet;
 					Layer lTo = (Layer)model.get(layers.getSelectedIndex()+1);
-					DataSet dsTo = lTo.getDataSet();
+					DataSet dsTo = lTo.dataSet;
 					dsTo.mergeFrom(dsFrom, Main.pref.mergeNodes);
 					layers.setSelectedValue(lTo, true);
@@ -198,6 +198,6 @@
 		boolean enable = model.getSize() > 1;
 		enable = enable && sel < model.getSize()-1;
-		enable = enable && l.getDataSet() != null;
-		enable = enable && ((Layer)model.get(sel+1)).getDataSet() != null;
+		enable = enable && l.dataSet != null;
+		enable = enable && ((Layer)model.get(sel+1)).dataSet != null;
 		enable = enable && l.isEditable() == ((Layer)model.get(sel+1)).isEditable();
 		mergeButton.setEnabled(enable);
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 21)
@@ -8,5 +8,5 @@
 import javax.swing.border.Border;
 
-import org.openstreetmap.josm.gui.Main;
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 21)
@@ -16,10 +16,10 @@
 import javax.swing.ListSelectionModel;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.SelectionComponentVisitor;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
@@ -127,8 +127,8 @@
 
 	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
-		DataSet ds = oldLayer.getDataSet();
+		DataSet ds = oldLayer.dataSet;
 		if (ds != null)
 			ds.removeSelectionChangedListener(this);
-		ds = newLayer.getDataSet();
+		ds = newLayer.dataSet;
 		if (ds != null)
 			ds.addSelectionChangedListener(this);
Index: src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 21)
@@ -13,6 +13,6 @@
 import javax.swing.KeyStroke;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.ImageProvider;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 
Index: src/org/openstreetmap/josm/gui/engine/RawGpsEngine.java
===================================================================
--- src/org/openstreetmap/josm/gui/engine/RawGpsEngine.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/engine/RawGpsEngine.java	(revision 21)
@@ -7,8 +7,8 @@
 import java.beans.PropertyChangeListener;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.LineSegment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Main;
 import org.openstreetmap.josm.gui.MapView;
 
Index: src/org/openstreetmap/josm/gui/layer/DataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/DataLayer.java	(revision 20)
+++ 	(revision )
@@ -1,82 +1,0 @@
-package org.openstreetmap.josm.gui.layer;
-
-import java.awt.Graphics;
-
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.engine.Engine;
-
-/**
- * Base class for all layer that depends on some DataSet.
- * The dataset is final and so can not be changed later.
- * 
- * @author imi
- */
-public abstract class DataLayer implements Layer {
-
-	/**
-	 * The dataSet this layer operates on.
-	 */
-	protected final DataSet dataSet;
-	/**
-	 * The engine used to draw the data.
-	 */
-	protected final Engine engine;
-	/**
-	 * The name of this layer.
-	 */
-	private final String name;
-	/**
-	 * The visibility state of the layer.
-	 */
-	private boolean visible = true;
-
-	/**
-	 * Construct the datalayer and fill the dataset.
-	 * @param name The name of this layer. Returned by getName.
-	 */
-	public DataLayer(DataSet dataSet, Engine engine, String name) {
-		if (dataSet == null || engine == null || name == null)
-			throw new NullPointerException();
-		this.name = name;
-		this.dataSet = dataSet;
-		this.engine = engine;
-	}
-
-	/**
-	 * Paint the dataset using the engine set.
-	 * @param mv The object that can translate GeoPoints to screen coordinates.
-	 */
-	public void paint(Graphics g, MapView mv) {
-		engine.init(g, mv);
-
-		for (Track t : dataSet.tracks())
-			engine.drawTrack(t);
-		for (LineSegment ls : dataSet.pendingLineSegments())
-			engine.drawPendingLineSegment(ls);
-		for (Node n : dataSet.nodes)
-			engine.drawNode(n);
-	}
-
-	/**
-	 * Return the data set behind this data layer.
-	 */
-	public DataSet getDataSet() {
-		return dataSet;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public boolean isVisible() {
-		return visible;
-	}
-
-	public void setVisible(boolean visible) {
-		this.visible = visible;
-	}
-}
Index: src/org/openstreetmap/josm/gui/layer/Layer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 21)
@@ -5,6 +5,10 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
+import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Track;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.engine.Engine;
 
 /**
@@ -23,14 +27,50 @@
  * @author imi
  */
-public interface Layer {
+abstract public class Layer {
 
 	/**
-	 * Draw the layer on the given Graphics. The state of the graphics object
-	 * can be changed (drawing color..)
-	 *
-	 * @param g The graphics to draw the layer on.
-	 * @param mv The MapView with information about the screen layout. 
+	 * The visibility state of the layer.
 	 */
-	void paint(Graphics g, MapView mv);
+	public boolean visible = true;
+	/**
+	 * The dataSet this layer operates on, if any. Not all layer may have a
+	 * dataset associated.
+	 */
+	public final DataSet dataSet;
+	/**
+	 * The name of this layer.
+	 */
+	public final String name;
+	/**
+	 * The engine used to draw the data.
+	 */
+	private final Engine engine;
+	
+	/**
+	 * Create the layer and fill in the necessary components.
+	 * @param dataSet The DataSet, this layer operates on. Can be <code>null</code>.
+	 */
+	public Layer(DataSet dataSet, Engine engine, String name) {
+		if (engine == null || name == null)
+			throw new NullPointerException();
+		this.dataSet = dataSet;
+		this.name = name;
+		this.engine = engine;
+	}
+
+	/**
+	 * Paint the dataset using the engine set.
+	 * @param mv The object that can translate GeoPoints to screen coordinates.
+	 */
+	public final void paint(Graphics g, MapView mv) {
+		engine.init(g, mv);
+
+		for (Track t : dataSet.tracks())
+			engine.drawTrack(t);
+		for (LineSegment ls : dataSet.pendingLineSegments())
+			engine.drawPendingLineSegment(ls);
+		for (Node n : dataSet.nodes)
+			engine.drawNode(n);
+	}
 
 	/**
@@ -38,31 +78,11 @@
 	 * be larger than 64 pixel in any dimension.
 	 */
-	Icon getIcon();
+	abstract public Icon getIcon();
 
-	/**
-	 * Provide a human readable name (may be in html format).
-	 */
-	String getName();
-	
-	/**
-	 * If the layer has a dataset it can provide, return it here.
-	 * @return The dataset for this layer or <code>null</code> if no dataset
-	 * 		is available.
-	 */
-	DataSet getDataSet();
-	
 	/**
 	 * @return <code>true</code>, if the map data can be edited.
 	 */
-	boolean isEditable();
-
-	/**
-	 * @return <code>true</code>, if the layer is visible
-	 */
-	boolean isVisible();
-	
-	/**
-	 * Set the visibility state of the layer.
-	 */
-	void setVisible(boolean visible);
+	public boolean isEditable() {
+		return false;
+	}
 }
Index: src/org/openstreetmap/josm/gui/layer/LayerFactory.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/LayerFactory.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/layer/LayerFactory.java	(revision 21)
@@ -1,5 +1,5 @@
 package org.openstreetmap.josm.gui.layer;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 
 /**
Index: src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 21)
@@ -3,5 +3,5 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.engine.SimpleEngine;
@@ -14,5 +14,5 @@
  * @author imi
  */
-public class OsmDataLayer extends DataLayer {
+public class OsmDataLayer extends Layer {
 
 	private static Icon icon;
@@ -29,4 +29,5 @@
 	 * 		updated by a background thread to not disturb the running programm.
 	 */
+	@Override
 	public Icon getIcon() {
 		if (icon == null)
@@ -35,4 +36,5 @@
 	}
 
+	@Override
 	public boolean isEditable() {
 		return true;
Index: src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 20)
+++ src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 21)
@@ -3,5 +3,5 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.gui.ImageProvider;
 import org.openstreetmap.josm.gui.engine.RawGpsEngine;
@@ -13,5 +13,5 @@
  * @author imi
  */
-public class RawGpsDataLayer extends DataLayer {
+public class RawGpsDataLayer extends Layer {
 
 	private static Icon icon;
@@ -24,4 +24,5 @@
 	 * Return a static icon.
 	 */
+	@Override
 	public Icon getIcon() {
 		if (icon == null)
@@ -29,7 +30,3 @@
 		return icon;
 	}
-
-	public boolean isEditable() {
-		return false;
-	}
 }
Index: src/org/openstreetmap/josm/io/DataReader.java
===================================================================
--- src/org/openstreetmap/josm/io/DataReader.java	(revision 20)
+++ src/org/openstreetmap/josm/io/DataReader.java	(revision 21)
@@ -1,5 +1,5 @@
 package org.openstreetmap.josm.io;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 
 /**
Index: src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxReader.java	(revision 20)
+++ src/org/openstreetmap/josm/io/GpxReader.java	(revision 21)
@@ -9,6 +9,7 @@
 import org.jdom.Namespace;
 import org.jdom.input.SAXBuilder;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.GeoPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Key;
 import org.openstreetmap.josm.data.osm.LineSegment;
@@ -16,5 +17,4 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Track;
-import org.openstreetmap.josm.gui.Main;
 
 /**
Index: src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxWriter.java	(revision 20)
+++ src/org/openstreetmap/josm/io/GpxWriter.java	(revision 21)
@@ -14,5 +14,5 @@
 import org.jdom.output.Format;
 import org.jdom.output.XMLOutputter;
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.data.osm.Key;
 import org.openstreetmap.josm.data.osm.LineSegment;
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 20)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 21)
@@ -17,7 +17,7 @@
 import javax.swing.JTextField;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.DataSet;
 import org.openstreetmap.josm.gui.GBC;
-import org.openstreetmap.josm.gui.Main;
 
 /**
