Index: /.classpath
===================================================================
--- /.classpath	(revision 102)
+++ /.classpath	(revision 103)
@@ -4,5 +4,4 @@
 	<classpathentry including="images/" kind="src" path=""/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="lib" path="lib/jdom.jar"/>
 	<classpathentry sourcepath="JUNIT_SRC_HOME/junitsrc.zip" kind="var" path="JUNIT_HOME/junit.jar"/>
 	<classpathentry kind="lib" path="lib/MinML2.jar"/>
Index: /CONTRIBUTION
===================================================================
--- /CONTRIBUTION	(revision 102)
+++ /CONTRIBUTION	(revision 103)
@@ -1,6 +1,4 @@
-One XML Parser is JDOM 1.0 which comes from www.jdom.org and
-is licensed under "JDOM license", a modified Apache License
-with Aknowledgement removed. The other XML Parser is MinML2
-from http://www.wilson.co.uk/xml/minml2.htm. The license is 
+The XML Parser is MinML2 from 
+http://www.wilson.co.uk/xml/minml2.htm. The license is 
 attached below.
 
Index: /src/org/openstreetmap/josm/Main.java
===================================================================
--- /src/org/openstreetmap/josm/Main.java	(revision 102)
+++ /src/org/openstreetmap/josm/Main.java	(revision 103)
@@ -94,5 +94,7 @@
 			panel.setVisible(true);
 			map.mapView.addLayerChangeListener(new LayerChangeListener(){
-				public void activeLayerChange(final Layer oldLayer, final Layer newLayer) {}
+				public void activeLayerChange(final Layer oldLayer, final Layer newLayer) {
+					setLayerMenu(newLayer.getMenuEntries());
+				}
 				public void layerAdded(final Layer newLayer) {
 					if (newLayer instanceof OsmDataLayer)
@@ -102,4 +104,6 @@
 					if (oldLayer instanceof OsmDataLayer)
 						Main.main.editLayer().listenerCommands.add(redoUndoListener);
+					if (map.mapView.getAllLayers().isEmpty())
+						setLayerMenu(null);
 				}
 			});
@@ -110,4 +114,18 @@
 	}
 
+	/**
+	 * Set the layer menu (changed when active layer changes).
+	 */
+	public final void setLayerMenu(Component[] entries) {
+		if (entries == null || entries.length == 0)
+			layerMenu.setVisible(false);
+		else {
+			layerMenu.removeAll();
+			for (Component c : entries)
+				layerMenu.add(c);
+			layerMenu.setVisible(true);
+		}
+	}
+	
 	/**
 	 * Remove the specified layer from the map. If it is the last layer, remove the map as well.
@@ -141,11 +159,15 @@
 
 
-		final JMenu layerMenu = new JMenu("Layer");
+		final JMenu connectionMenu = new JMenu("Connection");
+		connectionMenu.setMnemonic('C');
+		connectionMenu.add(downloadAction);
+		connectionMenu.add(uploadAction);
+		mainMenu.add(connectionMenu);
+
+		layerMenu = new JMenu("Layer");
 		layerMenu.setMnemonic('L');
-		layerMenu.add(downloadAction);
-		layerMenu.add(uploadAction);
-		layerMenu.addSeparator();
 		mainMenu.add(layerMenu);
-
+		layerMenu.setVisible(false);
+		
 		final JMenu editMenu = new JMenu("Edit");
 		editMenu.setMnemonic('E');
@@ -185,11 +207,11 @@
 	public final void addLayer(final Layer layer) {
 		if (map == null) {
-			final MapFrame mapFrame = new MapFrame(layer);
+			final MapFrame mapFrame = new MapFrame();
 			setMapFrame(mapFrame);
 			mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction());
 			mapFrame.setVisible(true);
 			mapFrame.setVisibleDialogs();
-		} else
-			map.mapView.addLayer(layer);
+		}
+		map.mapView.addLayer(layer);
 	}
 	/**
@@ -232,4 +254,5 @@
 		}
 	};
+	private JMenu layerMenu;
 
 	/**
Index: /src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 102)
+++ /src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 103)
@@ -30,5 +30,4 @@
 import javax.swing.event.ListSelectionListener;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
@@ -99,5 +98,5 @@
 		}
 
-		@Override public void realRun() throws IOException, JDOMException {
+		@Override public void realRun() throws IOException, SAXException {
 			rawData = reader.parseRawGps();
 		}
Index: /src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 102)
+++ /src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 103)
@@ -8,5 +8,5 @@
 import java.awt.event.KeyEvent;
 import java.io.File;
-import java.io.FileWriter;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Calendar;
@@ -58,4 +58,8 @@
 			return;
 
+		exportGpx(file, this.layer == null ? Main.main.editLayer() : this.layer);
+	}
+
+	public static void exportGpx(File file, Layer layer) {
 		String fn = file.getPath();
 		if (fn.indexOf('.') == -1) {
@@ -113,7 +117,5 @@
 		
 		try {
-			Layer layer = this.layer == null ? Main.main.editLayer() : this.layer;
-			FileWriter out = new FileWriter(file);
-			GpxWriter w = new GpxWriter(out, layer.name, desc.getText(),
+			GpxWriter w = new GpxWriter(new FileOutputStream(file), layer.name, desc.getText(),
 					authorName.getText(), email.getText(), copyright.getText(),
 					copyrightYear.getText(), keywords.getText());
@@ -122,5 +124,5 @@
 			else
 				w.output(Main.ds);
-			out.close();
+			w.close();
 		} catch (IOException x) {
 			x.printStackTrace();
@@ -128,5 +130,5 @@
 		}		
 	}
-
+	
 	/**
 	 * Add all those listeners to handle the enable state of the fields.
@@ -137,5 +139,5 @@
 	 * @param warning 
 	 */
-	private void addDependencies(
+	private static void addDependencies(
 			final JCheckBox author, 
 			final JTextField authorName,
@@ -204,5 +206,5 @@
 	}
 
-	private void enableCopyright(final JTextField copyright, final JButton predefined, final JTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel, final JLabel warning, boolean enable) {
+	private static void enableCopyright(final JTextField copyright, final JButton predefined, final JTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel, final JLabel warning, boolean enable) {
 		copyright.setEnabled(enable);
 		predefined.setEnabled(enable);
Index: /src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/OpenAction.java	(revision 102)
+++ /src/org/openstreetmap/josm/actions/OpenAction.java	(revision 103)
@@ -5,4 +5,5 @@
 import java.awt.event.KeyEvent;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
@@ -14,5 +15,4 @@
 import javax.swing.KeyStroke;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -20,7 +20,5 @@
 import org.openstreetmap.josm.gui.layer.RawGpsLayer;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
-import org.openstreetmap.josm.io.GpxReader;
 import org.openstreetmap.josm.io.OsmReader;
-import org.openstreetmap.josm.io.OsmReaderOld;
 import org.openstreetmap.josm.io.RawCsvReader;
 import org.openstreetmap.josm.io.RawGpsReader;
@@ -60,5 +58,5 @@
 				Collection<Collection<GpsPoint>> data;
 				if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-					data = new RawGpsReader(new FileReader(filename)).parse();
+					data = RawGpsReader.parse(new FileInputStream(filename));
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
 					data = new LinkedList<Collection<GpsPoint>>();
@@ -69,26 +67,6 @@
 			} else {
 				DataSet dataSet;
-				if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-					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)) {
-					try {
-						// temporary allow loading of old xml format.
-						dataSet = OsmReader.parseDataSet(new FileReader(filename), null, null);
-					} catch (SAXException x) {
-						if (x.getMessage().equals("Unknown version null")) {
-							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" +
-									"will not be available in future JOSM version. You should\n" +
-									"immediatly save the file, if successfull imported.",
-									"Load as 0.2 API file?",
-									JOptionPane.YES_NO_OPTION);
-							if (answer != JOptionPane.YES_OPTION)
-								return;
-							dataSet = new OsmReaderOld(new FileReader(filename)).parse();
-						} else 
-							throw x;
-					}					
+				if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn)) {
+					dataSet = OsmReader.parseDataSet(new FileInputStream(filename), null, null);
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
 					JOptionPane.showMessageDialog(Main.parent, fn+": CSV Data import for non-GPS data is not implemented yet.");
@@ -101,7 +79,4 @@
 			}
 		} catch (SAXException x) {
-			x.printStackTrace();
-			JOptionPane.showMessageDialog(Main.parent, "Error while parsing "+fn+": "+x.getMessage());
-		} catch (JDOMException x) {
 			x.printStackTrace();
 			JOptionPane.showMessageDialog(Main.parent, "Error while parsing "+fn+": "+x.getMessage());
@@ -121,7 +96,5 @@
 		if (!ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn))
 			return false;
-		return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(
-				Main.parent, "Do you want to open "+fn+" as raw gps data?",
-				"Open as raw data?", JOptionPane.YES_NO_OPTION);
+		return true;
 	}
 }
Index: /src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/SaveAction.java	(revision 102)
+++ /src/org/openstreetmap/josm/actions/SaveAction.java	(revision 103)
@@ -5,5 +5,5 @@
 import java.awt.event.KeyEvent;
 import java.io.File;
-import java.io.FileWriter;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
@@ -14,6 +14,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.Segment;
-import org.openstreetmap.josm.io.GpxWriter;
 import org.openstreetmap.josm.io.OsmWriter;
 
@@ -64,16 +62,12 @@
 				file = new File(fn);
 			}
-			FileWriter fileWriter;
 			if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-				for (Segment ls : Main.ds.segments) {
-					if (ls.incomplete) {
-						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;
-					}
-				}
-				new GpxWriter(fileWriter = new FileWriter(file), Main.ds).output();
-			} else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn))
-				OsmWriter.output(fileWriter = new FileWriter(file), Main.ds, false);
-			else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
+				GpxExportAction.exportGpx(file, Main.main.editLayer());
+				Main.main.editLayer().cleanData(null, false);
+				return;
+			} else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn)) {
+				OsmWriter.output(new FileOutputStream(file), Main.ds, false);
+				Main.main.editLayer().cleanData(null, false);
+			} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
 				JOptionPane.showMessageDialog(Main.parent, "CSV output not supported yet.");
 				return;
@@ -82,6 +76,4 @@
 				return;
 			}
