Index: src/org/openstreetmap/josm/actions/ExtensionFileFilter.java
===================================================================
--- src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 32)
+++ src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 32)
@@ -0,0 +1,43 @@
+package org.openstreetmap.josm.actions;
+
+import java.io.File;
+
+import javax.swing.filechooser.FileFilter;
+
+/**
+ * A file filter that filters after the extension. Also includes a list of file 
+ * filters used in JOSM.
+ * 
+ * @author imi
+ */
+public class ExtensionFileFilter extends FileFilter {
+	
+	private final String extension;
+	private final String description;
+
+	public static ExtensionFileFilter[] filters = {
+		new ExtensionFileFilter(".xml", "OSM Server Version 0.2 (.xml)"),
+		new ExtensionFileFilter(".gpx", "GPX Files Version 0.1 (.gpx)"),
+		//new ExtensionFileFilter(".josm", "JOSM Savefiles (.josm)")
+	};
+	
+	/**
+	 * Construct an extension file filter by giving the extension to check after.
+	 *
+	 */
+	private ExtensionFileFilter(String extension, String description) {
+		this.extension = extension;
+		this.description = description;
+	}
+
+	@Override
+	public boolean accept(File pathname) {
+		String name = pathname.getName().toLowerCase();
+		return pathname.isDirectory() || name.endsWith(extension);
+	}
+
+	@Override
+	public String getDescription() {
+		return description;
+	}
+}
Index: src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenAction.java	(revision 31)
+++ src/org/openstreetmap/josm/actions/OpenAction.java	(revision 32)
@@ -17,5 +17,4 @@
 import javax.swing.JPanel;
 import javax.swing.KeyStroke;
-import javax.swing.filechooser.FileFilter;
 
 import org.jdom.JDOMException;
@@ -49,14 +48,7 @@
 	public void actionPerformed(ActionEvent e) {
 		JFileChooser fc = new JFileChooser("data");
-		fc.setFileFilter(new FileFilter(){
-			@Override
-			public boolean accept(File f) {
-				String name = f.getName().toLowerCase();
-				return f.isDirectory() || name.endsWith(".gpx") || name.endsWith(".xml");
-			}
-			@Override
-			public String getDescription() {
-				return "GPX or XML Files";
-			}});
+		for (int i = 0; i < ExtensionFileFilter.filters.length; ++i)
+			fc.addChoosableFileFilter(ExtensionFileFilter.filters[i]);
+		fc.setAcceptAllFileFilterUsed(true);
 		
 		// additional options
Index: src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveAction.java	(revision 31)
+++ src/org/openstreetmap/josm/actions/SaveAction.java	(revision 32)
@@ -11,5 +11,4 @@
 import javax.swing.JOptionPane;
 import javax.swing.KeyStroke;
-import javax.swing.filechooser.FileFilter;
 
 import org.openstreetmap.josm.Main;
@@ -39,15 +38,7 @@
 		}
 		JFileChooser fc = new JFileChooser("data");
-		fc.setFileFilter(new FileFilter(){
-			@Override
-			public boolean accept(File f) {
-				String name = f.getName().toLowerCase();
-				return f.isDirectory() || name.endsWith(".xml") || name.endsWith(".gpx");
-			}
-			@Override
-			public String getDescription() {
-				return "GPX or XML Files";
-			}
-		});
+		for (int i = 0; i < ExtensionFileFilter.filters.length; ++i)
+			fc.addChoosableFileFilter(ExtensionFileFilter.filters[i]);
+		fc.setAcceptAllFileFilterUsed(true);
 		fc.showSaveDialog(Main.main);
 		File file = fc.getSelectedFile();
Index: src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 31)
+++ src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 32)
@@ -111,5 +111,6 @@
 		for (OsmPrimitive osm : selection)
 			deleteCommands.add(new DeleteCommand(Main.main.ds, osm));
-		mv.editLayer().add(new SequenceCommand(deleteCommands));
+		if (!deleteCommands.isEmpty())
+			mv.editLayer().add(new SequenceCommand(deleteCommands));
 	}
 
@@ -133,5 +134,6 @@
 				deleteCommands.add(new DeleteCommand(Main.main.ds, osm));
 		}
-		mv.editLayer().add(new SequenceCommand(deleteCommands));
+		if (!deleteCommands.isEmpty())
+			mv.editLayer().add(new SequenceCommand(deleteCommands));
 	}
 }
Index: src/org/openstreetmap/josm/command/ChangeKeyValueCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/ChangeKeyValueCommand.java	(revision 31)
+++ src/org/openstreetmap/josm/command/ChangeKeyValueCommand.java	(revision 32)
@@ -38,4 +38,9 @@
 	 */
 	private List<Map<Key, String>> oldProperties;