-			fileWriter.close();
-			Main.main.editLayer().cleanData(null, false);
 		} catch (IOException e) {
 			e.printStackTrace();
Index: /src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/UploadAction.java	(revision 102)
+++ /src/org/openstreetmap/josm/actions/UploadAction.java	(revision 103)
@@ -15,5 +15,4 @@
 import javax.swing.KeyStroke;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -22,4 +21,5 @@
 import org.openstreetmap.josm.io.OsmServerWriter;
 import org.openstreetmap.josm.tools.GBC;
+import org.xml.sax.SAXException;
 
 /**
@@ -73,5 +73,5 @@
 
 		PleaseWaitRunnable uploadTask = new PleaseWaitRunnable("Uploading data"){
-			@Override protected void realRun() throws JDOMException {
+			@Override protected void realRun() throws SAXException {
 				server.setProgressInformation(currentAction, progress);
 				server.uploadOsm(all);
Index: /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 102)
+++ /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 103)
@@ -164,5 +164,5 @@
 	
 	public String getTimeStr() {
-		return timestamp == null ? null : new SimpleDateFormat("y-M-d H:m:s").format(timestamp);
+		return timestamp == null ? null : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
 	}
 }
Index: /src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 103)
@@ -32,5 +32,4 @@
 import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
-import org.openstreetmap.josm.gui.layer.Layer;
 
 /**
@@ -69,5 +68,5 @@
 	 * @param layer The first layer in the mapView. 
 	 */
-	public MapFrame(Layer layer) {
+	public MapFrame() {
 		setSize(400,400);
 		setLayout(new BorderLayout());
@@ -75,5 +74,4 @@
 		final AutoScaleAction autoScaleAction = new AutoScaleAction(this);
 		add(mapView = new MapView(autoScaleAction), BorderLayout.CENTER);
-		mapView.addLayer(layer);
 
 		// toolbar
Index: /src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapStatus.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/MapStatus.java	(revision 103)
@@ -44,5 +44,5 @@
  */
 public class MapStatus extends JPanel {
-	
+
 	/**
 	 * The MapView this status belongs. 
@@ -57,5 +57,5 @@
 	 */
 	JTextField nameText = new JTextField(30);
-	
+
 	/**
 	 * The collector class that waits for notification and then update
@@ -77,11 +77,11 @@
 		 */
 		private Popup popup;
-		
+
 		private MapFrame parent;
-		
+
 		public Collector(MapFrame parent) {
 			this.parent = parent;
 		}
-		
+
 		/**
 		 * Execution function for the Collector.
@@ -100,4 +100,7 @@
 					continue; // freeze display when holding down ctrl
 
+				if (mv.center == null)
+					continue;
+
 				// This try/catch is a hack to stop the flooding bug reports about this.
 				// The exception needed to handle with in the first place, means that this
@@ -106,13 +109,13 @@
 				try {
 					Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
-					
+
 					if (osms == null && osmStatus == null && ms.modifiers == oldModifiers)
 						continue;
 					if (osms != null && osms.equals(osmStatus) && ms.modifiers == oldModifiers)
 						continue;
-					
+
 					osmStatus = osms;
 					oldModifiers = ms.modifiers;
-					
+
 					OsmPrimitive osmNearest = null;
 					// Set the text label in the bottom status bar
@@ -124,10 +127,10 @@
 					} else
 						nameText.setText("");
-					
+
 					// Popup Information
 					if ((ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0 && osms != null) {
 						if (popup != null)
 							popup.hide();
-						
+
 						JPanel c = new JPanel(new GridBagLayout());
 						for (final OsmPrimitive osm : osms) {
@@ -160,5 +163,5 @@
 							c.add(l, GBC.eol());
 						}
-						
+
 						Point p = mv.getLocationOnScreen();
 						popup = PopupFactory.getSharedInstance().getPopup(mv, c, p.x+ms.mousePos.x+16, p.y+ms.mousePos.y+16);
@@ -173,5 +176,5 @@
 		}
 	}
-	
+
 	/**
 	 * Everything, the collector is interested of. Access must be synchronized.
@@ -186,5 +189,5 @@
 	 */
 	MouseState mouseState = new MouseState();
-	
+
 	/**
 	 * Construct a new MapStatus and attach it to the map view.
@@ -193,5 +196,5 @@
 	public MapStatus(final MapFrame mapFrame) {
 		this.mv = mapFrame.mapView;
-		
+
 		// Listen for mouse movements and set the position text field
 		mv.addMouseMotionListener(new MouseMotionListener(){
@@ -207,5 +210,5 @@
 			}
 		});
-		
+
 		positionText.setEditable(false);
 		nameText.setEditable(false);
@@ -216,9 +219,9 @@
 		add(new JLabel(" Object "));
 		add(nameText);
-		
+
 		// The background thread
 		final Collector collector = new Collector(mapFrame);
 		new Thread(collector).start();
-		
+
 		// Listen to keyboard/mouse events for pressing/releasing alt key and
 		// inform the collector.
Index: /src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapView.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/MapView.java	(revision 103)
@@ -207,4 +207,6 @@
 	 */
 	@Override public void paint(Graphics g) {
+		if (center == null)
+			return; // no data loaded yet.
 		g.setColor(SimplePaintVisitor.getPreferencesColor("background", Color.BLACK));
 		g.fillRect(0, 0, getWidth(), getHeight());
Index: /src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- /src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 103)
@@ -19,5 +19,4 @@
 import javax.swing.JProgressBar;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
@@ -77,7 +76,4 @@
 			x.printStackTrace();
 			errorMessage = "Error while parsing: "+x.getMessage();
-		} catch (JDOMException x) {
-			x.printStackTrace();
-			errorMessage = "Error while parsing: "+x.getMessage();
 		} catch (FileNotFoundException x) {
 			x.printStackTrace();
@@ -101,5 +97,5 @@
 	 * is called. finish() is called in any case.
 	 */
-	protected abstract void realRun() throws SAXException, JDOMException, IOException;
+	protected abstract void realRun() throws SAXException, IOException;
 
 	/**
Index: /src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 103)
@@ -43,56 +43,54 @@
 public class LayerList extends ToggleDialog implements LayerChangeListener {
 
+	/**
+	 * The last layerlist created. Used to update the list in the Show/Hide and Delete actions.
+	 * TODO: Replace with Listener-Pattern.
+	 */
+	static JList instance;
+
 	public final static class DeleteLayerAction extends AbstractAction {
 
-        private final JList layers;
-        private final Layer layer;
-
-        public DeleteLayerAction(JList layers, Layer layer) {
-            super("Delete", ImageProvider.get("dialogs", "delete"));
-            putValue(SHORT_DESCRIPTION, "Delete the selected layer.");
-            this.layers = layers;
-            this.layer = layer;
-        }
-
-        public void actionPerformed(ActionEvent e) {
-    	    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);
-        }
-    }
-
-    public final static class ShowHideLayerAction extends AbstractAction {
-        private final Layer layer;
-        private final JList layers;
-
-        public ShowHideLayerAction(JList layers, Layer layer) {
-            super("Show/Hide", ImageProvider.get("dialogs", "showhide"));
-            putValue(SHORT_DESCRIPTION, "Toggle visible state of the selected layer.");
-            this.layer = layer;
-            this.layers = layers;
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            Layer l = layer == null ? (Layer)layers.getSelectedValue() : layer;
-            l.visible = !l.visible;
-        	Main.map.mapView.repaint();
-        	layers.repaint();
-        }
-    }
-
-    /**
+		private final Layer layer;
+
+		public DeleteLayerAction(Layer layer) {
+			super("Delete", ImageProvider.get("dialogs", "delete"));
+			putValue(SHORT_DESCRIPTION, "Delete the selected layer.");
+			this.layer = layer;
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			int sel = instance.getSelectedIndex();
+			if (layer != null)
+				Main.main.removeLayer(layer);
+			else
+				Main.main.removeLayer((Layer)instance.getSelectedValue());
+			if (sel >= instance.getModel().getSize())
+				sel = instance.getModel().getSize()-1;
+			if (instance.getSelectedValue() == null)
+				instance.setSelectedIndex(sel);
+		}
+	}
+
+	public final static class ShowHideLayerAction extends AbstractAction {
+		private final Layer layer;
+
+		public ShowHideLayerAction(Layer layer) {
+			super("Show/Hide", ImageProvider.get("dialogs", "showhide"));
+			putValue(SHORT_DESCRIPTION, "Toggle visible state of the selected layer.");
+			this.layer = layer;
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			Layer l = layer == null ? (Layer)instance.getSelectedValue() : layer;
+			l.visible = !l.visible;
+			Main.map.mapView.repaint();
+			instance.repaint();
+		}
+	}
+
+	/**
 	 * The data model for the list component.
 	 */
 	DefaultListModel model = new DefaultListModel();
-	/**
-	 * The list component holding all layers.
-	 */
-	JList layers = new JList(model);
 	/**
 	 * The merge action. This is only called, if the current selection and its
@@ -111,5 +109,5 @@
 	 * Button for delete layer.
 	 */
-	private Action deleteAction = new DeleteLayerAction(layers, null);
+	private Action deleteAction = new DeleteLayerAction(null);
 
 	/**
@@ -118,8 +116,9 @@
 	public LayerList(MapFrame mapFrame) {
 		super("Layers", "layerlist", "Open a list of all loaded layers.", KeyEvent.VK_L);
+		instance = new JList(model);
 		setPreferredSize(new Dimension(320,100));
-		add(new JScrollPane(layers), BorderLayout.CENTER);
-		layers.setBackground(UIManager.getColor("Button.background"));
-		layers.setCellRenderer(new DefaultListCellRenderer(){
+		add(new JScrollPane(instance), BorderLayout.CENTER);
+		instance.setBackground(UIManager.getColor("Button.background"));
+		instance.setCellRenderer(new DefaultListCellRenderer(){
 			@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
 				Layer layer = (Layer)value;
@@ -141,22 +140,22 @@
 			model.addElement(l);
 
-		layers.setSelectedValue(mapView.getActiveLayer(), true);
-		layers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-		layers.addListSelectionListener(new ListSelectionListener(){
+		instance.setSelectedValue(mapView.getActiveLayer(), true);
+		instance.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		instance.addListSelectionListener(new ListSelectionListener(){
 			public void valueChanged(ListSelectionEvent e) {
-				if (layers.getModel().getSize() == 0)
+				if (instance.getModel().getSize() == 0)
 					return;
-				if (layers.getSelectedIndex() == -1)
-					layers.setSelectedIndex(e.getFirstIndex());
-				mapView.setActiveLayer((Layer)layers.getSelectedValue());
+				if (instance.getSelectedIndex() == -1)
+					instance.setSelectedIndex(e.getFirstIndex());
+				mapView.setActiveLayer((Layer)instance.getSelectedValue());
 			}
 		});
 		mapView.addLayerChangeListener(this);
 
-		layers.addMouseListener(new MouseAdapter(){
+		instance.addMouseListener(new MouseAdapter(){
 			private void openPopup(MouseEvent e) {
-				int index = layers.locationToIndex(e.getPoint());
-				Layer layer = (Layer)layers.getModel().getElementAt(index);
-				LayerListPopup menu = new LayerListPopup(layers, layer);
+				int index = instance.locationToIndex(e.getPoint());
+				Layer layer = (Layer)instance.getModel().getElementAt(index);
+				LayerListPopup menu = new LayerListPopup(instance, layer);
 				menu.show(LayerList.this, e.getX(), e.getY());
 			}
@@ -170,6 +169,6 @@
 			}
 		});
-		
-		
+
+
 		// Buttons
 		JPanel buttonPanel = new JPanel(new GridLayout(1, 5));
@@ -177,11 +176,11 @@
 		ActionListener upDown = new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
-				Layer l = (Layer)layers.getSelectedValue();
-				int sel = layers.getSelectedIndex();
+				Layer l = (Layer)instance.getSelectedValue();
+				int sel = instance.getSelectedIndex();
 				int selDest = e.getActionCommand().equals("up") ? sel-1 : sel+1;
 				mapView.moveLayer(l, selDest);
 				model.set(sel, model.get(selDest));
 				model.set(selDest, l);
-				layers.setSelectedIndex(selDest);
+				instance.setSelectedIndex(selDest);
 				updateButtonEnabled();
 				mapView.repaint();
@@ -193,25 +192,25 @@
 		upButton.setActionCommand("up");
 		buttonPanel.add(upButton);
-		
+
 		downButton.setToolTipText("Move the selected layer one row down.");
 		downButton.addActionListener(upDown);
 		downButton.setActionCommand("down");
 		buttonPanel.add(downButton);
-		
-		JButton showHideButton = new JButton(new ShowHideLayerAction(layers, null));
-        showHideButton.setText("");
-        buttonPanel.add(showHideButton);
-		
-        JButton deleteButton = new JButton(deleteAction);
-        deleteButton.setText("");
-        buttonPanel.add(deleteButton);
+
+		JButton showHideButton = new JButton(new ShowHideLayerAction(null));
+		showHideButton.setText("");
+		buttonPanel.add(showHideButton);
+
+		JButton deleteButton = new JButton(deleteAction);
+		deleteButton.setText("");
+		buttonPanel.add(deleteButton);
 
 		mergeButton.setToolTipText("Merge the selected layer into the layer directly below.");
 		mergeButton.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
-				Layer lFrom = (Layer)layers.getSelectedValue();
-				Layer lTo = (Layer)model.get(layers.getSelectedIndex()+1);
+				Layer lFrom = (Layer)instance.getSelectedValue();
+				Layer lTo = (Layer)model.get(instance.getSelectedIndex()+1);
 				lTo.mergeFrom(lFrom);
-				layers.setSelectedValue(lTo, true);
+				instance.setSelectedValue(lTo, true);
 				mapView.removeLayer(lFrom);
 			}
@@ -220,5 +219,5 @@
 
 		add(buttonPanel, BorderLayout.SOUTH);
-		
+
 		updateButtonEnabled();
 	}
@@ -228,6 +227,6 @@
 	 */
 	void updateButtonEnabled() {
-		int sel = layers.getSelectedIndex();
-		Layer l = (Layer)layers.getSelectedValue();
+		int sel = instance.getSelectedIndex();
+		Layer l = (Layer)instance.getSelectedValue();
 		boolean enable = model.getSize() > 1;
 		enable = enable && sel < model.getSize()-1;
@@ -249,6 +248,6 @@
 	public void layerRemoved(Layer oldLayer) {
 		model.removeElement(oldLayer);
-		if (layers.getSelectedIndex() == -1)
-			layers.setSelectedIndex(0);
+		if (instance.getSelectedIndex() == -1)
+			instance.setSelectedIndex(0);
 		updateButtonEnabled();
 	}
@@ -258,6 +257,6 @@
 	 */
 	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
-		if (newLayer != layers.getSelectedValue())
-			layers.setSelectedValue(newLayer, true);
+		if (newLayer != instance.getSelectedValue())
+			instance.setSelectedValue(newLayer, true);
 		updateButtonEnabled();
 	}
Index: /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 103)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.gui.dialogs;
 
+import java.awt.Component;
 import java.awt.event.ActionEvent;
 
@@ -29,9 +30,6 @@
 
 	public LayerListPopup(final JList layers, final Layer layer) {
-		add(new LayerList.ShowHideLayerAction(layers, layer));
-		add(new LayerList.DeleteLayerAction(layers, layer));
-		addSeparator();
-
-		layer.addMenuEntries(this);
+		for (Component c : layer.getMenuEntries())
+			add(c);
 	}
 }
Index: /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 103)
@@ -11,5 +11,5 @@
 import java.awt.event.MouseEvent;
 import java.io.IOException;
-import java.io.Reader;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -73,5 +73,5 @@
 			try {
 		        URLConnection con = url.openConnection();
-		        Reader in = new ProgressReader(con, progress, currentAction);
+		        InputStream in = new ProgressReader(con, progress, currentAction);
 				currentAction.setText("Downloading...");
 				Map<Long, String> ids = idReader.parseIds(in);
Index: /src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 103)
@@ -36,6 +36,6 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
 import javax.swing.JTextField;
 import javax.swing.JToggleButton;
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.dialogs.LayerList;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
@@ -314,5 +315,5 @@
 	}
 
-	@Override public void addMenuEntries(JPopupMenu menu) {
+	@Override public Component[] getMenuEntries() {
 		JMenuItem sync = new JMenuItem("Sync clock", ImageProvider.get("clock"));
 		sync.addActionListener(new ActionListener(){
@@ -338,8 +339,11 @@
 			}
 		});
-		menu.add(sync);
-
-		menu.addSeparator();
-		menu.add(new LayerListPopup.InfoAction(this));
+		return new Component[]{
+				new JMenuItem(new LayerList.ShowHideLayerAction(this)),
+				new JMenuItem(new LayerList.DeleteLayerAction(this)),
+				new JSeparator(),
+				sync,
+				new JSeparator(), 
+				new JMenuItem(new LayerListPopup.InfoAction(this))};
 	}
 
Index: /src/org/openstreetmap/josm/gui/layer/Layer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 103)
@@ -1,8 +1,8 @@
 package org.openstreetmap.josm.gui.layer;
 
+import java.awt.Component;
 import java.awt.Graphics;
 
 import javax.swing.Icon;
-import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
@@ -82,5 +82,5 @@
 	abstract public Object getInfoComponent();
 	