+	
+	/**
+	 * These are the old modified states of the data.
+	 */
+	private List<Boolean> oldModified = new LinkedList<Boolean>();
 
 	public ChangeKeyValueCommand(Collection<OsmPrimitive> objects, Key key, String value) {
@@ -48,6 +53,8 @@
 		// save old
 		oldProperties = new LinkedList<Map<Key, String>>();
-		for (OsmPrimitive osm : objects)
+		for (OsmPrimitive osm : objects) {
 			oldProperties.add(osm.keys == null ? null : new HashMap<Key, String>(osm.keys));
+			oldModified.add(osm.modified);
+		}
 			
 		if (value == null) {
@@ -70,6 +77,9 @@
 	public void undoCommand() {
 		Iterator<Map<Key, String>> it = oldProperties.iterator();
-		for (OsmPrimitive osm : objects)
+		Iterator<Boolean> itMod = oldModified.iterator();
+		for (OsmPrimitive osm : objects) {
 			osm.keys = it.next();
+			osm.modified = itMod.next();
+		}
 	}
 
Index: src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- src/org/openstreetmap/josm/command/MoveCommand.java	(revision 31)
+++ src/org/openstreetmap/josm/command/MoveCommand.java	(revision 32)
@@ -1,5 +1,4 @@
 package org.openstreetmap.josm.command;
 
-import java.awt.geom.Point2D;
 import java.util.Collection;
 import java.util.Iterator;
@@ -33,7 +32,17 @@
 
 	/**
-	 * x/y List of all old positions of the objects.
+	 * Small helper for holding the interesting part of the old data state of the
+	 * objects. 
+	 * @author imi
 	 */
-	private List<Point2D.Double> oldPositions = new LinkedList<Point2D.Double>();
+	class OldState
+	{
+		double x,y;
+		boolean modified;
+	}
+	/**
+	 * List of all old states of the objects.
+	 */
+	private List<OldState> oldState = new LinkedList<OldState>();
 
 	/**
@@ -44,6 +53,11 @@
 		this.y = y;
 		this.objects = getAffectedNodes(objects);
-		for (Node n : this.objects)
-			oldPositions.add(new Point2D.Double(n.coor.x, n.coor.y));
+		for (Node n : this.objects) {
+			OldState os = new OldState();
+			os.x = n.coor.x;
+			os.y = n.coor.y;
+			os.modified = n.modified;
+			oldState.add(os);
+		}
 	}
 
@@ -80,13 +94,15 @@
 			n.coor.x += x;
 			n.coor.y += y;
+			n.modified = true;
 		}
 	}
 
 	public void undoCommand() {
-		Iterator<Point2D.Double> it = oldPositions.iterator();
+		Iterator<OldState> it = oldState.iterator();
 		for (Node n : objects) {
-			Point2D.Double p = it.next();
-			n.coor.x = p.x;
-			n.coor.y = p.y;
+			OldState os = it.next();
+			n.coor.x = os.x;
+			n.coor.y = os.y;
+			n.modified = os.modified;
 		}
 	}
Index: src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 31)
+++ src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 32)
@@ -42,4 +42,9 @@
 	 */
 	public Collection<Track> tracks = new LinkedList<Track>();
+
+	/**
+	 * All deleted objects goes here.
+	 */
+	public Collection<OsmPrimitive> deleted = new LinkedList<OsmPrimitive>();
 
 	/**
Index: src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 31)
+++ src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 32)
@@ -32,4 +32,12 @@
 	public long id = 0;
 
+	/**
+	 * <code>true</code>, if the object has been modified since it was loaded from
+	 * the server. In this case, on next upload, this object will be updated. Deleted
+	 * objects are deleted from the server, even if they are modified. If the objects
+	 * are added (id=0), the modified is ignored and the object is added to the server. 
+	 */
+	public boolean modified = false;
+	
 	/**
 	 * If set to true, this object is currently selected.
Index: src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 31)
+++ src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 32)
@@ -26,10 +26,13 @@
 	public void visit(Node n) {
 		ds.nodes.add(n);
+		ds.deleted.remove(n); // remove if there.
 	}
 	public void visit(LineSegment ls) {
 		ds.lineSegments.add(ls);
+		ds.deleted.remove(ls); // remove if there.
 	}
 	public void visit(Track t) {
 		ds.tracks.add(t);
+		ds.deleted.remove(t); // remove if there.
 	}
 	public void visit(Key k) {}
Index: src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 31)
+++ src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 32)
@@ -25,11 +25,14 @@
 	
 	public void visit(Node n) {
-		ds.nodes.remove(n);
+		if (ds.nodes.remove(n))
+			ds.deleted.add(n);
 	}
 	public void visit(LineSegment ls) {
-		ds.lineSegments.remove(ls);
+		if (ds.lineSegments.remove(ls))
+			ds.deleted.add(ls);
 	}
 	public void visit(Track t) {
-		ds.tracks.remove(t);
+		if (ds.tracks.remove(t))
+			ds.deleted.add(t);
 	}
 	public void visit(Key k) {}
Index: src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 31)
+++ src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 32)
@@ -82,5 +82,5 @@
 	@Override
 	public String getToolTipText() {
-		return data.nodes.size()+" nodes, "+data.tracks.size()+" streets.";
+		return data.nodes.size()+" nodes, "+data.lineSegments.size()+" segments, "+data.tracks.size()+" streets.";
 	}
 
Index: src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxReader.java	(revision 31)
+++ src/org/openstreetmap/josm/io/GpxReader.java	(revision 32)
@@ -99,5 +99,5 @@
 			addNode(data, parseWaypoint((Element)o));
 	
-		// read tracks
+		// read tracks (and line segments)
 		for (Object trackElement : e.getChildren("trk", GPX))
 			parseTrack((Element)trackElement, data);
@@ -143,10 +143,7 @@
 				parseKeyValueTag(track, child);
 		}
-		if (realLineSegment && track.segments.size() == 1)
-			ds.lineSegments.add(track.segments.get(0));
-		else {
+		ds.lineSegments.addAll(track.segments);
+		if (!realLineSegment)
 			ds.tracks.add(track);
-			ds.lineSegments.addAll(track.segments);
-		}
 	}
 	
Index: src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/GpxWriter.java	(revision 31)
+++ src/org/openstreetmap/josm/io/GpxWriter.java	(revision 32)
@@ -80,7 +80,9 @@
 		Element e = new Element("gpx", GPX);
 		e.setAttribute("version", "1.0");
-		e.setAttribute("creator", "JOSM Beta2");
+		e.setAttribute("creator", "JOSM");
 		// for getting all unreferenced waypoints in the wpt-list
-		LinkedList<Node> nodes = new LinkedList<Node>(Main.main.ds.nodes);
+		LinkedList<Node> unrefNodes = new LinkedList<Node>(Main.main.ds.nodes);
+		// for getting all unreferenced line segments
+		LinkedList<LineSegment> unrefLs = new LinkedList<LineSegment>(Main.main.ds.lineSegments);
 
 		// tracks
@@ -101,6 +103,7 @@
 			for (LineSegment ls : t.segments) {
 				tElem.getChildren().add(parseLineSegment(ls));
-				nodes.remove(ls.start);
-				nodes.remove(ls.end);
+				unrefNodes.remove(ls.start);
+				unrefNodes.remove(ls.end);
+				unrefLs.remove(ls);
 			}
 
@@ -109,9 +112,9 @@
 		
 		// encode pending line segments as tracks
-		for (LineSegment ls : Main.main.ds.lineSegments) {
+		for (LineSegment ls : unrefLs) {
 			Element t = new Element("trk", GPX);
 			t.getChildren().add(parseLineSegment(ls));
-			nodes.remove(ls.start);
-			nodes.remove(ls.end);
+			unrefNodes.remove(ls.start);
+			unrefNodes.remove(ls.end);
 			Element ext = new Element("extensions", GPX);
 			ext.getChildren().add(new Element("segment", OSM));
@@ -121,5 +124,5 @@
 
 		// waypoints (missing nodes)
-		for (Node n : nodes)
+		for (Node n : unrefNodes)
 			e.getChildren().add(parseWaypoint(n, "wpt"));
 
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 31)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 32)
@@ -120,7 +120,4 @@
 				if (data.lineSegments.contains(ls))
 					throw new JDOMException("Double segment definition "+ls.id);
-				for (Track t : data.tracks)
-					if (t.segments.contains(ls))
-						throw new JDOMException("Double segment definition "+ls.id);
 				data.lineSegments.add(ls);
 			} else if (child.getName().equals("track")) {
@@ -176,16 +173,5 @@
 			long id = Long.parseLong(child.getAttributeValue("uid"));
 			LineSegment ls = findLineSegment(data.lineSegments, id);
-			if (ls != null) {
-				track.segments.add(ls);
-				data.lineSegments.remove(ls);
-				continue;
-			}
-			for (Track t : data.tracks) {
-				ls = findLineSegment(t.segments, id);
-				if (ls != null) {
-					track.segments.add(ls);
-					break;
-				}
-			}
+			track.segments.add(ls);
 		}
 		return track;
@@ -195,9 +181,9 @@
 	 * Search for a segment in a collection by comparing the id.
 	 */
-	private LineSegment findLineSegment(Collection<LineSegment> segments, long id) {
+	private LineSegment findLineSegment(Collection<LineSegment> segments, long id) throws JDOMException {
 		for (LineSegment ls : segments)
 			if (ls.id == id)
 				return ls;
-		return null;
+		throw new JDOMException("Unknown line segment reference: "+id);
 	}
 	
Index: src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmWriter.java	(revision 31)
+++ src/org/openstreetmap/josm/io/OsmWriter.java	(revision 32)
@@ -63,10 +63,4 @@
 			list.add(parseNode(n, properties));
 		for (LineSegment ls : ds.lineSegments)
-			list.add(parseLineSegment(ls, properties));
-		// all other line segments
-		Collection<LineSegment> lineSegments = new HashSet<LineSegment>();
-		for (Track t : ds.tracks)
-			lineSegments.addAll(t.segments);
-		for (LineSegment ls : lineSegments)
 			list.add(parseLineSegment(ls, properties));
 		for (Track t : ds.tracks)