-	abstract public void addMenuEntries(JPopupMenu menu);
+	abstract public Component[] getMenuEntries();
 	
 	/**
Index: /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 103)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.gui.layer;
 
+import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.GridBagLayout;
@@ -16,5 +17,5 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
 
 import org.openstreetmap.josm.Main;
@@ -33,4 +34,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
+import org.openstreetmap.josm.gui.dialogs.LayerList;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.GBC;
@@ -309,9 +311,13 @@
 	}
 
-	@Override public void addMenuEntries(final JPopupMenu menu) {
-		menu.add(new JMenuItem(new SaveAction()));
-		menu.add(new JMenuItem(new GpxExportAction(this)));
-		menu.addSeparator();
-		menu.add(new LayerListPopup.InfoAction(this));
+	@Override public Component[] getMenuEntries() {
+		return new Component[]{
+				new JMenuItem(new LayerList.ShowHideLayerAction(this)),
+				new JMenuItem(new LayerList.DeleteLayerAction(this)),
+				new JSeparator(),
+				new JMenuItem(new SaveAction()),
+				new JMenuItem(new GpxExportAction(this)),
+				new JSeparator(),
+				new JMenuItem(new LayerListPopup.InfoAction(this))};
 	}
 }
Index: /src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 103)
@@ -2,4 +2,5 @@
 
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Point;
@@ -16,5 +17,5 @@
 import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
-import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
 import javax.swing.filechooser.FileFilter;
 
@@ -30,4 +31,5 @@
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerList;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.ColorHelper;
@@ -42,7 +44,7 @@
 public class RawGpsLayer extends Layer implements PreferenceChangedListener {
 
-	public class ConvertToOsmAction extends AbstractAction {
-		public ConvertToOsmAction() {
-			super("Convert layer to OSM");
+	public class ConvertToDataLayerAction extends AbstractAction {
+		public ConvertToDataLayerAction() {
+			super("Convert to data layer", ImageProvider.get("converttoosm"));
         }
 		public void actionPerformed(ActionEvent e) {
@@ -154,7 +156,5 @@
 	}
 
-	@Override public void addMenuEntries(JPopupMenu menu) {
-		menu.add(new JMenuItem(new GpxExportAction(this)));
-		
+	@Override public Component[] getMenuEntries() {
 		JMenuItem color = new JMenuItem("Customize Color", ImageProvider.get("colorchooser"));
 		color.addActionListener(new ActionListener(){
@@ -177,5 +177,4 @@
 			}
 		});
-		menu.add(color);
 		
 		JMenuItem tagimage = new JMenuItem("Import images", ImageProvider.get("tagimages"));
@@ -213,10 +212,14 @@
             }
 		});
-		menu.add(tagimage);
-		
-		menu.add(new JMenuItem(new ConvertToOsmAction()));
-		
-		menu.addSeparator();
-		menu.add(new LayerListPopup.InfoAction(this));
+		return new Component[]{
+				new JMenuItem(new LayerList.ShowHideLayerAction(this)),
+				new JMenuItem(new LayerList.DeleteLayerAction(this)),
+				new JSeparator(),
+				new JMenuItem(new GpxExportAction(this)),
+				color,
+				tagimage,
+				new JMenuItem(new ConvertToDataLayerAction()),
+				new JSeparator(),
+				new JMenuItem(new LayerListPopup.InfoAction(this))};
     }
 
Index: /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java	(revision 102)
+++ /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java	(revision 103)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.gui.layer;
 
+import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Image;
@@ -6,5 +7,6 @@
 
 import javax.swing.Icon;
-import javax.swing.JPopupMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JSeparator;
 
 import org.openstreetmap.josm.Main;
@@ -14,4 +16,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerList;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -95,7 +98,10 @@
 	}
 
-	@Override public void addMenuEntries(JPopupMenu menu) {
-		menu.addSeparator();
-		menu.add(new LayerListPopup.InfoAction(this));
+	@Override public Component[] getMenuEntries() {
+		return new Component[]{
+				new JMenuItem(new LayerList.ShowHideLayerAction(this)),
+				new JMenuItem(new LayerList.DeleteLayerAction(this)),
+				new JSeparator(),
+				new JMenuItem(new LayerListPopup.InfoAction(this))};
     }
 }
Index: c/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/GpxReader.java	(revision 102)
+++ 	(revision )
@@ -1,282 +1,0 @@
-package org.openstreetmap.josm.io;
-
-import static org.openstreetmap.josm.io.GpxWriter.JOSM;
-import static org.openstreetmap.josm.io.GpxWriter.OSM;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Segment;
-import org.openstreetmap.josm.data.osm.Way;
-
-/**
- * Reads an gpx stream and construct a DataSet out of it. 
- * Some information may not be imported, but GpxReader tries its best to load
- * all data possible in the key/value structure.
- * 
- * @author imi
- */
-public class GpxReader {
-
-	/**
-	 * The data source from this reader.
-	 */
-	public Reader source;
-	/**
-	 * Mapper to find new created objects that occoure more than once.
-	 */
-	private HashMap<Long, OsmPrimitive> newCreatedPrimitives = new HashMap<Long, OsmPrimitive>();
-	/**
-	 * Either set to true or false, depending whether the JOSM namespace declaration 
-	 * was found.
-	 */
-	private boolean mergeNodes = false;
-
-	private Namespace gpx;
-	
-	/**
-	 * Construct a parser from a specific data source.
-	 * @param source The data source, as example a FileReader to read from a file.
-	 */
-	public GpxReader(Reader source) {
-		this.source = source;
-	}
-
-	/**
-	 * Read the input stream and return a DataSet from the stream.
-	 */
-	public DataSet parse() throws JDOMException, IOException {
-		try {
-			final SAXBuilder builder = new SAXBuilder();
-			Element root = builder.build(source).getRootElement();
-			gpx = root.getNamespace();
-			mergeNodes = !root.getAdditionalNamespaces().contains(JOSM);
-			return parseDataSet(root);
-		} catch (NullPointerException npe) {
-			throw new JDOMException("NullPointerException. Probably a tag name mismatch.", npe);
-		} catch (ClassCastException cce) {
-			throw new JDOMException("ClassCastException. Probably a tag does not contain the correct type.", cce);
-		}
-	}
-
-
-	/**
-	 * Read one node (waypoint).
-	 * @param e 	The element to parse
-	 * @return		The Waypoint read from the element
-	 */
-	private Node parseWaypoint(Element e) {
-		Node data = new Node(new LatLon(
-				Double.parseDouble(e.getAttributeValue("lat")),
-				Double.parseDouble(e.getAttributeValue("lon"))));
-
-		for (Object o : e.getChildren()) {
-			Element child = (Element)o;
-			if (child.getName().equals("extensions"))
-				parseKeyValueExtensions(data, child);
-			else if (child.getName().equals("link"))
-				parseKeyValueLink(data, child);
-			else
-				parseKeyValueTag(data, child);
-		}
-		data = (Node)getNewIfSeenBefore(data);
-		return data;
-	}
-
-	/**
-	 * Read a data set from the element.
-	 * @param e 	The element to parse
-	 * @return		The DataSet read from the element
-	 */
-	private DataSet parseDataSet(Element e) {
-		DataSet data = new DataSet();
-		// read waypoints not contained in ways or areas
-		for (Object o : e.getChildren("wpt", gpx)) {
-			Node node = parseWaypoint((Element)o);
-			addNode(data, node);
-		}
-
-		// read ways (and segments)
-		for (Object wayElement : e.getChildren("trk", gpx))
-			parseWay((Element)wayElement, data);
-
-		// reset new created ids to zero
-		for (OsmPrimitive osm : data.allPrimitives())
-			if (osm.id < 0)
-				osm.id = 0;
-
-		// clean up the data a bit (remove broken stuff)
-		// remove segments with from==to
-		for (Iterator<Segment> it = data.segments.iterator(); it.hasNext();) {
-			Segment ls = it.next();
-			if (ls.from.equals(ls.to)) {
-				it.remove();
-				for (Way w : data.ways)
-					w.segments.remove(ls);
-			}
-		}
-		// remove double segments (remove only subsequent doubles yet)
-		for (Iterator<Way> it = data.ways.iterator(); it.hasNext();) {
-			Segment ls = null;
-			for (Iterator<Segment> its = it.next().segments.iterator(); its.hasNext();) {
-				Segment cur = its.next();
-				if (ls != null && ls.equals(cur))
-					its.remove();
-				ls = cur;
-			}
-		}
-		// remove empty ways
-		for (Iterator<Way> it = data.ways.iterator(); it.hasNext();)
-			if (it.next().segments.isEmpty())
-				it.remove();
-
-		return data;
-	}
-
-	/**
-	 * Parse and read a way from the element. Store it in the dataSet, as well
-	 * as all nodes in it.
-	 *
-	 * @param e		The element that contain the way.
-	 * @param ds	The DataSet to store the data in.
-	 */
-	private void parseWay(Element e, DataSet ds) {
-		Way way = new Way();
-		boolean realSegment = false; // is this way just a fake?
-
-		for (Object o : e.getChildren()) {
-			Element child = (Element)o;
-
-			if (child.getName().equals("trkseg")) {
-				Node start = null;
-				for (Object w : child.getChildren("trkpt", gpx)) {
-					Node node = addNode(ds, parseWaypoint((Element)w));
-					if (start == null)
-						start = node;
-					else {
-						Segment segment = new Segment(start, node);
-						parseKeyValueExtensions(segment, child.getChild("extensions", gpx));
-						segment = (Segment)getNewIfSeenBefore(segment);
-						way.segments.add(segment);
-						start = node;
-					}
-				}
-			} else if (child.getName().equals("extensions")) {
-				parseKeyValueExtensions(way, child);
-				if (child.getChild("segment", JOSM) != null)
-					realSegment = true;
-			} else if (child.getName().equals("link"))
-				parseKeyValueLink(way, child);
-			else
-				parseKeyValueTag(way, child);
-		}
-		way = (Way)getNewIfSeenBefore(way);
-		ds.segments.addAll(way.segments);
-		if (!realSegment)
-			ds.ways.add(way);
-	}
-
-	/**
-	 * Adds the node to allNodes if it is not already listed. Does respect the
-	 * setting "mergeNodes". Return the node in the list that correspond
-	 * to the node in the list (either the new added or the old found).
-	 * 
-	 * @param data The DataSet to add the node to.
-	 * @param node The node that should be added.
-	 * @return Either the parameter node or the old node found in the dataset. 
-	 */
-	private Node addNode(DataSet data, Node node) {
-		if (mergeNodes)
-			for (Node n : data.nodes)
-				if (node.coor.equals(n.coor))
-					return n;
-		data.nodes.add(node);
-		return node;
-	}
-
-
-	/**
-	 * @return Either the parameter or an index from the newCreatedPrimitives map
-	 * 		with the id seen before.
-	 */
-	private OsmPrimitive getNewIfSeenBefore(OsmPrimitive osm) {
-		if (newCreatedPrimitives.containsKey(osm.id))
-			return newCreatedPrimitives.get(osm.id);
-		return osm;
-	}
-
-	/**
-	 * Parse the extensions tag and add all properties found as key/value. 
-	 * <code>osm.keys</code> may be <code>null</code>, in which case it is 
-	 * created first. If <code>e</code> is <code>null</code>, nothing
-	 * happens.
-	 * 
-	 * @param osm	The primitive to store the properties.
-	 * @param e		The extensions element to read the properties from.
-	 */
-	private void parseKeyValueExtensions(OsmPrimitive osm, Element e) {
-		if (e != null) {
-			for (Object o : e.getChildren("property", OSM)) {
-				Element child = (Element)o;
-				String keyname = child.getAttributeValue("key");
-				if (keyname != null) {
-					String value = child.getAttributeValue("value");
-					if (value == null)
-						value = "";
-					osm.put(keyname, value);
-				}
-			}
-			Element idElement = e.getChild("uid", JOSM);
-			if (idElement != null)
-				osm.id = Long.parseLong(idElement.getText());
-			if (osm.id < 0 && !newCreatedPrimitives.containsKey(osm.id))
-				newCreatedPrimitives.put(osm.id, osm);
-			osm.modified = e.getChild("modified", JOSM) != null;
-			osm.delete(e.getChild("deleted", JOSM) != null);
-		}
-	}
-
-	/**
-	 * If the element is not <code>null</code>, read the data from it and put
-	 * it as the key with the name of the elements name in the given object.
-	 * 
-	 * The <code>keys</code> - field of the element could be <code>null</code>,
-	 * in which case it is created first.
-	 * 
-	 * @param osm     The osm primitive to put the key into.
-	 * @param e		  The element to look for data.
-	 */
-	private void parseKeyValueTag(OsmPrimitive osm, Element e) {
-		if (e != null)
-			osm.put(e.getName(), e.getValue());
-	}
-
-	/**
-	 * Parse the GPX linkType data information and store it as value in the 
-	 * primitives <i>link</i> key. <code>osm.keys</code> may be 
-	 * <code>null</code>, in which case it is created first. If 
-	 * <code>e</code> is <code>null</code>, nothing happens.
-	 * 
-	 * The format stored is: mimetype;url
-	 * Example: text/html;http://www.openstreetmap.org
-	 * 
-	 * @param osm	The osm primitive to store the data in.
-	 * @param e		The element in gpx:linkType - format.
-	 */
-	private void parseKeyValueLink(OsmPrimitive osm, Element e) {
-		if (e != null) {
-			String link = e.getChildText("type") + ";" + e.getChildText("text");
-			osm.put("link", link);
-		}
-	}
-}
Index: /src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/GpxWriter.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/GpxWriter.java	(revision 103)
@@ -1,25 +1,17 @@
 package org.openstreetmap.josm.io;
 
-import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.io.Writer;
+import java.io.UnsupportedEncodingException;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.Map.Entry;
-
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.Namespace;
-import org.jdom.output.Format;
-import org.jdom.output.XMLOutputter;
+
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
@@ -39,290 +31,14 @@
 
 	/**
-	 * The GPX namespace used.
-	 */
-	public static final Namespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0");
-	/**
-	 * The OSM namespace used (for extensions).
-	 */
-	public static final Namespace OSM = Namespace.getNamespace("osm", "http://www.openstreetmap.org");
-	/**
-	 * The JOSM namespace (for JOSM-extensions).
-	 */
-	public static final Namespace JOSM = Namespace.getNamespace("josm", "http://wiki.eigenheimstrasse.de/wiki/JOSM");
-
-	/**
 	 * This is the output writer to store the resulting data in.
 	 */
 	private PrintWriter out;
-	/**
-	 * The dataset beeing processed.
-	 */
-	private DataSet ds;
-	/**
-	 * Map all new primitives to the element which hold them. After inserting everything,
-	 * the writer sets ids to every element that was in the list and had more than one
-	 * element using it. 
-	 */
-	private HashMap<OsmPrimitive, Collection<Element>> usedNewPrimitives = new HashMap<OsmPrimitive, Collection<Element>>();
-	/**
-	 * The counter for new created objects used more than once.
-	 * Starting at -1 and goes down.
-	 */
-	private long newIdCounter = -1;
-	
-	/**
-	 * Create a GpxWrite from an output writer. As example to write in a file,
-	 * use FileWriter.
-	 *
-	 * @param out The Writer to store the result data in.
-	 */
-	public GpxWriter(Writer out, DataSet ds) {
-		this.out = new PrintWriter(out);
-		this.ds = ds;
-	}
-
-
-	/**
-	 * Do the output in the former set writer.
-	 * @exception IOException In case of IO errors, throw this exception.
-	 */
-	public void output() throws IOException {
-		Element root = parseDataSet();
-		root.addNamespaceDeclaration(OSM);
-		root.addNamespaceDeclaration(JOSM);
-		Document d = new Document(root);
-		XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
-		xmlOut.output(d, out);
-	}
-
-
-	/**
-	 * Write the whole DataSet in an JDom-Element and return the new element.
-	 * @return The created element, out of the dataset.
-	 */
-	@SuppressWarnings("unchecked")
-	private Element parseDataSet() {
-		Element e = new Element("gpx", GPX);
-		e.setAttribute("version", "1.0");
-		e.setAttribute("creator", "JOSM");
-		// for getting all unreferenced waypoints in the wpt-list
-		LinkedList<Node> unrefNodes = new LinkedList<Node>(ds.nodes);
-		// for getting all unreferenced segments
-		LinkedList<Segment> unrefLs = new LinkedList<Segment>(ds.segments);
-
-		// ways
-		for (Way w : ds.ways) {
-			if (w.deleted && w.id == 0)
-				continue;
-			Element tElem = new Element("trk", GPX);
-			HashMap<String, String> keys = null;
-			if (w.keys != null) {
-				keys = new HashMap<String, String>(w.keys);
-				addAndRemovePropertyTag("name", tElem, keys);
-				addAndRemovePropertyTag("cmt", tElem, keys);
-				addAndRemovePropertyTag("desc", tElem, keys);
-				addAndRemovePropertyTag("src", tElem, keys);
-				addAndRemovePropertyLinkTag(tElem, keys);
-				addAndRemovePropertyTag("number", tElem, keys);
-				addAndRemovePropertyTag("type", tElem, keys);
-			}
-			addPropertyExtensions(tElem, keys, w);
-
-			// segments
-			for (Segment ls : w.segments) {
-				if (ls.incomplete)
-					continue;
-				tElem.getChildren().add(parseSegment(ls));
-				unrefNodes.remove(ls.from);
-				unrefNodes.remove(ls.to);
-				unrefLs.remove(ls);
-			}
-
-			e.getChildren().add(tElem);
-		}
-		
-		// encode pending segments as ways
-		for (Segment ls : unrefLs) {
-			if (ls.deleted && ls.id == 0)
-				continue;
-			Element t = new Element("trk", GPX);
-			t.getChildren().add(parseSegment(ls));
-			unrefNodes.remove(ls.from);
-			unrefNodes.remove(ls.to);
-			Element ext = new Element("extensions", GPX);
-			ext.getChildren().add(new Element("segment", JOSM));
-			t.getChildren().add(ext);
-			e.getChildren().add(t);
-		}
-
-		// waypoints (missing nodes)
-		for (Node n : unrefNodes) {
-			if (n.deleted && n.id == 0)
-				continue;
-			e.getChildren().add(parseWaypoint(n, "wpt"));
-		}
-
-		// link all ids used more than once
-		for (Entry<OsmPrimitive, Collection<Element>> entry : usedNewPrimitives.entrySet()) {
-			if (entry.getValue().size() > 1) {
-				long id = newIdCounter--;
-				for (Element element : entry.getValue()) {
-					Element ext = element.getChild("extensions", GPX);
-					if (ext == null)
-						element.getChildren().add(ext = new Element("extensions", GPX));
-					ext.getChildren().add(new Element("uid", JOSM).setText(""+id));
-				}
-			}
-		}
-
-		return e;
-	}
-
-
-	/**
-	 * Parse a segment and store it into a JDOM-Element. Return that element.
-	 */
-	@SuppressWarnings("unchecked")
-	private Element parseSegment(Segment ls) {
-		Element lsElem = new Element("trkseg", GPX);
-		addPropertyExtensions(lsElem, ls.keys, ls);
-		lsElem.getChildren().add(parseWaypoint(ls.from, "trkpt"));
-		lsElem.getChildren().add(parseWaypoint(ls.to, "trkpt"));
-		return lsElem;
-	}
-
-	/**
-	 * Parse a waypoint (node) and store it into an JDOM-Element. Return that
-	 * element.
-	 * 
-	 * @param n The Node to parse and store
-	 * @param name The name of the tag (different names for nodes in GPX)
-	 * @return The resulting GPX-Element
-	 */
-	private Element parseWaypoint(Node n, String name) {
-		Element e = new Element(name, GPX);
-		e.setAttribute("lat", Double.toString(n.coor.lat()));
-		e.setAttribute("lon", Double.toString(n.coor.lon()));
-		HashMap<String, String> keys = null;
-		if (n.keys != null) {
-			keys = new HashMap<String, String>(n.keys);
-			addAndRemovePropertyTag("ele", e, keys);
-			addAndRemovePropertyTag("time", e, keys);
-			addAndRemovePropertyTag("magvar", e, keys);
-			addAndRemovePropertyTag("geoidheight", e, keys);
-			addAndRemovePropertyTag("name", e, keys);
-			addAndRemovePropertyTag("cmt", e, keys);
-			addAndRemovePropertyTag("desc", e, keys);
-			addAndRemovePropertyTag("src", e, keys);
-			addAndRemovePropertyLinkTag(e, keys);
-			addAndRemovePropertyTag("sym", e, keys);
-			addAndRemovePropertyTag("type", e, keys);
-			addAndRemovePropertyTag("fix", e, keys);
-			addAndRemovePropertyTag("sat", e, keys);
-			addAndRemovePropertyTag("hdop", e, keys);
-			addAndRemovePropertyTag("vdop", e, keys);
-			addAndRemovePropertyTag("pdop", e, keys);
-			addAndRemovePropertyTag("ageofdgpsdata", e, keys);
-			addAndRemovePropertyTag("dgpsid", e, keys);
-		}
-		addPropertyExtensions(e, keys, n);
-		return e;
-	}
-
-
-	/**
-	 * Add a link-tag to the element, if the property list contain a value named 
-	 * "link". The property is removed from the map afterwards.
-	 * 
-	 * For the format, @see GpxReader#parseKeyValueLink(OsmPrimitive, Element).
-	 * @param e		The element to add the link to.
-	 * @param keys	The map containing the link property.
-	 */
-	@SuppressWarnings("unchecked")
-	private void addAndRemovePropertyLinkTag(Element e, Map<String, String> keys) {
-		String value = keys.get("link");
-		if (value != null) {
-			StringTokenizer st = new StringTokenizer(value, ";");
-			if (st.countTokens() != 2)
-				return;
-			Element link = new Element("link", GPX);
-			link.getChildren().add(new Element("type", GPX).setText(st.nextToken()));
-			link.getChildren().add(0,new Element("text", GPX).setText(st.nextToken()));
-			e.getChildren().add(link);
-			keys.remove("link");
-		}
-	}
-
-
-	/**
-	 * Helper to add a property with a given name as tag to the element. This
-	 * will look like &lt;name&gt;<i>keys.get(name)</i>&lt;/name&gt; 
-	 * 
-	 * After adding, the property is removed from the map.
-	 * 
-	 * If the property does not exist, nothing is done.
-	 * 
-	 * @param name The properties name
-	 * @param e The element to add the tag to.
-	 * @param osm The data to get the property from.
-	 */
-	@SuppressWarnings("unchecked")
-	private void addAndRemovePropertyTag(String name, Element e, Map<String, String> keys) {
-		String value = keys.get(name);
-		if (value != null) {
-			e.getChildren().add(new Element(name, GPX).setText(value));
-			keys.remove(name);
-		}
-	}
-	
-	/**
-	 * Add the property in the entry as &lt;extensions&gt; to the element 
-	 * @param e		The element to add the property to.
-	 * @param prop	The property to add.
-	 */
-	@SuppressWarnings("unchecked")
-	private void addPropertyExtensions(Element e, Map<String, String> keys, OsmPrimitive osm) {
-		LinkedList<Element> extensions = new LinkedList<Element>();
-		if (keys != null && !keys.isEmpty()) {
-			for (Entry<String, String> prop : keys.entrySet()) {
-				Element propElement = new Element("property", OSM);
-				propElement.setAttribute("key", prop.getKey());
-				propElement.setAttribute("value", prop.getValue());
-				extensions.add(propElement);
-			}
-		}
-		
-		if (osm.id != 0) {
-			Element propElement = new Element("uid", JOSM);
-			propElement.setText(""+osm.id);
-			extensions.add(propElement);
-		} else {
-			Collection<Element> l = usedNewPrimitives.get(osm);
-			if (l == null)
-				l = new LinkedList<Element>();
-			l.add(e);
-			usedNewPrimitives.put(osm, l);
-		}
-		if (osm.modified) {
-			Element modElement = new Element("modified", JOSM);
-			extensions.add(modElement);
-		}
-		if (osm.deleted) {
-			Element modElement = new Element("deleted", JOSM);
-			extensions.add(modElement);
-		}
-		
-		if (extensions.isEmpty())
-			return;
-
-		Element ext = e.getChild("extensions", GPX);
-		if (ext == null)
-			e.getChildren().add(ext = new Element("extensions", GPX));
-		ext.getChildren().addAll(extensions);
-	}
-
-
-	public GpxWriter(Writer writer, String name, String desc, String author, String email, String copyright, String year, String keywords) {
-		out = writer instanceof PrintWriter ? (PrintWriter)writer : new PrintWriter(writer);
+
+	public GpxWriter(OutputStream os, String name, String desc, String author, String email, String copyright, String year, String keywords) {
+		try {
+			out = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException(e);
+		}
 		out.println(XmlWriter.header());
 		out.println("<gpx version='1.1' creator='JOSM' xmlns='http://www.topografix.com/GPX/1/1'>");
@@ -373,5 +89,5 @@
 		out.println("    <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
 		out.println("  </metadata>");
-		
+
 		// add ways
 		for (Way w : data.ways) {
@@ -407,5 +123,5 @@
 			all.remove(w);
 		}
-		
+
 		// add remaining segments
 		Collection<Segment> segments = new LinkedList<Segment>();
@@ -426,10 +142,10 @@
 			out.println("  </trk>");
 		}
-		
+
 		// finally add the remaining nodes
 		for (OsmPrimitive osm : all)
 			if (osm instanceof Node)
 				outputNode((Node)osm, true);
-		
+
 		out.println("</gpx>");
 	}
@@ -453,5 +169,5 @@
 		out.println("    <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
 		out.println("  </metadata>");
-		
+
 		out.println("  <trk>");
 		for (Collection<GpsPoint> c : data) {
@@ -508,3 +224,8 @@
 			out.println(" />");
 	}
+
+	public void close() {
+		out.flush();
+		out.close();
+	}
 }
Index: /src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmConnection.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmConnection.java	(revision 103)
@@ -26,4 +26,11 @@
 public class OsmConnection {
 
+	public static class OsmParseException extends Exception {
+		public OsmParseException() {super();}
+		public OsmParseException(String message, Throwable cause) {super(message, cause);}
+		public OsmParseException(String message) {super(message);}
+		public OsmParseException(Throwable cause) {super(cause);}
+	}
+	
 	protected boolean cancel = false;
 	protected HttpURLConnection activeConnection;
Index: /src/org/openstreetmap/josm/io/OsmIdReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmIdReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmIdReader.java	(revision 103)
@@ -2,4 +2,6 @@
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.util.HashMap;
@@ -33,8 +35,8 @@
     }
 
-	public Map<Long, String> parseIds(Reader in) throws IOException, SAXException {
-        this.in = in;
+	public Map<Long, String> parseIds(InputStream in) throws IOException, SAXException {
+        this.in = new InputStreamReader(in, "UTF-8");
 		try {
-	        parse(in);
+	        parse(this.in);
         } catch (SAXException e) {
         	if (!cancel)
Index: /src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmReader.java	(revision 103)
@@ -2,5 +2,6 @@
 
 import java.io.IOException;
-import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.text.DateFormat;
 import java.text.ParseException;
@@ -56,5 +57,5 @@
 	 */
 	private Map<Long, Node> nodes = new HashMap<Long, Node>();
-	
+
 	private static class OsmPrimitiveData extends OsmPrimitive {
 		@Override public void visit(Visitor visitor) {}
@@ -68,7 +69,7 @@
 			osm.deleted = deleted;
 			osm.timestamp = timestamp;
-        }
-	}
-	
+		}
+	}
+
 	/**
 	 * Data structure for the remaining segment objects
@@ -200,9 +201,9 @@
 	 * Parse the given input source and return the dataset.
 	 */
-	public static DataSet parseDataSet(Reader source, JLabel currentAction, BoundedRangeModel progress) throws SAXException, IOException {
+	public static DataSet parseDataSet(InputStream source, JLabel currentAction, BoundedRangeModel progress) throws SAXException, IOException {
 		OsmReader osm = new OsmReader();
 
 		// phase 1: Parse nodes and read in raw segments and ways
-		osm.new Parser().parse(source);
+		osm.new Parser().parse(new InputStreamReader(source, "UTF-8"));
 		if (progress != null)
 			progress.setValue(0);
Index: c/org/openstreetmap/josm/io/OsmReaderOld.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmReaderOld.java	(revision 102)
+++ 	(revision )
@@ -1,236 +1,0 @@
-package org.openstreetmap.josm.io;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Collection;
-import java.util.StringTokenizer;
-
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
-
-/**
- * Reads the old osm 0.2 format. 
- * 
- * @author imi
- */
-public class OsmReaderOld {
-
-	/**
-	 * The data source from this reader.
-	 */
-	public Reader source;
-
-	/**
-	 * Construct a parser from a specific data source.
-	 * @param source The data source, as example a FileReader to read from a file.
-	 */
-	public OsmReaderOld(Reader source) {
-		this.source = source;
-	}
-
-	/**
-	 * Read the input stream and return a DataSet from the stream.
-	 */
-	public DataSet parse() throws JDOMException, IOException {
-		try {
-			final SAXBuilder builder = new SAXBuilder();
-			Element root = builder.build(source).getRootElement();
-			return parseDataSet(root);
-		} catch (NumberFormatException nfe) {
-			throw new JDOMException("NumberFormatException. Probably a tag is missing.", nfe);
-		} catch (NullPointerException npe) {
-			throw new JDOMException("NullPointerException. Probably a tag name mismatch.", npe);
-		} catch (ClassCastException cce) {
-			throw new JDOMException("ClassCastException. Probably a tag does not contain the correct type.", cce);
-		}
-	}
-
-
-	/**
-	 * Read one node.
-	 * @param e 	The element to parse
-	 * @return		The Waypoint read from the element
-	 * @throws JDOMException In case of a parsing error.
-	 */
-	private Node parseNode(Element e) throws JDOMException {
-		Node data = new Node(new LatLon(
-			Double.parseDouble(e.getAttributeValue("lat")),
-			Double.parseDouble(e.getAttributeValue("lon"))));
-		if (Double.isNaN(data.coor.lat()) || 
-				data.coor.lat() < -90 || data.coor.lat() > 90 ||
-				data.coor.lon() < -180 || data.coor.lon() > 180)
-			throw new JDOMException("Illegal lat or lon value: "+data.coor.lat()+"/"+data.coor.lon());
-		parseCommon(data, e);
-		return data;
-	}
-
-	/**
-	 * Parse any (yet unknown) object and return it.
-	 */
-	private OsmPrimitive parseObject(Element e, DataSet data) throws JDOMException {
-		if (e.getName().equals("node"))
-			return parseNode(e);
-		else if (e.getName().equals("segment"))
-			return parseSegment(e, data);
-		else if (e.getName().equals("way"))
-			return parseWay(e, data);
-		else if (e.getName().equals("property")) {
-			parseProperty(e, data);
-			return null;
-		}
-		throw new JDOMException("unknown tag: "+e.getName());
-	}
-	
-	/**
-	 * Read a data set from the element.
-	 * @param e 	The element to parse
-	 * @return		The DataSet read from the element
-	 * @throws JDOMException In case of a parsing error.
-	 */
-	private DataSet parseDataSet(Element e) throws JDOMException {
-		DataSet data = new DataSet();
-		AddVisitor visitor = new AddVisitor(data);
-		for (Object o : e.getChildren()) {
-			Element child = (Element)o;
-			OsmPrimitive osm = parseObject(child, data);
-			if (osm != null)
-				osm.visit(visitor);
-		}
-		
-		// clear all negative ids (new to this file)
-		for (OsmPrimitive osm : data.allPrimitives())
-			if (osm.id < 0)
-				osm.id = 0;
-
-		return data;
-	}
-
-	/**
-	 * Parse and return an segment. The node information of the "from" and
-	 * "to" attributes must already be in the dataset.
-	 * @param e		The segment element to parse.
-	 * @param data	The dataset to obtain the node information from.
-	 * @return The parsed segment.
-	 * @throws JDOMException In case of parsing errors.
-	 */
-	private Segment parseSegment(Element e, DataSet data) throws JDOMException {
-		long startId = Long.parseLong(e.getAttributeValue("from"));
-		long endId = Long.parseLong(e.getAttributeValue("to"));
-		
-		Node start = null, end = null;
-		for (Node n : data.nodes) {
-			if (n.id == startId)
-				start = n;
-			if (n.id == endId)
-				end = n;
-		}
-		if (start == null || end == null)
-			throw new JDOMException("The 'from' or 'to' object has not been transfered before.");
-		Segment ls = new Segment(start, end);
-		parseCommon(ls, e);
-		return ls;
-	}
-
-	/**
-	 * Parse and read a way from the element.
-	 *
-	 * @param e		The element that contain the way.
-	 * @param data	The DataSet to get segment information from.
-	 * @return 		The parsed way.
-	 * @throws JDOMException In case of a parsing error.
-	 */
-	private Way parseWay(Element e, DataSet data) throws JDOMException {
-		Way way = new Way();
-		parseCommon(way, e);
-		for (Object o : e.getChildren("segment")) {
-			Element child = (Element)o;
-			long id = Long.parseLong(child.getAttributeValue("uid"));
-			Segment ls = findSegment(data.segments, id);
-			way.segments.add(ls);
-		}
-		return way;
-	}
-	
-	/**
-	 * Parse the common part (properties and uid) of the element.
-	 * @param data	To store the data in. 
-	 * @param e		The element to extract the common information.
-	 * @throws JDOMException In case of a parsing error
-	 */
-	private void parseCommon(OsmPrimitive data, Element e) {
-		String suid = e.getAttributeValue("uid");
-		if (suid != null)
-			data.id = Long.parseLong(suid);
-		
-		String propStr = e.getAttributeValue("tags");
-		if (propStr != null && !propStr.equals("")) {
-			StringTokenizer st = new StringTokenizer(propStr, ";");
-			while (st.hasMoreTokens()) {
-				String next = st.nextToken();
-				if (next.trim().equals(""))
-					continue;
-				int equalPos = next.indexOf('=');
-				if (equalPos == -1)
-					data.put(next, "");
-				else {
-					String keyStr = next.substring(0, equalPos);
-					data.put(keyStr, next.substring(equalPos+1));
-				}
-			}
-		}
-		
-		String action = e.getAttributeValue("action");
-		if (action == null)
-			return;
-		if (action.equals("delete"))
-			data.delete(true);
-		else if (action.startsWith("modify"))
-			data.modified = true;
-	}
-
-	/**
-	 * Parse a property tag and assign the property to a previous found object.
-	 */
-	private void parseProperty(Element e, DataSet data) throws JDOMException {
-		long id = Long.parseLong(e.getAttributeValue("uid"));
-		OsmPrimitive osm = findObject(data, id);
-		String key = e.getAttributeValue("key");
-		String value = e.getAttributeValue("value");
-		if (value != null)
-			osm.put(key, value);
-	}
-
-	/**
-	 * Search for an object in the dataset by comparing the id.
-	 */
-	private OsmPrimitive findObject(DataSet data, long id) throws JDOMException {
-		for (OsmPrimitive osm : data.nodes)
-			if (osm.id == id)
-				return osm;
-		for (OsmPrimitive osm : data.segments)
-			if (osm.id == id)
-				return osm;
-		for (OsmPrimitive osm : data.ways)
-			if (osm.id == id)
-				return osm;
-		throw new JDOMException("Unknown object reference: "+id);
-	}
-
-	/**
-	 * Search for a segment in a collection by comparing the id.
-	 */
-	private Segment findSegment(Collection<Segment> segments, long id) throws JDOMException {
-		for (Segment ls : segments)
-			if (ls.id == id)
-				return ls;
-		throw new JDOMException("Unknown segment reference: "+id);
-	}
-}
Index: /src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 103)
@@ -2,5 +2,5 @@
 
 import java.io.IOException;
-import java.io.Reader;
+import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -8,5 +8,4 @@
 import java.util.LinkedList;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -46,5 +45,5 @@
 	 * 		ways.
 	 */
-	public Collection<Collection<GpsPoint>> parseRawGps() throws IOException, JDOMException {
+	public Collection<Collection<GpsPoint>> parseRawGps() throws IOException, SAXException {
 		try {
 			String url = Main.pref.get("osm-server.url")+"/0.3/trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";
@@ -54,9 +53,8 @@
 			for (int i = 0;;++i) {
 				currentAction.setText("Downloading points "+(i*5000)+" to "+((i+1)*5000)+"...");
-				Reader r = getReader(url+i);
-				if (r == null)
+				InputStream in = getInputStream(url+i);
+				if (in == null)
 					break;
-				RawGpsReader gpsReader = new RawGpsReader(r);
-				Collection<Collection<GpsPoint>> allWays = gpsReader.parse();
+				Collection<Collection<GpsPoint>> allWays = RawGpsReader.parse(in);
 				boolean foundSomething = false;
 				for (Collection<GpsPoint> t : allWays) {
@@ -68,5 +66,5 @@
 				if (!foundSomething)
 					break;
-				r.close();
+				in.close();
 				activeConnection = null;
 			}
@@ -78,5 +76,5 @@
 				return null;
 			throw e;
-		} catch (JDOMException e) {
+		} catch (SAXException e) {
 			throw e;
 		} catch (Exception e) {
@@ -96,10 +94,10 @@
 	public DataSet parseOsm() throws SAXException, IOException {
 		try {
-			final Reader r = getReader(Main.pref.get("osm-server.url")+"/0.3/map?bbox="+lon1+","+lat1+","+lon2+","+lat2);
-			if (r == null)
+			final InputStream in = getInputStream(Main.pref.get("osm-server.url")+"/0.3/map?bbox="+lon1+","+lat1+","+lon2+","+lat2);
+			if (in == null)
 				return null;
 			currentAction.setText("Downloading OSM data...");
-			final DataSet data = OsmReader.parseDataSet(r, currentAction, progress);
-			r.close();
+			final DataSet data = OsmReader.parseDataSet(in, currentAction, progress);
+			in.close();
 			activeConnection = null;
 			return data;
@@ -126,5 +124,5 @@
 	 * @return An reader reading the input stream (servers answer) or <code>null</code>.
 	 */
-	private Reader getReader(String urlStr) throws IOException {
+	private InputStream getInputStream(String urlStr) throws IOException {
 		System.out.println("download: "+urlStr);
 		initAuthentication();
Index: /src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 103)
@@ -2,10 +2,9 @@
 
 import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.StringWriter;
-import java.io.Writer;
+import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -14,5 +13,4 @@
 import java.util.LinkedList;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Node;
@@ -22,4 +20,5 @@
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.xml.sax.SAXException;
 
 /**
@@ -55,5 +54,5 @@
 	 * does not want to send the data.
 	 */
-	public void uploadOsm(Collection<OsmPrimitive> list) throws JDOMException {
+	public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
 		processed = new LinkedList<OsmPrimitive>();
 		initAuthentication();
@@ -73,5 +72,5 @@
 			}
 		} catch (RuntimeException e) {
-			throw new JDOMException("An error occoured: ", e);
+			throw new SAXException("An error occoured: ", e);
 		}
 	}
@@ -162,5 +161,5 @@
 
 			if (addBody) {
-				Writer out = new OutputStreamWriter(activeConnection.getOutputStream());
+				OutputStream out = activeConnection.getOutputStream();
 				OsmWriter.outputSingle(out, osm, true);
 				out.close();
@@ -176,7 +175,7 @@
 				return; // everything fine.. was already deleted.
 			if (retCode != 200) {
-				StringWriter o = new StringWriter();
+				ByteArrayOutputStream o = new ByteArrayOutputStream();
 				OsmWriter.outputSingle(o, osm, true);
-				System.out.println(o.getBuffer().toString());
+				System.out.println(new String(o.toByteArray(), "UTF-8").toString());
 				throw new RuntimeException(retCode+" "+retMsg);
 			}
Index: /src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmWriter.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/OsmWriter.java	(revision 103)
@@ -1,6 +1,8 @@
 package org.openstreetmap.josm.io;
 
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.io.Writer;
+import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.Map.Entry;
@@ -44,5 +46,5 @@
 	 * 		is lost and id's remain 0 instead of decrementing from -1)
 	 */
-	public static void output(Writer out, DataSet ds, boolean osmConform) {
+	public static void output(OutputStream out, DataSet ds, boolean osmConform) {
 		OsmWriter writer = new OsmWriter(out, osmConform);
 		writer.out.println("<?xml version='1.0' encoding='UTF-8'?>");
@@ -55,7 +57,8 @@
 			writer.visit(w);
 		writer.out.println("</osm>");
+		writer.close();
 	}
 
-	public static void outputSingle(Writer out, OsmPrimitive osm, boolean osmConform) {
+	public static void outputSingle(OutputStream out, OsmPrimitive osm, boolean osmConform) {
 		OsmWriter writer = new OsmWriter(out, osmConform);
 		writer.out.println(XmlWriter.header());
@@ -63,11 +66,13 @@
 		osm.visit(writer);
 		writer.out.println("</osm>");
+		writer.close();
 	}
 
-	private OsmWriter(Writer out, boolean osmConform) {
-		if (out instanceof PrintWriter)
-			this.out = (PrintWriter)out;
-		else
-			this.out = new PrintWriter(out);
+	private OsmWriter(OutputStream out, boolean osmConform) {
+		try {
+	        this.out = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
+        } catch (UnsupportedEncodingException e) {
+        	throw new RuntimeException(e);
+        }
 		this.osmConform = osmConform;
 	}
@@ -141,3 +146,7 @@
 		}
 	}
+
+	public void close() {
+	    out.close();
+    }
 }
Index: /src/org/openstreetmap/josm/io/ProgressReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/ProgressReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/ProgressReader.java	(revision 103)
@@ -2,4 +2,5 @@
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
@@ -13,5 +14,5 @@
  * @author Imi
  */
-public class ProgressReader extends Reader {
+public class ProgressReader extends InputStream {
 
 	private final Reader in;
@@ -36,7 +37,7 @@
 	}
 
-	@Override public int read(char[] cbuf, int off, int len) throws IOException {
-		int read = in.read(cbuf, off, len);
-		readSoFar += read;
+	@Override public int read() throws IOException {
+		int read = in.read();
+		readSoFar++;
 
 		String progStr = " ("+readSoFar+"/";
@@ -55,5 +56,4 @@
 		progress.setValue(readSoFar);
 		return read;
-	}
-
+    }
 }
Index: /src/org/openstreetmap/josm/io/RawCsvReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/RawCsvReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/RawCsvReader.java	(revision 103)
@@ -9,8 +9,8 @@
 import java.util.StringTokenizer;
 
-import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
+import org.xml.sax.SAXException;
 
 /**
@@ -29,5 +29,5 @@
 	}
 
-	public Collection<GpsPoint> parse() throws JDOMException, IOException {
+	public Collection<GpsPoint> parse() throws SAXException, IOException {
 		Collection<GpsPoint> data = new LinkedList<GpsPoint>();
 		String formatStr = Main.pref.get("csv.importstring");
@@ -35,5 +35,5 @@
 			formatStr = in.readLine();
 		if (formatStr == null)
-			throw new JDOMException("Could not detect data format string.");
+			throw new SAXException("Could not detect data format string.");
 
 		// get delimiter
@@ -58,6 +58,6 @@
 		if (!format.contains("lat") || !format.contains("lon")) {
 			if (Main.pref.get("csv.importstring").equals(""))
-				throw new JDOMException("Format string in data is incomplete or not found. Try setting an manual format string in Preferences.");
-			throw new JDOMException("Format string is incomplete. Need at least 'lat' and 'lon' specification");
+				throw new SAXException("Format string in data is incomplete or not found. Try setting an manual format string in Preferences.");
+			throw new SAXException("Format string is incomplete. Need at least 'lat' and 'lon' specification");
 		}
 
@@ -79,10 +79,10 @@
 						st.nextToken();
 					else
-						throw new JDOMException("Unknown data type: '"+token+"'."+(Main.pref.get("csv.importstring").equals("") ? " Maybe add an format string in preferences." : ""));
+						throw new SAXException("Unknown data type: '"+token+"'."+(Main.pref.get("csv.importstring").equals("") ? " Maybe add an format string in preferences." : ""));
 				}
 				data.add(new GpsPoint(new LatLon(lat, lon), time));
 			}
 		} catch (RuntimeException e) {
-			throw new JDOMException("Parsing error in line "+lineNo, e);
+			throw new SAXException("Parsing error in line "+lineNo, e);
 		}
 		return data;
Index: /src/org/openstreetmap/josm/io/RawGpsReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 102)
+++ /src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 103)
@@ -2,14 +2,15 @@
 
 import java.io.IOException;
-import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.Collection;
 import java.util.LinkedList;
 
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import uk.co.wilson.xml.MinML2;
 
 /**
@@ -20,80 +21,60 @@
 public class RawGpsReader {
 
-	/**
-	 * The data source from this reader.
-	 */
-	public Reader source;
-	
-	/**
-	 * Construct a gps reader from an input reader source.
-	 * @param source The source to read the raw gps data from. The data must be
-	 * 		in GPX format.
-	 */
-	public RawGpsReader(Reader source) {
-		this.source = source;
+	private static class Parser extends MinML2 {
+		/**
+		 * Current track to be read. The last entry is the current trkpt.
+		 * If in wpt-mode, it contain only one GpsPoint.
+		 */
+		private Collection<GpsPoint> current = new LinkedList<GpsPoint>();
+		public Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
+		private LatLon currentLatLon;
+		private String currentTime;
+
+		@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+			if (qName.equals("wpt") || qName.equals("trkpt")) {
+				try {
+	                double lat = Double.parseDouble(atts.getValue("lat"));
+	                double lon = Double.parseDouble(atts.getValue("lon"));
+	        		if (Math.abs(lat) > 90)
+	        			throw new SAXException("Data error: lat value '"+lat+"' is out of bound.");
+	        		if (Math.abs(lon) > 180)
+	        			throw new SAXException("Data error: lon value '"+lon+"' is out of bound.");
+	                currentLatLon = new LatLon(lat, lon);
+                } catch (NumberFormatException e) {
+                	e.printStackTrace();
+	                throw new SAXException(e);
+                }
+			} else if (qName.equals("time")) {
+				currentTime = "";
+			}
+		}
+
+		@Override public void characters(char[] ch, int start, int length) {
+			if (currentTime != null && currentTime.equals(""))
+				currentTime = new String(ch, start, length);
+		}
+
+		@Override public void endElement(String namespaceURI, String localName, String qName) {
+			if (qName.equals("wpt") || qName.equals("trkpt")) {
+				current.add(new GpsPoint(currentLatLon, currentTime));
+			} else if (qName.equals("trkseg") || qName.equals("trk") || qName.equals("gpx"))
+				newTrack();
+        }
+
+		private void newTrack() {
+			if (!current.isEmpty()) {
+				data.add(current);
+				current = new LinkedList<GpsPoint>();
+			}
+		}
 	}
 
 	/**
-	 * The gpx namespace.
-	 */
-	private Namespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0");
-	
-	/**
 	 * Parse and return the read data
 	 */
-	public Collection<Collection<GpsPoint>> parse() throws JDOMException, IOException {
-		final SAXBuilder builder = new SAXBuilder();
-		builder.setValidation(false);
-		Element root = builder.build(source).getRootElement();
-		return parseData(root);
-	}
-
-	/**
-	 * Parse and return the whole data thing.
-	 * @param root
-	 * @return
-	 */
-	@SuppressWarnings("unchecked")
-	private Collection<Collection<GpsPoint>> parseData(Element root) throws JDOMException {
-		Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
-
-		// workaround for bug where the server adds /gpx.asd to the namespace
-		GPX = Namespace.getNamespace(root.getNamespaceURI());
-		
-		for (Object o : root.getChildren("wpt", GPX)) {
-			Collection<GpsPoint> line = new LinkedList<GpsPoint>();
-			line.add(new GpsPoint(
-					new LatLon(parseDouble((Element)o, LatLonAttr.lat), parseDouble((Element)o, LatLonAttr.lon)),
-					((Element)o).getChildText("time", GPX)));
-			data.add(line);
-		}
-		for (Object o : root.getChildren("trk", GPX)) {
-			for (Object seg : ((Element)o).getChildren("trkseg", GPX)) {
-				Collection<GpsPoint> data1 = new LinkedList<GpsPoint>();
-				for (Object trkObj : ((Element)seg).getChildren("trkpt", GPX)) {
-					data1.add(new GpsPoint(
-							new LatLon(parseDouble((Element)trkObj, LatLonAttr.lat), parseDouble((Element)trkObj, LatLonAttr.lon)),
-							((Element)trkObj).getChildText("time", GPX)));
-				}
-				Collection<GpsPoint> line = data1;
-				if (!line.isEmpty())
-					data.add(line);
-			}
-		}
-		return data;
-	}
-
-	private enum LatLonAttr {lat, lon}
-	/**
-	 * Return a parsed float value from the element behind the object o.
-	 * @param o An object of dynamic type org.jdom.Element (will be casted).
-	 * @param attr The name of the attribute.
-	 * @throws JDOMException If the absolute of the value is out of bound.
-	 */
-	private double parseDouble(Element e, LatLonAttr attr) throws JDOMException {
-		double d = Double.parseDouble(e.getAttributeValue(attr.toString()));
-		if (Math.abs(d) > (attr == LatLonAttr.lat ? 90 : 180))
-			throw new JDOMException("Data error: "+attr+" value '"+d+"' is out of bound.");
-		return d;
+	public static Collection<Collection<GpsPoint>> parse(InputStream source) throws SAXException, IOException {
+		Parser parser = new Parser();
+		parser.parse(new InputStreamReader(source, "UTF-8"));
+		return parser.data;
 	}
 }
Index: c/org/openstreetmap/josm/test/GpxWriterTest.java
===================================================================
--- /src/org/openstreetmap/josm/test/GpxWriterTest.java	(revision 102)
+++ 	(revision )
@@ -1,84 +1,0 @@
-package org.openstreetmap.josm.test;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import junit.framework.TestCase;
-
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.io.GpxWriter;
-import org.openstreetmap.josm.test.framework.Bug;
-import org.openstreetmap.josm.test.framework.DataSetTestCaseHelper;
-
-public class GpxWriterTest extends TestCase {
-
-	private static Namespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0");
-	private static Namespace JOSM = Namespace.getNamespace("http://wiki.eigenheimstrasse.de/wiki/JOSM");
-
-	private DataSet ds;
-
-	private Element root;
-
-	/**
-	 * Verify that deleted objects that are not uploaded to the server does not show up
-	 * in gpx save output at all.
-	 */
-	@Bug(47)
-	public void testDeleteNewDoesReallyRemove() throws JDOMException, IOException {
-		ds.ways.iterator().next().delete(true);
-		root = reparse();
-		assertEquals("way has vanished and 3 trk (segments) left", 3, root.getChildren("trk", GPX).size());
-	}
-
-
-	/**
-	 * Verify, that new created elements, if and only if they occoure more than once in
-	 * the file, have a negative id attached.
-	 */
-	@Bug(47)
-	public void testNewCreateAddIdWhenMoreThanOnce() {
-		// the trk with the two trkseg's only occoure once -> no extension id
-		Element realWay = null;
-		for (Object o : root.getChildren("trk", GPX)) {
-			Element e = (Element)o;
-			if (e.getChildren("trkseg", GPX).size() != 2)
-				continue;
-			Element ext = e.getChild("extensions", GPX);
-			if (ext != null)
-				assertEquals("no id for way (used only once)", 0, ext.getChildren("uid", JOSM).size());
-			realWay = e;
-		}
-		assertNotNull("way not found in GPX file", realWay);
-
-		// the second point of the first segment of the ways has an id
-		Element trkseg = (Element)realWay.getChildren("trkseg", GPX).get(0);
-		Element trkpt = (Element)trkseg.getChildren("trkpt", GPX).get(1);
-		assertEquals("waypoint used twice but has no extensions at all", 1, trkpt.getChildren("extensions", GPX).size());
-		Element ext = trkpt.getChild("extensions", GPX);
-		assertEquals("waypoint used twice but has no id", 1, ext.getChildren("uid", JOSM).size());
-	}
-
-
-	/**
-	 * Parse the intern dataset and return the root gpx - element.
-	 */
-	private Element reparse() throws IOException, JDOMException {
-		StringWriter out = new StringWriter();
-		GpxWriter writer = new GpxWriter(out, ds);
-		writer.output();
-		Element root = new SAXBuilder().build(new StringReader(out.toString())).getRootElement();
-		return root;
-	}
-
-
-	@Override protected void setUp() throws Exception {
-		super.setUp();
-		ds = DataSetTestCaseHelper.createCommon();
-		root = reparse();
-	}
-}
Index: c/org/openstreetmap/josm/test/OsmWriterTest.java
===================================================================
--- /src/org/openstreetmap/josm/test/OsmWriterTest.java	(revision 102)
+++ 	(revision )
@@ -1,214 +1,0 @@
-package org.openstreetmap.josm.test;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.jdom.Attribute;
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.input.SAXBuilder;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.projection.Mercator;
-import org.openstreetmap.josm.io.OsmWriter;
-import org.openstreetmap.josm.test.framework.Bug;
-import org.openstreetmap.josm.test.framework.DataSetTestCaseHelper;
-
-/**
- * Test various problems with generation of OSM-XML
- * @author Imi
- */
-public class OsmWriterTest extends TestCase {
-
-	private Node n1;
-	private Node n2;
-	private Node n3;
-	private Node n4;
-	private Node n5;
-	private Segment ls1;
-	private Segment ls2;
-	private Segment ls3;
-	
-	private DataSet ds;
-	private Element osm;
-	private List<Element> nodes;
-	private List<Element> segments;
-	private List<Element> ways;
-	private StringWriter out;
-	
-	public OsmWriterTest() {
-		Main.proj = new Mercator();
-	}
-
-	public void testNode() throws Exception {
-		ds = new DataSet();
-		Node n = DataSetTestCaseHelper.createNode(ds);
-		n.id = 42;
-		reparse();
-		assertEquals(42, Long.parseLong(getAttr(osm, "node", 0, "id")));
-		assertEquals(n.coor.lat(), Double.parseDouble(getAttr(osm, "node", 0, "lat")));
-		assertEquals(n.coor.lon(), Double.parseDouble(getAttr(osm, "node", 0, "lon")));
-	}
-
-	@Bug(59)
-	public void testSpecialChars() throws Exception {
-		StringBuilder sb = new StringBuilder();
-		for (int i = 32; i < 0xd800; ++i)
-			sb.append((char)i);
-		String s = sb.toString();
-		n1.put(s, s);
-		reparse();
-		assertEquals(1, nodes.get(0).getChildren().size());
-		Attribute key = ((Element)nodes.get(0).getChildren().get(0)).getAttribute("k");
-		assertEquals(s, key.getValue());
-		Attribute value = ((Element)nodes.get(0).getChildren().get(0)).getAttribute("v");
-		assertEquals(s, value.getValue());
-	}
-	
-	public void testSegment() throws Exception {
-		ds = new DataSet();
-		Segment ls = DataSetTestCaseHelper.createSegment(ds, DataSetTestCaseHelper.createNode(ds), DataSetTestCaseHelper.createNode(ds));
-		ls.put("foo", "bar");
-		reparse();
-		assertEquals(1, segments.size());
-		assertEquals("foo", getAttr(osm.getChild("segment"), "tag", 0, "k"));
-		assertEquals("bar", getAttr(osm.getChild("segment"), "tag", 0, "v"));
-	}
-	
-	
-	/**
-	 * Test that the id generation creates unique ids and all are negative
-	 */
-	@SuppressWarnings("unchecked")
-	public void testIDGenerationUniqueNegative() {
-		Set<Long> ids = new HashSet<Long>();
-		for (Element e : (List<Element>)osm.getChildren()) {
-			long id = Long.parseLong(e.getAttributeValue("id"));
-			assertTrue("id "+id+" is negative", id < 0);
-			ids.add(id);
-		}
-		assertEquals(nodes.size()+segments.size()+ways.size(), ids.size());
-	}
-
-	/**
-	 * Verify that generated ids of higher level primitives point to the 
-	 * generated lower level ids (ways point to segments which point to nodes).
-	 */
-	@Bug(47)
-	public void testIDGenerationReferences() {
-		long id1 = Long.parseLong(getAttr(osm, "node", 0, "id"));
-		long id2 = Long.parseLong(getAttr(osm, "node", 1, "id"));
-		long lsFrom = Long.parseLong(getAttr(osm, "segment", 0, "from"));
-		long lsTo = Long.parseLong(getAttr(osm, "segment", 0, "to"));
-		assertEquals(id1, lsFrom);
-		assertEquals(id2, lsTo);
-		assertEquals(id2, lsTo);
-
-		long ls1 = Long.parseLong(getAttr(osm, "segment", 0, "id"));
-		long ls2 = Long.parseLong(getAttr(osm, "segment", 1, "id"));
-		long t1 = Long.parseLong(getAttr(osm.getChild("way"), "seg", 0, "id"));
-		long t2 = Long.parseLong(getAttr(osm.getChild("way"), "seg", 1, "id"));
-		assertEquals(ls1, t1);
-		assertEquals(ls2, t2);
-	}
-
-	/**
-	 * Verify that deleted objects that are not uploaded to the server does not show up
-	 * in xml save output at all.
-	 */
-	@Bug(47)
-	public void testDeleteNewDoesReallyRemove() throws Exception {
-		ds.ways.iterator().next().delete(true);
-		reparse();
-		//assertEquals(0, deleted.size());
-	}
-
-	
-	/**
-	 * Verify that action tag is set correctly.
-	 */
-	public void testActionTag() throws Exception {
-		int id = 1;
-		for (OsmPrimitive osm : ds.allPrimitives())
-			osm.id = id++; // make all objects "old".
-		n1.delete(true);
-		ls1.modified = true;
-		ls3.modified = true;
-		reparse();
-		
-		boolean foundNode = false;
-		for (Element n : nodes) {
-			if (n.getAttributeValue("id").equals(""+n1.id)) {
-				assertEquals("delete", n.getAttributeValue("action"));
-				foundNode = true;
-			}
-		}
-		assertTrue("Node found in output", foundNode);
-
-		boolean foundLs1 = false;
-		boolean foundLs3 = false;
-		for (Element lsElem : segments) {
-			String idStr = lsElem.getAttributeValue("id");
-			String action = lsElem.getAttributeValue("action");
-			if (idStr.equals(""+ls1.id)) {
-				assertEquals("Attribute action on modified data is ok", "modify", action);
-				foundLs1 = true;
-			} else if (idStr.equals(""+ls3.id)) {
-				assertEquals("Attribute action on modified/object data is ok", "modify", action);
-				foundLs3 = true;
-			}
-		}
-		assertTrue("Segments found in output", foundLs1 && foundLs3);
-		assertEquals("Way found in output", 1, ways.size());
-	}
-
-	@Override protected void setUp() throws Exception {
-		super.setUp();
-		
-		// create some data
-		ds = new DataSet();
-		n1 = DataSetTestCaseHelper.createNode(ds);
-		n2 = DataSetTestCaseHelper.createNode(ds);
-		n3 = DataSetTestCaseHelper.createNode(ds);
-		n4 = DataSetTestCaseHelper.createNode(ds);
-		n5 = DataSetTestCaseHelper.createNode(ds);
-		ls1 = DataSetTestCaseHelper.createSegment(ds, n1, n2);
-		ls2 = DataSetTestCaseHelper.createSegment(ds, n2, n3);
-		ls3 = DataSetTestCaseHelper.createSegment(ds, n4, n5);
-		DataSetTestCaseHelper.createWay(ds, ls1, ls2);
-		
-		reparse();
-	}
-
-	/**
-	 * Get an attribute out of an object of the root element.
-	 */
-	private String getAttr(Element root, String objName, int objPos, String attrName) {
-		Element e = (Element)root.getChildren(objName).get(objPos);
-		return e.getAttributeValue(attrName);
-	}
-
-	/**
-	 * Reparse the dataset into the lists members..
-	 */
-	@SuppressWarnings("unchecked")
-	private void reparse() throws IOException, JDOMException {
-		out = new StringWriter();
-		OsmWriter.output(out, ds, false);
-		
-		// reparse
-		osm = new SAXBuilder().build(new StringReader(out.toString())).getRootElement();
-		nodes = osm.getChildren("node");
-		segments = osm.getChildren("segment");
-		ways = osm.getChildren("way");
-	}
-}
Index: /src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java
===================================================================
--- /src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 102)
+++ /src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 103)
@@ -29,4 +29,9 @@
 		e.printStackTrace();
 		if (Main.parent != null) {
+			if (e instanceof OutOfMemoryError) {
+				JOptionPane.showMessageDialog(Main.parent, "You are out of memory. Strange things may happen.\nPlease restart JOSM and load smaller data sets.");
+				return;
+			}
+			
 			Object[] options = new String[]{"Do nothing", "Report Bug"};
 			int answer = JOptionPane.showOptionDialog(Main.parent, "An unexpected exception occoured.\n\n" +
