Index: /.classpath
===================================================================
--- /.classpath	(revision 85)
+++ /.classpath	(revision 86)
@@ -2,5 +2,4 @@
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="test"/>
 	<classpathentry including="images/" excluding="*" kind="src" path=""/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
Index: /.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /.settings/org.eclipse.jdt.core.prefs	(revision 85)
+++ /.settings/org.eclipse.jdt.core.prefs	(revision 86)
@@ -1,3 +1,3 @@
-#Mon Apr 03 21:11:54 CEST 2006
+#Fri Apr 21 12:51:47 CEST 2006
 eclipse.preferences.version=1
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
@@ -68,5 +68,5 @@
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
 org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
Index: /.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- /.settings/org.eclipse.jdt.ui.prefs	(revision 85)
+++ /.settings/org.eclipse.jdt.ui.prefs	(revision 86)
@@ -1,3 +1,3 @@
-#Mon Apr 03 21:08:35 CEST 2006
+#Fri Apr 21 12:51:47 CEST 2006
 eclipse.preferences.version=1
 formatter_profile=_josm
Index: /src/org/openstreetmap/josm/Main.java
===================================================================
--- /src/org/openstreetmap/josm/Main.java	(revision 85)
+++ /src/org/openstreetmap/josm/Main.java	(revision 86)
@@ -78,5 +78,5 @@
 	 * The global dataset.
 	 */
-	public DataSet ds = new DataSet();
+	public static DataSet ds = new DataSet();
 	
 	/**
@@ -176,6 +176,5 @@
 	
 		addWindowListener(new WindowAdapter(){
-			@Override
-			public void windowClosing(WindowEvent arg0) {
+			@Override public void windowClosing(WindowEvent arg0) {
 				if (mapFrame != null) {
 					boolean modified = false;
@@ -217,12 +216,12 @@
 			System.out.println();
 			System.out.println("usage:");
-			System.out.println("\tjava -jar josm.jar <options>");
+			System.out.println("\tjava -jar josm.jar <options> file file file...");
 			System.out.println();
 			System.out.println("options:");
 			System.out.println("\t--help                                  Show this help");
 			System.out.println("\t--download=minlat,minlon,maxlat,maxlon  Download the bounding box");
-			System.out.println("\t--open=file(.osm|.xml|.gpx|.txt|.csv)   Open the specific file");
 			System.out.println("\t--no-fullscreen                         Don't launch in fullscreen mode");
 			System.out.println("\t--reset-preferences                     Reset the preferences to default");
+			System.out.println("file(.osm|.xml|.gpx|.txt|.csv)            Open the specific file");
 			System.exit(0);
 		}
@@ -287,8 +286,5 @@
 		for (Iterator<String> it = arguments.iterator(); it.hasNext();) {
 			String s = it.next();
-			if (s.startsWith("--open=")) {
-				main.openAction.openFile(new File(s.substring(7)));
-				it.remove();
-			} else if (s.startsWith("--download=")) {
+			if (s.startsWith("--download=")) {
 				downloadFromParamString(false, s.substring(11));
 				it.remove();
@@ -299,10 +295,6 @@
 		}
 		
-		if (!arguments.isEmpty()) {
-			String s = "Unknown Parameter:\n";
-			for (String arg : arguments)
-				s += arg+"\n";
-			JOptionPane.showMessageDialog(main, s);
-		}
+		for (String s : arguments)
+			main.openAction.openFile(new File(s));
 	}
 
Index: /src/org/openstreetmap/josm/actions/DiskAccessAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/DiskAccessAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/DiskAccessAction.java	(revision 86)
@@ -28,6 +28,6 @@
 	 */
 	protected boolean isDataSetEmpty() {
-		for (OsmPrimitive osm : Main.main.ds.allNonDeletedPrimitives())
-			if (!osm.isDeleted() || osm.id > 0)
+		for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives())
+			if (!osm.deleted || osm.id > 0)
 				return false;
 		return true;
Index: /src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 86)
@@ -69,6 +69,5 @@
 	    }
 
-	    @Override
-	    public void realRun() throws IOException, SAXException {
+	    @Override public void realRun() throws IOException, SAXException {
     		dataSet = reader.parseOsm();
     		if (dataSet == null)
@@ -78,6 +77,5 @@
 	    }
 
-		@Override
-        protected void finish() {
+		@Override protected void finish() {
 			if (dataSet == null)
 				return; // user cancelled download or error occoured
@@ -101,11 +99,9 @@
 	    }
 
-	    @Override
-	    public void realRun() throws IOException, JDOMException {
+	    @Override public void realRun() throws IOException, JDOMException {
     		rawData = reader.parseRawGps();
 	    }
 
-		@Override
-        protected void finish() {
+		@Override protected void finish() {
 			if (rawData == null)
 				return;
@@ -188,6 +184,5 @@
 		dlg.add(osmUrl, GBC.eop().fill(GBC.HORIZONTAL));
 		final KeyListener osmUrlRefresher = new KeyAdapter(){
-			@Override
-			public void keyTyped(KeyEvent e) {
+			@Override public void keyTyped(KeyEvent e) {
 				SwingUtilities.invokeLater(new Runnable() {
 					public void run() {
@@ -223,6 +218,5 @@
 		SwingUtilities.invokeLater(new Runnable() {public void run() {osmUrlRefresher.keyTyped(null);}});
 		osmUrl.addKeyListener(new KeyAdapter(){
-			@Override
-			public void keyTyped(KeyEvent e) {
+			@Override public void keyTyped(KeyEvent e) {
 				SwingUtilities.invokeLater(new Runnable() {
 					public void run() {
Index: /src/org/openstreetmap/josm/actions/ExtensionFileFilter.java
===================================================================
--- /src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 86)
@@ -45,6 +45,5 @@
 	}
 
-	@Override
-	public boolean accept(File pathname) {
+	@Override public boolean accept(File pathname) {
 		if (pathname.isDirectory())
 			return true;
@@ -52,6 +51,5 @@
 	}
 
-	@Override
-	public String getDescription() {
+	@Override public String getDescription() {
 		return description;
 	}
Index: /src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 86)
@@ -121,5 +121,5 @@
 				w.output(((RawGpsDataLayer)layer).data);
 			else
-				w.output(Main.main.ds);
+				w.output(Main.ds);
 			out.close();
 		} catch (IOException x) {
Index: /src/org/openstreetmap/josm/actions/SaveAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/SaveAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/SaveAction.java	(revision 86)
@@ -14,5 +14,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.io.GpxWriter;
 import org.openstreetmap.josm.io.OsmWriter;
@@ -41,4 +41,10 @@
 		if (isDataSetEmpty() && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.main, "The document contains no data. Save anyway?", "Empty document", JOptionPane.YES_NO_OPTION))
 			return;
+		if (!Main.main.getMapFrame().conflictDialog.conflicts.isEmpty()) {
+			int answer = JOptionPane.showConfirmDialog(Main.main, 
+					"There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?", "Conflicts", JOptionPane.YES_NO_OPTION);
+			if (answer != JOptionPane.YES_OPTION)
+				return;
+		}
 
 		JFileChooser fc = createAndOpenFileChooser(false, false);
@@ -60,5 +66,5 @@
 			FileWriter fileWriter;
 			if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-				for (LineSegment ls : Main.main.ds.lineSegments) {
+				for (Segment ls : Main.ds.segments) {
 					if (ls.incomplete) {
 						JOptionPane.showMessageDialog(Main.main, "Export of data containing incomplete ways to GPX is not implemented.\nBe aware, that in future versions of JOSM, GPX support will be kept at a minimum.\nPlease use .osm or .xml as extension for the better OSM support.");
@@ -66,7 +72,7 @@
 					}
 				}
-				new GpxWriter(fileWriter = new FileWriter(file), Main.main.ds).output();
+				new GpxWriter(fileWriter = new FileWriter(file), Main.ds).output();
 			} else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn))
-				OsmWriter.output(fileWriter = new FileWriter(file), Main.main.ds, false);
+				OsmWriter.output(fileWriter = new FileWriter(file), Main.ds, false);
 			else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
 				JOptionPane.showMessageDialog(Main.main, "CSV output not supported yet.");
Index: /src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/UploadAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/UploadAction.java	(revision 86)
@@ -58,10 +58,10 @@
 		final Collection<OsmPrimitive> update = new LinkedList<OsmPrimitive>();
 		final Collection<OsmPrimitive> delete = new LinkedList<OsmPrimitive>();
-		for (OsmPrimitive osm : Main.main.ds.allPrimitives()) {
-			if (osm.id == 0 && !osm.isDeleted())
+		for (OsmPrimitive osm : Main.ds.allPrimitives()) {
+			if (osm.id == 0 && !osm.deleted)
 				add.add(osm);
-			else if ((osm.modified || osm.modifiedProperties) && !osm.isDeleted())
+			else if (osm.modified && !osm.deleted)
 				update.add(osm);
-			else if (osm.isDeleted() && osm.id != 0)
+			else if (osm.deleted && osm.id != 0)
 				delete.add(osm);
 		}
@@ -77,10 +77,8 @@
 		
 		PleaseWaitRunnable uploadTask = new PleaseWaitRunnable("Uploading data"){
-        			@Override
-        			protected void realRun() throws JDOMException {
+        			@Override protected void realRun() throws JDOMException {
         				server.uploadOsm(all);
         			}
-        			@Override
-                    protected void finish() {
+        			@Override protected void finish() {
         				Main.main.getMapFrame().mapView.editLayer().cleanData(server.processed, !add.isEmpty());
                     }
Index: /src/org/openstreetmap/josm/actions/WmsServerAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/WmsServerAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/WmsServerAction.java	(revision 86)
@@ -31,5 +31,5 @@
                         if (mv.getAllLayers().size() == 1) {
                             Main.main.setMapFrame(null);
-                            Main.main.ds = new DataSet();
+                            Main.ds = new DataSet();
                         } else
                             mv.removeLayer(l);
Index: c/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java	(revision 85)
+++ 	(revision )
@@ -1,169 +1,0 @@
-package org.openstreetmap.josm.actions.mapmode;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Point;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.data.osm.LineSegment;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.MapFrame;
-
-/**
- * The user can add a new line segment between two nodes by pressing on the 
- * starting node and dragging to the ending node. 
- * 
- * No line segment can be created if there is already a line segment containing
- * both nodes.
- * 
- * @author imi
- */
-public class AddLineSegmentAction extends MapMode implements MouseListener {
-
-	/**
-	 * The first node the user pressed the button onto.
-	 */
-	private Node first;
-	/**
-	 * The second node used if the user releases the button.
-	 */
-	private Node second;
-
-	/**
-	 * Whether the hint is currently drawn on screen.
-	 */
-	private boolean hintDrawn = false;
-	
-	/**
-	 * Create a new AddLineSegmentAction.
-	 * @param mapFrame The MapFrame this action belongs to.
-	 */
-	public AddLineSegmentAction(MapFrame mapFrame) {
-		super("Add Line Segment", "addlinesegment", "Add a line segment between two nodes.", "G", KeyEvent.VK_G, mapFrame);
-	}
-
-	@Override
-	public void registerListener() {
-		super.registerListener();
-		mv.addMouseListener(this);
-		mv.addMouseMotionListener(this);
-	}
-
-	@Override
-	public void unregisterListener() {
-		super.unregisterListener();
-		mv.removeMouseListener(this);
-		mv.removeMouseMotionListener(this);
-		drawHint(false);
-	}
-
-	
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		super.actionPerformed(e);
-		makeLineSegment();
-	}
-
-	/**
-	 * If user clicked on a node, from the dragging with that node. 
-	 */
-	@Override
-	public void mousePressed(MouseEvent e) {
-		if (e.getButton() != MouseEvent.BUTTON1)
-			return;
-
-		OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
-		if (clicked == null || !(clicked instanceof Node))
-			return;
-
-		drawHint(false);
-		first = second = (Node)clicked;
-	}
-
-	/**
-	 * Draw a hint which nodes will get connected if the user release
-	 * the mouse button now.
-	 */
-	@Override
-	public void mouseDragged(MouseEvent e) {
-		if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
-			return;
-
-		OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
-		if (clicked == null || clicked == second || !(clicked instanceof Node))
-			return;
-
-		drawHint(false);
-
-		second = (Node)clicked;
-		drawHint(true);
-	}
-
-	/**
-	 * If left button was released, try to create the line segment.
-	 */
-	@Override
-	public void mouseReleased(MouseEvent e) {
-		if (e.getButton() == MouseEvent.BUTTON1) {
-			makeLineSegment();
-			first = null; // release line segment drawing
-		}
-	}
-
-	/**
-	 * Create the line segment if first and second are different and there is
-	 * not already a line segment.
-	 */
-	private void makeLineSegment() {
-		if (first == null || second == null) {
-			first = null;
-			second = null;
-			return;
-		}
-
-		drawHint(false);
-		
-		Node start = first;
-		Node end = second;
-		first = second;
-		second = null;
-		
-		if (start != end) {
-			// try to find a line segment
-			for (LineSegment ls : Main.main.ds.lineSegments)
-				if ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to))
-					return; // already a line segment here - be happy, do nothing.
-
-			LineSegment ls = new LineSegment(start, end);
-			mv.editLayer().add(new AddCommand(Main.main.ds, ls));
-		}
-
-		mv.repaint();
-	}
-
-	/**
-	 * Draw or remove the hint line, depending on the parameter.
-	 */
-	private void drawHint(boolean draw) {
-		if (draw == hintDrawn)
-			return;
-		if (first == null || second == null)
-			return;
-		if (second == first)
-			return;
-
-		Graphics g = mv.getGraphics();
-		g.setColor(Color.BLACK);
-		g.setXORMode(Color.WHITE);
-		Point firstDrawn = mv.getPoint(first.eastNorth);
-		Point secondDrawn = mv.getPoint(second.eastNorth);
-		g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
-		hintDrawn = !hintDrawn;
-	}
-}
Index: /src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 86)
@@ -27,12 +27,10 @@
 	}
 
-	@Override
-	public void registerListener() {
+	@Override public void registerListener() {
 		super.registerListener();
 		mv.addMouseListener(this);
 	}
 
-	@Override
-	public void unregisterListener() {
+	@Override public void unregisterListener() {
 		super.unregisterListener();
 		mv.removeMouseListener(this);
@@ -43,6 +41,5 @@
 	 * position.
 	 */
-	@Override
-	public void mouseClicked(MouseEvent e) {
+	@Override public void mouseClicked(MouseEvent e) {
 		if (e.getButton() == MouseEvent.BUTTON1) {
 			Node node = new Node(mv.getLatLon(e.getX(), e.getY()));
@@ -51,5 +48,5 @@
 				return;
 			}
-			mv.editLayer().add(new AddCommand(Main.main.ds, node));
+			mv.editLayer().add(new AddCommand(Main.ds, node));
 			mv.repaint();
 		}
Index: /src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 86)
+++ /src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 86)
@@ -0,0 +1,163 @@
+package org.openstreetmap.josm.actions.mapmode;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.AddCommand;
+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.gui.MapFrame;
+
+/**
+ * The user can add a new segment between two nodes by pressing on the 
+ * starting node and dragging to the ending node. 
+ * 
+ * No segment can be created if there is already a segment containing
+ * both nodes.
+ * 
+ * @author imi
+ */
+public class AddSegmentAction extends MapMode implements MouseListener {
+
+	/**
+	 * The first node the user pressed the button onto.
+	 */
+	private Node first;
+	/**
+	 * The second node used if the user releases the button.
+	 */
+	private Node second;
+
+	/**
+	 * Whether the hint is currently drawn on screen.
+	 */
+	private boolean hintDrawn = false;
+	
+	/**
+	 * Create a new AddSegmentAction.
+	 * @param mapFrame The MapFrame this action belongs to.
+	 */
+	public AddSegmentAction(MapFrame mapFrame) {
+		super("Add segment", "addlinesegment", "Add a segment between two nodes.", "G", KeyEvent.VK_G, mapFrame);
+	}
+
+	@Override public void registerListener() {
+		super.registerListener();
+		mv.addMouseListener(this);
+		mv.addMouseMotionListener(this);
+	}
+
+	@Override public void unregisterListener() {
+		super.unregisterListener();
+		mv.removeMouseListener(this);
+		mv.removeMouseMotionListener(this);
+		drawHint(false);
+	}
+
+	
+	@Override public void actionPerformed(ActionEvent e) {
+		super.actionPerformed(e);
+		makeSegment();
+	}
+
+	/**
+	 * If user clicked on a node, from the dragging with that node. 
+	 */
+	@Override public void mousePressed(MouseEvent e) {
+		if (e.getButton() != MouseEvent.BUTTON1)
+			return;
+
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), true);
+		if (clicked == null || !(clicked instanceof Node))
+			return;
+
+		drawHint(false);
+		first = second = (Node)clicked;
+	}
+
+	/**
+	 * Draw a hint which nodes will get connected if the user release
+	 * the mouse button now.
+	 */
+	@Override public void mouseDragged(MouseEvent e) {
+		if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
+			return;
+
+		OsmPrimitive clicked = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		if (clicked == null || clicked == second || !(clicked instanceof Node))
+			return;
+
+		drawHint(false);
+
+		second = (Node)clicked;
+		drawHint(true);
+	}
+
+	/**
+	 * If left button was released, try to create the segment.
+	 */
+	@Override public void mouseReleased(MouseEvent e) {
+		if (e.getButton() == MouseEvent.BUTTON1) {
+			makeSegment();
+			first = null; // release segment drawing
+		}
+	}
+
+	/**
+	 * Create the segment if first and second are different and there is
+	 * not already a segment.
+	 */
+	private void makeSegment() {
+		if (first == null || second == null) {
+			first = null;
+			second = null;
+			return;
+		}
+
+		drawHint(false);
+		
+		Node start = first;
+		Node end = second;
+		first = second;
+		second = null;
+		
+		if (start != end) {
+			// try to find a segment
+			for (Segment ls : Main.ds.segments)
+				if ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to))
+					return; // already a segment here - be happy, do nothing.
+
+			Segment ls = new Segment(start, end);
+			mv.editLayer().add(new AddCommand(Main.ds, ls));
+		}
+
+		mv.repaint();
+	}
+
+	/**
+	 * Draw or remove the hint line, depending on the parameter.
+	 */
+	private void drawHint(boolean draw) {
+		if (draw == hintDrawn)
+			return;
+		if (first == null || second == null)
+			return;
+		if (second == first)
+			return;
+
+		Graphics g = mv.getGraphics();
+		g.setColor(Color.BLACK);
+		g.setXORMode(Color.WHITE);
+		Point firstDrawn = mv.getPoint(first.eastNorth);
+		Point secondDrawn = mv.getPoint(second.eastNorth);
+		g.drawLine(firstDrawn.x, firstDrawn.y, secondDrawn.x, secondDrawn.y);
+		hintDrawn = !hintDrawn;
+	}
+}
Index: /src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 86)
@@ -11,5 +11,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
@@ -17,13 +17,13 @@
 
 /**
- * Add a new way from all selected line segments.
+ * Add a new way from all selected segments.
  *
- * If there is a selection when the mode is entered, all line segments in this
+ * If there is a selection when the mode is entered, all segments in this
  * selection form a new way, except the user holds down Shift.
  *
- * The user can click on a line segment. If he holds down Shift, no way is 
+ * The user can click on a segment. If he holds down Shift, no way is 
  * created yet. If he holds down Alt, the whole way is considered instead of 
- * the clicked line segment. If the user holds down Ctrl, no way is created 
- * and the clicked line segment get removed from the list.
+ * the clicked segment. If the user holds down Ctrl, no way is created 
+ * and the clicked segment get removed from the list.
  *
  * Also, the user may select a rectangle as in selection mode. No node, area or
@@ -47,6 +47,5 @@
 	}
 
-	@Override
-	public void actionPerformed(ActionEvent e) {
+	@Override public void actionPerformed(ActionEvent e) {
 		makeWay();
 		super.actionPerformed(e);
@@ -58,16 +57,16 @@
 	 */
 	private void makeWay() {
-		Collection<OsmPrimitive> selection = Main.main.ds.getSelected();
+		Collection<OsmPrimitive> selection = Main.ds.getSelected();
 		if (selection.isEmpty())
 			return;
 
 		// form a new way
-		LinkedList<LineSegment> lineSegments = new LinkedList<LineSegment>();
+		LinkedList<Segment> segments = new LinkedList<Segment>();
 		int numberOfSelectedWays = 0;
 		for (OsmPrimitive osm : selection) {
 			if (osm instanceof Way)
 				numberOfSelectedWays++;
-			else if (osm instanceof LineSegment)
-				lineSegments.add((LineSegment)osm);
+			else if (osm instanceof Segment)
+				segments.add((Segment)osm);
 		}
 		
@@ -81,9 +80,9 @@
 				for (OsmPrimitive osm : selection)
 					if (osm instanceof Way)
-						lineSegments.addAll(((Way)osm).segments);
+						segments.addAll(((Way)osm).segments);
 			}
 		}
 		
-		// sort the line segments in best possible order. This is done by:
+		// sort the segments in best possible order. This is done by:
 		// 0  if no elements in list, quit
 		// 1  taking the first ls as pivot, remove it from list
@@ -91,13 +90,13 @@
 		// 3  if found, attach it, remove it from list, goto 2
 		// 4  if not found, save the pivot-string and goto 0
-		LinkedList<LineSegment> sortedLineSegments = new LinkedList<LineSegment>();
-		while (!lineSegments.isEmpty()) {
-			LinkedList<LineSegment> pivotList = new LinkedList<LineSegment>();
-			pivotList.add(lineSegments.getFirst());
-			lineSegments.removeFirst();
+		LinkedList<Segment> sortedSegments = new LinkedList<Segment>();
+		while (!segments.isEmpty()) {
+			LinkedList<Segment> pivotList = new LinkedList<Segment>();
+			pivotList.add(segments.getFirst());
+			segments.removeFirst();
 			for (boolean found = true; found;) {
 				found = false;
-				for (Iterator<LineSegment> it = lineSegments.iterator(); it.hasNext();) {
-					LineSegment ls = it.next();
+				for (Iterator<Segment> it = segments.iterator(); it.hasNext();) {
+					Segment ls = it.next();
 					if (ls.incomplete)
 						continue; // incomplete segments are never added to a new way
@@ -113,11 +112,11 @@
 				}
 			}
-			sortedLineSegments.addAll(pivotList);
+			sortedSegments.addAll(pivotList);
 		}
 		
 		Way t = new Way();
-		t.segments.addAll(sortedLineSegments);
-		mv.editLayer().add(new AddCommand(Main.main.ds, t));
-		Main.main.ds.clearSelection();
+		t.segments.addAll(sortedSegments);
+		mv.editLayer().add(new AddCommand(Main.ds, t));
+		Main.ds.clearSelection();
 		mv.repaint();
 	}
Index: /src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 86)
@@ -26,5 +26,5 @@
  * @see #deleteWithReferences(OsmPrimitive)
  *
- * Pressing Alt will select the way instead of a line segment, as usual.
+ * Pressing Alt will select the way instead of a segment, as usual.
  * 
  * If the user did not press Ctrl and the object has any references, the user
@@ -46,12 +46,10 @@
 	}
 
-	@Override
-	public void registerListener() {
+	@Override public void registerListener() {
 		super.registerListener();
 		mv.addMouseListener(this);
 	}
 
-	@Override
-	public void unregisterListener() {
+	@Override public void unregisterListener() {
 		super.unregisterListener();
 		mv.removeMouseListener(this);
@@ -59,12 +57,11 @@
 
 	
-	@Override
-	public void actionPerformed(ActionEvent e) {
+	@Override public void actionPerformed(ActionEvent e) {
 		super.actionPerformed(e);
 		boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
 		if (ctrl)
-			deleteWithReferences(Main.main.ds.getSelected());
+			deleteWithReferences(Main.ds.getSelected());
 		else
-			delete(Main.main.ds.getSelected(), false);
+			delete(Main.ds.getSelected(), false);
 		mv.repaint();
 	}
@@ -74,6 +71,5 @@
 	 * position.
 	 */
-	@Override
-	public void mouseClicked(MouseEvent e) {
+	@Override public void mouseClicked(MouseEvent e) {
 		if (e.getButton() != MouseEvent.BUTTON1)
 			return;
@@ -94,11 +90,11 @@
 	 * Delete the primitives and everything they references.
 	 * 
-	 * If a node is deleted, the node and all line segments, ways and areas
+	 * If a node is deleted, the node and all segments, ways and areas
 	 * the node is part of are deleted as well.
 	 * 
-	 * If a line segment is deleted, all ways the line segment is part of 
+	 * If a segment is deleted, all ways the segment is part of 
 	 * are deleted as well. No nodes are deleted.
 	 * 
-	 * If a way is deleted, only the way and no line segments or nodes are 
+	 * If a way is deleted, only the way and no segments or nodes are 
 	 * deleted.
 	 * 
@@ -110,5 +106,5 @@
 		Collection<Command> deleteCommands = new LinkedList<Command>();
 		for (OsmPrimitive osm : selection)
-			deleteCommands.add(new DeleteCommand(Main.main.ds, osm));
+			deleteCommands.add(new DeleteCommand(osm));
 		if (!deleteCommands.isEmpty())
 			mv.editLayer().add(new SequenceCommand(deleteCommands));
@@ -126,5 +122,5 @@
 		Collection<Command> deleteCommands = new LinkedList<Command>();
 		for (OsmPrimitive osm : selection) {
-			CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.main.ds);
+			CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
 			osm.visit(v);
 			if (!selection.containsAll(v.data)) {
@@ -132,5 +128,5 @@
 					JOptionPane.showMessageDialog(Main.main, "This object is in use.");
 			} else
-				deleteCommands.add(new DeleteCommand(Main.main.ds, osm));
+				deleteCommands.add(new DeleteCommand(osm));
 		}
 		if (!deleteCommands.isEmpty())
Index: /src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 86)
@@ -14,5 +14,5 @@
 /**
  * A class implementing MapMode is able to be selected as an mode for map editing.
- * As example scrolling the map is a MapMode, connecting Nodes to new LineSegments
+ * As example scrolling the map is a MapMode, connecting Nodes to new Segments
  * is another.
  * 
Index: /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 86)
@@ -5,4 +5,5 @@
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.util.Arrays;
 import java.util.Collection;
 
@@ -51,6 +52,5 @@
 	}
 
-	@Override
-	public void registerListener() {
+	@Override public void registerListener() {
 		super.registerListener();
 		mv.addMouseListener(this);
@@ -58,6 +58,5 @@
 	}
 
-	@Override
-	public void unregisterListener() {
+	@Override public void unregisterListener() {
 		super.unregisterListener();
 		mv.removeMouseListener(this);
@@ -70,6 +69,5 @@
 	 * objects.
 	 */
-	@Override
-	public void mouseDragged(MouseEvent e) {
+	@Override public void mouseDragged(MouseEvent e) {
 		if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
 			return;
@@ -87,5 +85,5 @@
 			return;
 
-		Collection<OsmPrimitive> selection = Main.main.ds.getSelected();
+		Collection<OsmPrimitive> selection = Main.ds.getSelected();
 		Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
 		
@@ -117,13 +115,12 @@
 	 * cursor to movement.
 	 */
-	@Override
-	public void mousePressed(MouseEvent e) {
+	@Override public void mousePressed(MouseEvent e) {
 		if (e.getButton() != MouseEvent.BUTTON1)
 			return;
 
-		if (Main.main.ds.getSelected().size() == 0) {
+		if (Main.ds.getSelected().size() == 0) {
 			OsmPrimitive osm = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
 			if (osm != null)
-				osm.setSelected(true);
+				Main.ds.setSelected(Arrays.asList(new OsmPrimitive[]{osm}));
 			singleOsmPrimitive = osm;
 			mv.repaint();
@@ -139,9 +136,8 @@
 	 * Restore the old mouse cursor.
 	 */
-	@Override
-	public void mouseReleased(MouseEvent e) {
+	@Override public void mouseReleased(MouseEvent e) {
 		mv.setCursor(oldCursor);
 		if (singleOsmPrimitive != null) {
-			singleOsmPrimitive.setSelected(false);
+			Main.ds.clearSelection();
 			mv.repaint();
 		}
Index: /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 86)
@@ -4,4 +4,5 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
+import java.util.LinkedList;
 
 import org.openstreetmap.josm.Main;
@@ -43,6 +44,6 @@
  * pixel are considered "only click". If that happens, the nearest Node will
  * be selected if there is any within 10 pixel range. If there is no Node within
- * 10 pixel, the nearest LineSegment (or Street, if user hold down the Alt-Key)
- * within 10 pixel range is selected. If there is no LineSegment within 10 pixel
+ * 10 pixel, the nearest Segment (or Street, if user hold down the Alt-Key)
+ * within 10 pixel range is selected. If there is no Segment within 10 pixel
  * and the user clicked in or 10 pixel away from an area, this area is selected. 
  * If there is even no area, nothing is selected. Shift and Ctrl key applies to 
@@ -67,12 +68,10 @@
 	}
 
-	@Override
-	public void registerListener() {
+	@Override public void registerListener() {
 		super.registerListener();
 		selectionManager.register(mv);
 	}
 
-	@Override
-	public void unregisterListener() {
+	@Override public void unregisterListener() {
 		super.unregisterListener();
 		selectionManager.unregister(mv);
@@ -87,10 +86,17 @@
 			return; // not allowed together
 
+		Collection<OsmPrimitive> curSel;
 		if (!ctrl && !shift)
-			Main.main.ds.clearSelection(); // new selection will replace the old.
+			curSel = new LinkedList<OsmPrimitive>(); // new selection will replace the old.
+		else
+			curSel = Main.ds.getSelected(); 
 
 		Collection<OsmPrimitive> selectionList = selectionManager.getObjectsInRectangle(r,alt);
 		for (OsmPrimitive osm : selectionList)
-			osm.setSelected(!ctrl);
+			if (ctrl)
+				curSel.remove(osm);
+			else
+				curSel.add(osm);
+		Main.ds.setSelected(curSel);
 		mv.repaint();
 	}
Index: /src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 85)
+++ /src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java	(revision 86)
@@ -57,12 +57,10 @@
 	}
 
-	@Override
-	public void registerListener() {
+	@Override public void registerListener() {
 		super.registerListener();
 		selectionManager.register(mv);
 	}
 
-	@Override
-	public void unregisterListener() {
+	@Override public void unregisterListener() {
 		super.unregisterListener();
 		selectionManager.unregister(mv);
Index: /src/org/openstreetmap/josm/command/AddCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/AddCommand.java	(revision 85)
+++ /src/org/openstreetmap/josm/command/AddCommand.java	(revision 86)
@@ -14,5 +14,5 @@
  * @author imi
  */
-public class AddCommand implements Command {
+public class AddCommand extends Command {
 
 	/**
@@ -34,13 +34,13 @@
 	}
 
-	public void executeCommand() {
+	@Override public void executeCommand() {
 		osm.visit(new AddVisitor(ds));
 	}
 
-	public void undoCommand() {
+	@Override public void undoCommand() {
 		osm.visit(new DeleteVisitor(ds));
 	}
 
-	public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
 		added.add(osm);
 	}
Index: c/org/openstreetmap/josm/command/ChangeKeyValueCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/ChangeKeyValueCommand.java	(revision 85)
+++ 	(revision )
@@ -1,82 +1,0 @@
-package org.openstreetmap.josm.command;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-
-/**
- * Command that manipulate the key/value structure of several objects. Manages deletion,
- * adding and modify of values and keys.
- * 
- * @author imi
- */
-public class ChangeKeyValueCommand implements Command {
-
-	/**
-	 * All primitives, that are affected with this command.
-	 */
-	private final List<OsmPrimitive> objects;
-	/**
-	 * The key that is subject to change.
-	 */
-	private final String key;
-	/**
-	 * The key value. If it is <code>null</code>, delete all key references with the given
-	 * key. Else, change the properties of all objects to the given value or create keys of
-	 * those objects that do not have the key yet.
-	 */
-	private final String value;
-	
-	/**
-	 * These are the old values of the objects to do a proper undo.
-	 */
-	private List<Map<String, String>> oldProperties;
-	
-	/**
-	 * These are the old modified states of the data.
-	 */
-	private List<Boolean> oldModified = new LinkedList<Boolean>();
-
-	public ChangeKeyValueCommand(Collection<OsmPrimitive> objects, String key, String value) {
-		this.objects = new LinkedList<OsmPrimitive>(objects);
-		this.key = key;
-		this.value = value;
-	}
-	
-	public void executeCommand() {
-		// save old
-		oldProperties = new LinkedList<Map<String, String>>();
-		for (OsmPrimitive osm : objects) {
-			oldProperties.add(osm.keys == null ? null : new HashMap<String, String>(osm.keys));
-			oldModified.add(osm.modifiedProperties);
-			osm.modifiedProperties = true;
-		}
-
-		if (value == null) {
-			for (OsmPrimitive osm : objects)
-				osm.remove(key);
-		} else {
-			for (OsmPrimitive osm : objects)
-				osm.put(key, value);
-		}
-	}
-
-	public void undoCommand() {
-		Iterator<Map<String, String>> it = oldProperties.iterator();
-		Iterator<Boolean> itMod = oldModified.iterator();
-		for (OsmPrimitive osm : objects) {
-			osm.keys = it.next();
-			osm.modifiedProperties = itMod.next();
-		}
-	}
-
-	public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
-		modified.addAll(objects);
-	}
-
-}
Index: /src/org/openstreetmap/josm/command/ChangePropertyCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 86)
+++ /src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 86)
@@ -0,0 +1,53 @@
+package org.openstreetmap.josm.command;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+/**
+ * Command that manipulate the key/value structure of several objects. Manages deletion,
+ * adding and modify of values and keys.
+ * 
+ * @author imi
+ */
+public class ChangePropertyCommand extends Command {
+
+	/**
+	 * All primitives, that are affected with this command.
+	 */
+	private final List<OsmPrimitive> objects;
+	/**
+	 * The key that is subject to change.
+	 */
+	private final String key;
+	/**
+	 * The key value. If it is <code>null</code>, delete all key references with the given
+	 * key. Else, change the properties of all objects to the given value or create keys of
+	 * those objects that do not have the key yet.
+	 */
+	private final String value;
+	
+	public ChangePropertyCommand(Collection<OsmPrimitive> objects, String key, String value) {
+		this.objects = new LinkedList<OsmPrimitive>(objects);
+		this.key = key;
+		this.value = value;
+	}
+	
+	@Override public void executeCommand() {
+		super.executeCommand(); // save old
+		if (value == null) {
+			for (OsmPrimitive osm : objects)
+				osm.remove(key);
+		} else {
+			for (OsmPrimitive osm : objects)
+				osm.put(key, value);
+		}
+	}
+
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+		modified.addAll(objects);
+	}
+
+}
Index: /src/org/openstreetmap/josm/command/Command.java
===================================================================
--- /src/org/openstreetmap/josm/command/Command.java	(revision 85)
+++ /src/org/openstreetmap/josm/command/Command.java	(revision 86)
@@ -2,6 +2,9 @@
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map.Entry;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.CloneVisitor;
 
 
@@ -16,10 +19,19 @@
  * @author imi
  */
-public interface Command {
+abstract public class Command {
 
+	private CloneVisitor orig; 
+	
 	/**
-	 * Executes the command on the dataset.
+	 * Executes the command on the dataset. This implementation will remember all
+	 * primitives returned by fillModifiedData for restoring them on undo.
 	 */
-	void executeCommand();
+	public void executeCommand() {
+		orig = new CloneVisitor();
+		Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
+		fillModifiedData(all, all, all);
+		for (OsmPrimitive osm : all)
+			osm.visit(orig);
+	}
 
 	/**
@@ -27,7 +39,12 @@
 	 * It can be assumed, that all objects are in the same state they were before.
 	 * It can also be assumed that executeCommand was called exactly once before.
+	 * 
+	 * This implementation undoes all objects stored by a former call to executeCommand.
 	 */
-	void undoCommand();
-	
+	public void undoCommand() {
+		for (Entry<OsmPrimitive, OsmPrimitive> e : orig.orig.entrySet())
+			e.getKey().cloneFrom(e.getValue());
+	}
+
 	/**
 	 * Fill in the changed data this command operates on.
@@ -38,5 +55,5 @@
 	 * @param added		The added primitives
 	 */
-	void fillModifiedData(Collection<OsmPrimitive> modified,
+	abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
 			Collection<OsmPrimitive> deleted,
 			Collection<OsmPrimitive> added);
Index: /src/org/openstreetmap/josm/command/ConflictResolveCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 86)
+++ /src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 86)
@@ -0,0 +1,67 @@
+package org.openstreetmap.josm.command;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.swing.DefaultListModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.ConflictItem;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.ConflictResolver;
+
+public class ConflictResolveCommand extends Command {
+
+	private final Collection<ConflictItem> conflicts;
+	private final Map<OsmPrimitive, OsmPrimitive> resolved;
+	private Map<OsmPrimitive, OsmPrimitive> origAllConflicts;
+
+	public ConflictResolveCommand(List<ConflictItem> conflicts, Map<OsmPrimitive, OsmPrimitive> resolved) {
+		this.conflicts = conflicts;
+		this.resolved = resolved;
+	}
+
+	@Override public void executeCommand() {
+		super.executeCommand();
+
+		origAllConflicts = new HashMap<OsmPrimitive, OsmPrimitive>(Main.main.getMapFrame().conflictDialog.conflicts);
+
+		
+		Set<OsmPrimitive> completed = new HashSet<OsmPrimitive>(resolved.keySet());
+		for (ConflictItem ci : conflicts) {
+			for (Entry<OsmPrimitive, OsmPrimitive> e : resolved.entrySet()) {
+				if (ci.resolution == ConflictResolver.Resolution.THEIR)
+					ci.apply(e.getKey(), e.getValue());
+				else if (ci.resolution == ConflictResolver.Resolution.MY)
+					ci.apply(e.getValue(), e.getKey());
+				else if (ci.hasConflict(e.getKey(), e.getValue()))
+					completed.remove(e.getKey());
+			}
+		}
+		for (OsmPrimitive k : completed) {
+			Main.main.getMapFrame().conflictDialog.conflicts.remove(k);
+			Main.main.getMapFrame().conflictDialog.model.removeElement(k);
+		}
+	}
+
+	@Override public void undoCommand() {
+		super.undoCommand();
+		Map<OsmPrimitive, OsmPrimitive> c = Main.main.getMapFrame().conflictDialog.conflicts;
+		DefaultListModel m = Main.main.getMapFrame().conflictDialog.model;
+
+		c.clear();
+		c.putAll(origAllConflicts);
+		m.removeAllElements();
+		for (Entry<OsmPrimitive, OsmPrimitive> e : c.entrySet())
+			m.addElement(e.getKey());
+	}
+
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+		modified.addAll(resolved.keySet());
+	}
+}
Index: /src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 85)
+++ /src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 86)
@@ -4,5 +4,5 @@
 import java.util.HashSet;
 
-import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
@@ -12,10 +12,6 @@
  * @author imi
  */
-public class DeleteCommand implements Command {
+public class DeleteCommand extends Command {
 
-	/**
-	 * The dataset this command operates on.
-	 */
-	final DataSet ds;
 	/**
 	 * The primitive that get deleted.
@@ -23,7 +19,6 @@
 	final Collection<OsmPrimitive> data = new HashSet<OsmPrimitive>();
 
-	public DeleteCommand(DataSet ds, OsmPrimitive osm) {
-		this.ds = ds;
-		CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(ds);
+	public DeleteCommand(OsmPrimitive osm) {
+		CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
 		osm.visit(v);
 		data.addAll(v.data);
@@ -31,15 +26,11 @@
 	}
 	
-	public void executeCommand() {
+	@Override public void executeCommand() {
+		super.executeCommand();
 		for (OsmPrimitive osm : data)
-			osm.setDeleted(true);
+			osm.delete(true);
 	}
 
-	public void undoCommand() {
-		for (OsmPrimitive osm : data)
-			osm.setDeleted(false);
-	}
-
-	public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
 		deleted.addAll(data);
 	}
Index: /src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/MoveCommand.java	(revision 85)
+++ /src/org/openstreetmap/josm/command/MoveCommand.java	(revision 86)
@@ -19,5 +19,5 @@
  * @author imi
  */
-public class MoveCommand implements Command {
+public class MoveCommand extends Command {
 
 	/**
@@ -84,5 +84,5 @@
 	}
 	
-	public void executeCommand() {
+	@Override public void executeCommand() {
 		for (Node n : objects) {
 			n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);
@@ -92,5 +92,5 @@
 	}
 
-	public void undoCommand() {
+	@Override public void undoCommand() {
 		Iterator<OldState> it = oldState.iterator();
 		for (Node n : objects) {
@@ -102,5 +102,5 @@
 	}
 
-	public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
 		for (OsmPrimitive osm : objects)
 			modified.add(osm);
Index: /src/org/openstreetmap/josm/command/SequenceCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 85)
+++ /src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 86)
@@ -10,5 +10,5 @@
  * @author imi
  */
-public class SequenceCommand implements Command {
+public class SequenceCommand extends Command {
 
 	/**
@@ -26,16 +26,15 @@
 	}
 	
-	public void executeCommand() {
+	@Override public void executeCommand() {
 		for (Command c : sequenz)
 			c.executeCommand();
 	}
 
-	public void undoCommand() {
+	@Override public void undoCommand() {
 		for (int i = sequenz.length-1; i >= 0; --i)
 			sequenz[i].undoCommand();
 	}
 
-	public void fillModifiedData(Collection<OsmPrimitive> modified,
-			Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
+	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
 		for (Command c : sequenz)
 			c.fillModifiedData(modified, deleted, added);
Index: /src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- /src/org/openstreetmap/josm/data/Bounds.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/Bounds.java	(revision 86)
@@ -35,6 +35,5 @@
 	}
 	
-	@Override
-	public String toString() {
+	@Override public String toString() {
 		return "Bounds["+min.lat()+","+min.lon()+","+max.lat()+","+max.lon()+"]";
 	}
Index: c/org/openstreetmap/josm/data/SelectionTracker.java
===================================================================
--- /src/org/openstreetmap/josm/data/SelectionTracker.java	(revision 85)
+++ 	(revision )
@@ -1,110 +1,0 @@
-package org.openstreetmap.josm.data;
-
-import java.util.Collection;
-import java.util.LinkedList;
-
-import javax.swing.SwingUtilities;
-
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-
-/**
- * This class is to help the DataSet collecting and fire selectionChanged events.
- * For more, @see org.openstreetmap.josm.data.SelectionChangedListener
- * 
- * @author imi
- */
-abstract public class SelectionTracker {
-
-	/**
-	 * Collects the selction changed events. The first collector that runs in 
-	 * one queue, starts the purger.
-	 * @author imi
-	 */
-	private final class Collector implements Runnable {
-		public void run() {
-			switch (state) {
-			case WAITING:
-				throw new IllegalStateException();
-			case COLLECTING:
-				state = SelectionEventState.PURGING;
-				SwingUtilities.invokeLater(new Purger());
-				break;
-			case PURGING:
-				break; // still purging events.
-			}
-		}
-	}
-
-	/**
-	 * Informs the listener clients and go back to waiting state.
-	 * @author imi
-	 */
-	private final class Purger implements Runnable {
-		public void run() {
-			if (state != SelectionEventState.PURGING)
-				throw new IllegalStateException();
-			state = SelectionEventState.WAITING;
-			Collection<OsmPrimitive> sel = getSelected();
-			for (SelectionChangedListener l : listeners)
-				l.selectionChanged(sel);
-		}
-	}
-
-	/**
-	 * The event state for the selection dispatching. WAITING means we are
-	 * waiting for any fireSelectionChanged event. COLLECTING means, we have
-	 * already some events in the EventQueue and are now collecting more events.
-	 * PURGING means, the collecting phase is over and we wait now for the finish
-	 * event to just contact the listeners.
-	 * @author imi
-	 */
-	private enum SelectionEventState {WAITING, COLLECTING, PURGING}
-
-	/**
-	 * The state, regarding to the selection changing that we are in.
-	 */
-	transient SelectionEventState state = SelectionEventState.WAITING;
-
-	/**
-	 * A list of listeners to selection changed events.
-	 */
-	transient Collection<SelectionChangedListener> listeners = new LinkedList<SelectionChangedListener>();
-
-	
-	/**
-	 * Add a listener to the selection changed listener list. If <code>null</code>
-	 * is passed, nothing happens.
-	 * @param listener The listener to add to the list.
-	 */
-	public void addSelectionChangedListener(SelectionChangedListener listener) {
-		if (listener != null)
-			listeners.add(listener);
-	}
-	
-	/**
-	 * Remove a listener from the selection changed listener list. 
-	 * If <code>null</code> is passed, nothing happens.
-	 * @param listener The listener to remove from the list.
-	 */
-	public void removeSelectionChangedListener(SelectionChangedListener listener) {
-		if (listener != null)
-			listeners.remove(listener);
-	}
-
-	/**
-	 * Remember to fire an selection changed event. A call to this will not fire
-	 * the event immediately. For more, @see SelectionChangedListener
-	 */
-	public void fireSelectionChanged() {
-		if (state == SelectionEventState.WAITING) {
-			state = SelectionEventState.COLLECTING;
-			SwingUtilities.invokeLater(new Collector());
-		}
-	}
-	
-	/**
-	 * This function is needed by the Purger to get the actual selection.
-	 * @return The selected primitives.
-	 */
-	abstract public Collection<OsmPrimitive> getSelected();
-}
Index: /src/org/openstreetmap/josm/data/conflict/ConflictItem.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/ConflictItem.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/ConflictItem.java	(revision 86)
@@ -0,0 +1,37 @@
+package org.openstreetmap.josm.data.conflict;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.ConflictResolver.Resolution;
+
+public abstract class ConflictItem {
+
+	public String my, their;
+	public Resolution resolution = null;
+
+	public final void initialize(Map<OsmPrimitive,OsmPrimitive> conflicts) {
+		my = collectStr(conflicts.keySet());
+		their = collectStr(conflicts.values());
+	}
+
+	abstract public boolean hasConflict(OsmPrimitive key, OsmPrimitive value);
+	abstract protected String str(OsmPrimitive osm);
+	abstract public String key();
+	abstract public void apply(OsmPrimitive target, OsmPrimitive other);
+
+	protected final String collectStr(Collection<OsmPrimitive> c) {
+		String value = null;
+		for (OsmPrimitive osm : c) {
+			String v = str(osm);
+			if (value == null)
+				value = v;
+			else if (!value.equals(v)) {
+				value = "<html><i>&lt;different&gt;</i></html>";
+				break;
+			}
+		}
+		return value == null ? "" : value;
+	}
+}
Index: /src/org/openstreetmap/josm/data/conflict/DeleteConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/DeleteConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/DeleteConflict.java	(revision 86)
@@ -0,0 +1,22 @@
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public class DeleteConflict extends ConflictItem {
+
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		return key.deleted != value.deleted;
+	}
+
+	@Override public String key() {
+		return "deleted|deleted";
+	}
+
+	@Override protected String str(OsmPrimitive osm) {
+		return osm.deleted ? "true" : "false";
+	}
+
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		target.deleted = other.deleted;
+	}
+}
Index: /src/org/openstreetmap/josm/data/conflict/FromConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/FromConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/FromConflict.java	(revision 86)
@@ -0,0 +1,24 @@
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Segment;
+
+public class FromConflict extends ConflictItem {
+
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		return key instanceof Segment && !((Segment)key).from.equals(((Segment)value).from);
+	}
+	
+	@Override protected String str(OsmPrimitive osm) {
+		return osm instanceof Segment ? String.valueOf(((Segment)osm).from.id) : null;
+	}
+	
+	@Override public String key() {
+		return "segment|from";
+	}
+	
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		if (target instanceof Segment)
+			((Segment)target).from = ((Segment)other).from;
+    }
+}
Index: /src/org/openstreetmap/josm/data/conflict/PositionConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/PositionConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/PositionConflict.java	(revision 86)
@@ -0,0 +1,26 @@
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public class PositionConflict extends ConflictItem {
+	
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		return key instanceof Node && !((Node)key).coor.equals(((Node)value).coor);
+	}
+	
+	@Override protected String str(OsmPrimitive osm) {
+		return osm instanceof Node ? ((Node)osm).coor.lat()+", "+((Node)osm).coor.lon() : null;
+	}
+	
+	@Override public String key() {
+		return "node|position";
+	}
+	
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		if (target instanceof Node) {
+			((Node)target).coor = ((Node)other).coor;
+			((Node)target).eastNorth = ((Node)other).eastNorth;
+		}
+    }
+}
Index: /src/org/openstreetmap/josm/data/conflict/PropertyConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/PropertyConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/PropertyConflict.java	(revision 86)
@@ -0,0 +1,30 @@
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public class PropertyConflict extends ConflictItem {
+	private String key;
+	
+	public PropertyConflict(String key) {
+		this.key = key;
+	}
+	
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		String k = key.get(this.key);
+		String v = value.get(this.key);
+		return k == null ? v!=null : !k.equals(v);
+	}
+	
+	@Override protected String str(OsmPrimitive osm) {
+		String v = osm.get(key);
+		return v == null ? "" : v;
+	}
+	
+	@Override public String key() {
+		return "key|"+key;
+	}
+	
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		target.put(key, other.get(key));
+    }
+}
Index: /src/org/openstreetmap/josm/data/conflict/SegmentConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/SegmentConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/SegmentConflict.java	(revision 86)
@@ -0,0 +1,32 @@
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class SegmentConflict extends ConflictItem {
+	
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		return key instanceof Way && !((Way)key).segments.equals(((Way)value).segments);
+	}
+	
+	@Override protected String str(OsmPrimitive osm) {
+		if (!(osm instanceof Way))
+			return null;
+		String s = "";
+		for (Segment ls : ((Way)osm).segments)
+			s += ls.id + ",";
+		return s.equals("") ? "<html><i>&lt;none&gt;</i></html>" : s.substring(0, s.length()-1);
+	}
+	
+	@Override public String key() {
+		return "way|segments";
+	}
+	
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		if (!(target instanceof Way))
+			return;
+		((Way)target).segments.clear();
+		((Way)target).segments.addAll(((Way)other).segments);
+    }
+}
Index: /src/org/openstreetmap/josm/data/conflict/ToConflict.java
===================================================================
--- /src/org/openstreetmap/josm/data/conflict/ToConflict.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/conflict/ToConflict.java	(revision 86)
@@ -0,0 +1,27 @@
+/**
+ * 
+ */
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Segment;
+
+public class ToConflict extends ConflictItem {
+	
+	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
+		return key instanceof Segment && !((Segment)key).to.equals(((Segment)value).to);
+	}
+
+	@Override protected String str(OsmPrimitive osm) {
+		return osm instanceof Segment ? String.valueOf(((Segment)osm).to.id) : null;
+	}
+
+	@Override public String key() {
+		return "segment|to";
+	}
+	
+	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
+		if (target instanceof Segment)
+			((Segment)target).to = ((Segment)other).to;
+    }
+}
Index: /src/org/openstreetmap/josm/data/coor/Coordinate.java
===================================================================
--- /src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 86)
@@ -50,11 +50,9 @@
 	}
 
-	@Override
-	public boolean equals(Object obj) {
+	@Override public boolean equals(Object obj) {
 		return obj instanceof Coordinate ? x == ((Coordinate)obj).x && ((Coordinate)obj).y == y : false;
 	}
 
-	@Override
-	public int hashCode() {
+	@Override public int hashCode() {
 		return (int)(x*65536+y*4096);
 	}
Index: /src/org/openstreetmap/josm/data/coor/EastNorth.java
===================================================================
--- /src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 86)
@@ -22,6 +22,5 @@
 	}
 	
-	@Override
-	public String toString() {
+	@Override public String toString() {
 		return "EastNorth[e="+x+", n="+y+"]";
 	}
Index: /src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- /src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 86)
@@ -42,6 +42,5 @@
 	}
 
-    @Override
-    public String toString() {
+    @Override public String toString() {
         return "LatLon[lat="+lat()+",lon="+lon()+"]";
     }
Index: /src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 86)
@@ -2,8 +2,9 @@
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 
-import org.openstreetmap.josm.data.SelectionTracker;
+import org.openstreetmap.josm.data.SelectionChangedListener;
 
 /**
@@ -17,5 +18,5 @@
  * @author imi
  */
-public class DataSet extends SelectionTracker {
+public class DataSet {
 
 	/**
@@ -27,7 +28,7 @@
 
 	/**
-	 * All line segments goes here, even when they are in a way.
+	 * All segments goes here, even when they are in a way.
 	 */
-	public Collection<LineSegment> lineSegments = new LinkedList<LineSegment>();
+	public Collection<Segment> segments = new LinkedList<Segment>();
 
 	/**
@@ -41,4 +42,9 @@
 
 	/**
+     * A list of listeners to selection changed events.
+     */
+    transient Collection<SelectionChangedListener> listeners = new LinkedList<SelectionChangedListener>();
+
+	/**
 	 * @return A collection containing all primitives (except keys) of the
 	 * dataset.
@@ -47,5 +53,5 @@
 		Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
 		o.addAll(nodes);
-		o.addAll(lineSegments);
+		o.addAll(segments);
 		o.addAll(ways);
 		return o;
@@ -58,5 +64,5 @@
 		Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
 		for (OsmPrimitive osm : allPrimitives())
-			if (!osm.isDeleted())
+			if (!osm.deleted)
 				o.add(osm);
 		return o;
@@ -68,6 +74,8 @@
 	public void clearSelection() {
 		clearSelection(nodes);
-		clearSelection(lineSegments);
+		clearSelection(segments);
 		clearSelection(ways);
+		Collection<OsmPrimitive> sel = Collections.emptyList();
+		fireSelectionChanged(sel);
 	}
 
@@ -76,12 +84,18 @@
 	 * @return List of all selected objects.
 	 */
-	@Override
 	public Collection<OsmPrimitive> getSelected() {
 		Collection<OsmPrimitive> sel = getSelected(nodes);
-		sel.addAll(getSelected(lineSegments));
+		sel.addAll(getSelected(segments));
 		sel.addAll(getSelected(ways));
 		return sel;
 	}
 
+	public void setSelected(Collection<OsmPrimitive> selection) {
+		clearSelection();
+		for (OsmPrimitive osm : selection)
+			osm.selected = true;
+		fireSelectionChanged(selection);
+	}
+	
 	/**
 	 * Remove the selection from every value in the collection.
@@ -92,5 +106,5 @@
 			return;
 		for (OsmPrimitive osm : list)
-			osm.setSelected(false);
+			osm.selected = false;
 	}
 
@@ -104,7 +118,36 @@
 			return sel;
 		for (OsmPrimitive osm : list)
-			if (osm.isSelected() && !osm.isDeleted())
+			if (osm.selected && !osm.deleted)
 				sel.add(osm);
 		return sel;
 	}
+
+	/**
+     * Remember to fire an selection changed event. A call to this will not fire
+     * the event immediately. For more, @see SelectionChangedListener
+     */
+    private void fireSelectionChanged(Collection<OsmPrimitive> sel) {
+		for (SelectionChangedListener l : listeners)
+			l.selectionChanged(sel);
+    }
+
+	/**
+     * Add a listener to the selection changed listener list. If <code>null</code>
+     * is passed, nothing happens.
+     * @param listener The listener to add to the list.
+     */
+    public void addSelectionChangedListener(SelectionChangedListener listener) {
+    	if (listener != null)
+    		listeners.add(listener);
+    }
+
+	/**
+     * Remove a listener from the selection changed listener list. 
+     * If <code>null</code> is passed, nothing happens.
+     * @param listener The listener to remove from the list.
+     */
+    public void removeSelectionChangedListener(SelectionChangedListener listener) {
+    	if (listener != null)
+    		listeners.remove(listener);
+    }
 }
Index: c/org/openstreetmap/josm/data/osm/LineSegment.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/LineSegment.java	(revision 85)
+++ 	(revision )
@@ -1,79 +1,0 @@
-package org.openstreetmap.josm.data.osm;
-
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
-
-
-/**
- * One way line segment consisting of a pair of nodes (from/to) 
- *
- * @author imi
- */
-public class LineSegment extends OsmPrimitive {
-
-	/**
-	 * The starting node of the line segment
-	 */
-	public Node from;
-
-	/**
-	 * The ending node of the line segment
-	 */
-	public Node to;
-
-	/**
-	 * If set to true, this object is incomplete, which means only the id
-	 * and type is known (type is the objects instance class)
-	 */
-	public boolean incomplete;
-
-	/**
-	 * Create an line segment from the given starting and ending node
-	 * @param from	Starting node of the line segment.
-	 * @param to	Ending node of the line segment.
-	 */
-	public LineSegment(Node from, Node to) {
-		this.from = from;
-		this.to = to;
-		incomplete = false;
-	}
-
-	public LineSegment(long id) {
-		this.id = id;
-		incomplete = true;
-	}
-
-	@Override
-	public void visit(Visitor visitor) {
-		visitor.visit(this);
-	}
-
-	/**
-	 * @return <code>true</code>, if the <code>ls</code> occupy
-	 * exactly the same place as <code>this</code>.
-	 */
-	public boolean equalPlace(LineSegment ls) {
-		if (equals(ls))
-			return true;
-		if (incomplete || ls.incomplete)
-			return incomplete == ls.incomplete;
-		return ((from.coor.equals(ls.from.coor) && to.coor.equals(ls.to.coor)) ||
-				(from.coor.equals(ls.to.coor) && to.coor.equals(ls.from.coor)));
-	}
-
-	@Override
-	public String toString() {
-		String s = "{LineSegment id="+id;
-		if (incomplete)
-			return s+",incomplete}";
-		return s+",from="+from+",to="+to+"}";
-	}
-
-	@Override
-	public void cloneFrom(OsmPrimitive osm) {
-		super.cloneFrom(osm);
-		LineSegment ls = ((LineSegment)osm);
-		from = ls.from;
-		to = ls.to;
-		incomplete = ls.incomplete;
-	}
-}	
Index: /src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/Node.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/Node.java	(revision 86)
@@ -15,5 +15,12 @@
 	
 	public LatLon coor;
-	public EastNorth eastNorth;
+	public volatile EastNorth eastNorth;
+
+	/**
+	 * Create an identical clone of the argument (including the id)
+	 */
+	public Node(Node clone) {
+		cloneFrom(clone);
+	}
 
 	public Node(LatLon latlon) {
@@ -22,19 +29,20 @@
 	}
 
-	@Override
-	public void visit(Visitor visitor) {
+	@Override public void visit(Visitor visitor) {
 		visitor.visit(this);
 	}
 	
-	@Override
-	public String toString() {
-		return "{Node id="+id+",lat="+coor.lat()+",lon="+coor.lon()+"}";
-	}
-
-	@Override
-	public void cloneFrom(OsmPrimitive osm) {
+	@Override public void cloneFrom(OsmPrimitive osm) {
 		super.cloneFrom(osm);
 		coor = ((Node)osm).coor;
 		eastNorth = ((Node)osm).eastNorth;
 	}
+
+	@Override public String toString() {
+		return "{Node id="+id+",lat="+coor.lat()+",lon="+coor.lon()+"}";
+	}
+
+	@Override public boolean realEqual(OsmPrimitive osm) {
+		return osm instanceof Node ? super.realEqual(osm) && coor.equals(((Node)osm).coor) : false;
+    }
 }
Index: /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 86)
@@ -8,5 +8,4 @@
 import java.util.Map.Entry;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
@@ -38,27 +37,20 @@
 
 	/**
-	 * <code>true</code>, if the objects content (not the properties) 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.
-	 * If the objects are added (id=0), the modified is ignored and the object is
-	 * added to the server. 
+	 * <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. If the objects are added (id=0),
+	 * the modified is ignored and the object is added to the server. 
 	 */
 	public boolean modified = false;
 
 	/**
-	 * <code>true</code>, if the object's keys has been changed by JOSM since
-	 * last update.
-	 */
-	public boolean modifiedProperties = false;
-	
-	/**
 	 * <code>true</code>, if the object has been deleted.
 	 */
-	private boolean deleted = false;
+	public boolean deleted = false;
 
 	/**
 	 * If set to true, this object is currently selected.
 	 */
-	private boolean selected = false;
+	public volatile boolean selected = false;
 
 	/**
@@ -67,5 +59,5 @@
 	 * used to check against edit conflicts.
 	 */
-	public Date lastModified = null;
+	public Date timestamp = null;
 
 	/**
@@ -76,53 +68,8 @@
 	abstract public void visit(Visitor visitor);
 
-	/**
-	 * Return <code>true</code>, if either <code>this.keys</code> and 
-	 * <code>other.keys</code> is <code>null</code> or if they do not share Keys
-	 * with different values.
-	 *  
-	 * @param other		The second key-set to compare with.
-	 * @return	True, if the keysets are mergable
-	 */
-	final public boolean keyPropertiesMergable(OsmPrimitive other) {
-		if ((keys == null) != (other.keys == null))
-			return false;
-
-		if (keys != null) {
-			for (String k : keys.keySet())
-				if (other.keys.containsKey(k) && !keys.get(k).equals(other.keys.get(k)))
-					return false;
-			for (String k : other.keys.keySet())
-				if (keys.containsKey(k) && !other.keys.get(k).equals(keys.get(k)))
-					return false;
-		}
-		return true;
-	}
-
-	/**
-	 * Mark the primitive as selected or not selected and fires a selection 
-	 * changed later, if the value actualy changed.
-	 * @param selected Whether the primitive should be selected or not.
-	 */
-	final public void setSelected(boolean selected) {
-		if (selected != this.selected)
-			Main.main.ds.fireSelectionChanged();
-		this.selected = selected;
-	}
-
-	/**
-	 * @return Return whether the primitive is selected on screen.
-	 */
-	final public boolean isSelected() {
-		return selected;
-	}
-
-
-	public void setDeleted(boolean deleted) {
+	public final void delete(boolean deleted) {
 		this.deleted = deleted;
-		setSelected(false);
-	}
-
-	public boolean isDeleted() {
-		return deleted;
+		selected = false;
+		modified = true;
 	}
 
@@ -133,6 +80,5 @@
 	 * An primitive is equal to its incomplete counter part.
 	 */
-	@Override
-	public boolean equals(Object obj) {
+	@Override public final boolean equals(Object obj) {
 		if (obj == null || getClass() != obj.getClass() || id == 0 || ((OsmPrimitive)obj).id == 0)
 			return super.equals(obj);
@@ -145,6 +91,5 @@
 	 * An primitive has the same hashcode as its incomplete counter part.
 	 */
-	@Override
-	public int hashCode() {
+	@Override public final int hashCode() {
 		return id == 0 ? super.hashCode() : (int)id;
 	}
@@ -155,13 +100,17 @@
 	 * @param value The value for the key.
 	 */
-	public void put(String key, String value) {
-		if (keys == null)
-			keys = new HashMap<String, String>();
-		keys.put(key, value);
+	public final void put(String key, String value) {
+		if (value == null)
+			remove(key);
+		else {
+			if (keys == null)
+				keys = new HashMap<String, String>();
+			keys.put(key, value);
+		}
 	}
 	/**
 	 * Remove the given key from the list.
 	 */
-	public void remove(String key) {
+	public final void remove(String key) {
 		if (keys != null) {
 			keys.remove(key);
@@ -171,9 +120,9 @@
 	}
 
-	public String get(String key) {
+	public final String get(String key) {
 		return keys == null ? null : keys.get(key);
 	}
-	
-	public Collection<Entry<String, String>> entrySet() {
+
+	public final Collection<Entry<String, String>> entrySet() {
 		if (keys == null)
 			return Collections.emptyList();
@@ -181,5 +130,5 @@
 	}
 
-	public Collection<String> keySet() {
+	public final Collection<String> keySet() {
 		if (keys == null)
 			return Collections.emptyList();
@@ -192,11 +141,23 @@
 	 */
 	public void cloneFrom(OsmPrimitive osm) {
-		keys = osm.keys;
+		keys = osm.keys == null ? null : new HashMap<String, String>(osm.keys);
 		id = osm.id;
 		modified = osm.modified;
-		modifiedProperties = osm.modifiedProperties;
 		deleted = osm.deleted;
 		selected = osm.selected;
-		lastModified = osm.lastModified;
+		timestamp = osm.timestamp;
+	}
+
+	/**
+	 * Perform an equality compare for all non-volatile fields not only for the id 
+	 * but for the whole object (for conflict resolving etc)
+	 */
+	public boolean realEqual(OsmPrimitive osm) {
+		return
+		id == osm.id && 
+		modified == osm.modified && 
+		deleted == osm.deleted &&
+		(timestamp == null ? osm.timestamp==null : timestamp.equals(osm.timestamp)) &&
+		(keys == null ? osm.keys==null : keys.equals(osm.keys));
 	}
 }
Index: /src/org/openstreetmap/josm/data/osm/Segment.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/Segment.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/osm/Segment.java	(revision 86)
@@ -0,0 +1,87 @@
+package org.openstreetmap.josm.data.osm;
+
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+
+
+/**
+ * One way segment consisting of a pair of nodes (from/to) 
+ *
+ * @author imi
+ */
+public class Segment extends OsmPrimitive {
+
+	/**
+	 * The starting node of the segment
+	 */
+	public Node from;
+
+	/**
+	 * The ending node of the segment
+	 */
+	public Node to;
+
+	/**
+	 * If set to true, this object is incomplete, which means only the id
+	 * and type is known (type is the objects instance class)
+	 */
+	public boolean incomplete;
+
+	/**
+	 * Create an identical clone of the argument (including the id)
+	 */
+	public Segment(Segment clone) {
+		cloneFrom(clone);
+	}
+
+	/**
+	 * Create an segment from the given starting and ending node
+	 * @param from	Starting node of the segment.
+	 * @param to	Ending node of the segment.
+	 */
+	public Segment(Node from, Node to) {
+		this.from = from;
+		this.to = to;
+		incomplete = false;
+	}
+
+	public Segment(long id) {
+		this.id = id;
+		incomplete = true;
+	}
+
+	@Override public void visit(Visitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * @return <code>true</code>, if the <code>ls</code> occupy
+	 * exactly the same place as <code>this</code>.
+	 */
+	public boolean equalPlace(Segment ls) {
+		if (equals(ls))
+			return true;
+		if (incomplete || ls.incomplete)
+			return incomplete == ls.incomplete;
+		return ((from.coor.equals(ls.from.coor) && to.coor.equals(ls.to.coor)) ||
+				(from.coor.equals(ls.to.coor) && to.coor.equals(ls.from.coor)));
+	}
+
+	@Override public void cloneFrom(OsmPrimitive osm) {
+		super.cloneFrom(osm);
+		Segment ls = ((Segment)osm);
+		from = ls.from;
+		to = ls.to;
+		incomplete = ls.incomplete;
+	}
+
+	@Override public String toString() {
+		return "{Segment id="+id+" from="+from+" to="+to+"}";
+	}
+
+	@Override public boolean realEqual(OsmPrimitive osm) {
+		return osm instanceof Segment ? 
+				super.realEqual(osm) && 
+				from.equals(((Segment)osm).from) && 
+				to.equals(((Segment)osm).to) : false;
+	}
+}	
Index: /src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/Way.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/Way.java	(revision 86)
@@ -2,4 +2,5 @@
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
@@ -16,16 +17,32 @@
 	 * All way segments in this way
 	 */
-	public final List<LineSegment> segments = new ArrayList<LineSegment>();
+	public final List<Segment> segments = new ArrayList<Segment>();
 
-	@Override
-	public void visit(Visitor visitor) {
+	@Override public void visit(Visitor visitor) {
 		visitor.visit(this);
 	}
 
-	@Override
-	public void cloneFrom(OsmPrimitive osm) {
+	/**
+	 * Create an identical clone of the argument (including the id)
+	 */
+	public Way(Way clone) {
+		cloneFrom(clone);
+	}
+	
+	public Way() {
+	}
+	
+	@Override public void cloneFrom(OsmPrimitive osm) {
 		super.cloneFrom(osm);
 		segments.clear();
 		segments.addAll(((Way)osm).segments);
 	}
+
+    @Override public String toString() {
+        return "{Way id="+id+" segments="+Arrays.toString(segments.toArray())+"}";
+    }
+
+	@Override public boolean realEqual(OsmPrimitive osm) {
+		return osm instanceof Way ? super.realEqual(osm) && segments.equals(((Way)osm).segments) : false;
+    }
 }
Index: /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 86)
@@ -4,5 +4,5 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -26,6 +26,6 @@
 		ds.nodes.add(n);
 	}
-	public void visit(LineSegment ls) {
-		ds.lineSegments.add(ls);
+	public void visit(Segment ls) {
+		ds.segments.add(ls);
 	}
 	public void visit(Way t) {
Index: /src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 86)
@@ -4,5 +4,5 @@
 import java.util.HashSet;
 
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -31,5 +31,5 @@
 	 * Line segments have exactly two nodes: from and to.
 	 */
-	public void visit(LineSegment ls) {
+	public void visit(Segment ls) {
 		if (!ls.incomplete) {
 			visit(ls.from);
@@ -39,8 +39,8 @@
 
 	/**
-	 * Ways have all nodes from their line segments.
+	 * Ways have all nodes from their segments.
 	 */
 	public void visit(Way t) {
-		for (LineSegment ls : t.segments)
+		for (Segment ls : t.segments)
 			visit(ls);
 	}
Index: /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 86)
@@ -4,5 +4,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -21,5 +21,5 @@
 	}
 
-	public void visit(LineSegment ls) {
+	public void visit(Segment ls) {
 		if (!ls.incomplete) {
 			visit(ls.from);
@@ -29,5 +29,5 @@
 
 	public void visit(Way t) {
-		for (LineSegment ls : t.segments)
+		for (Segment ls : t.segments)
 			visit(ls);
 	}
Index: /src/org/openstreetmap/josm/data/osm/visitor/CloneVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/CloneVisitor.java	(revision 86)
+++ /src/org/openstreetmap/josm/data/osm/visitor/CloneVisitor.java	(revision 86)
@@ -0,0 +1,24 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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;
+
+public class CloneVisitor implements Visitor {
+	
+	public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
+	
+	public void visit(Node n) {
+		orig.put(n, new Node(n));
+    }
+	public void visit(Segment s) {
+		orig.put(s, new Segment(s));
+    }
+	public void visit(Way w) {
+		orig.put(w, new Way(w));
+    }
+}
Index: /src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 86)
@@ -5,5 +5,5 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -11,6 +11,6 @@
 
 /**
- * Helper that collect all line segments a node is part of, all ways
- * a node or line segment is part of and all areas a node is part of. 
+ * Helper that collect all segments a node is part of, all ways
+ * a node or segment is part of and all areas a node is part of. 
  * 
  * Deleted objects are not collected.
@@ -38,7 +38,7 @@
 	public void visit(Node n) {
 		for (Way t : ds.ways) {
-			if (t.isDeleted())
+			if (t.deleted)
 				continue;
-			for (LineSegment ls : t.segments) {
+			for (Segment ls : t.segments) {
 				if (ls.incomplete)
 					continue;
@@ -49,6 +49,6 @@
 			}
 		}
-		for (LineSegment ls : ds.lineSegments) {
-			if (ls.isDeleted() || ls.incomplete)
+		for (Segment ls : ds.segments) {
+			if (ls.deleted || ls.incomplete)
 				continue;
 			if (ls.from == n || ls.to == n)
@@ -56,7 +56,7 @@
 		}
 	}
-	public void visit(LineSegment ls) {
+	public void visit(Segment ls) {
 		for (Way t : ds.ways) {
-			if (t.isDeleted())
+			if (t.deleted)
 				continue;
 			if (t.segments.contains(ls))
Index: /src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 86)
@@ -4,5 +4,5 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -26,6 +26,6 @@
 		ds.nodes.remove(n);
 	}
-	public void visit(LineSegment ls) {
-		ds.lineSegments.remove(ls);
+	public void visit(Segment ls) {
+		ds.segments.remove(ls);
 	}
 	public void visit(Way t) {
Index: /src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 86)
@@ -1,4 +1,6 @@
 package org.openstreetmap.josm.data.osm.visitor;
 
+import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -7,5 +9,5 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -20,6 +22,12 @@
 public class MergeVisitor implements Visitor {
 
+	/**
+	 * Map from primitives in the database to visited primitives. (Attention: The other way 
+	 * round than mergedNodes and mergedSegments)
+	 */
+	public Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
+
 	private final DataSet ds;
-	
+
 	/**
 	 * A list of all nodes that got replaced with other nodes.
@@ -29,10 +37,10 @@
 	private final Map<Node, Node> mergedNodes = new HashMap<Node, Node>();
 	/**
-	 * A list of all line segments that got replaced with others.
+	 * A list of all segments that got replaced with others.
 	 * Key is the segment in the other's dataset and the value is the one that is now
-	 * in ds.lineSegments.
-	 */
-	private final Map<LineSegment, LineSegment> mergedLineSegments = new HashMap<LineSegment, LineSegment>();
-	
+	 * in ds.segments.
+	 */
+	private final Map<Segment, Segment> mergedSegments = new HashMap<Segment, Segment>();
+
 	public MergeVisitor(DataSet ds) {
 		this.ds = ds;
@@ -43,87 +51,97 @@
 	 * either id is zero, merge if lat/lon matches.
 	 */
-	public void visit(Node otherNode) {
-		Node myNode = null;
+	public void visit(Node other) {
+		if (mergeAfterId(mergedNodes, ds.nodes, other))
+			return;
+
+		Node my = null;
 		for (Node n : ds.nodes) {
-			if (match(n, otherNode)) {
-				myNode = n;
+			if (match(n, other)) {
+				my = n;
 				break;
 			}
 		}
-		if (myNode == null)
-			ds.nodes.add(otherNode);
+		if (my == null)
+			ds.nodes.add(other);
 		else {
-			mergedNodes.put(otherNode, myNode);
-			mergeCommon(myNode, otherNode);
-			if (myNode.modified && !otherNode.modified)
+			mergedNodes.put(other, my);
+			mergeCommon(my, other);
+			if (my.modified && !other.modified)
 				return;
-			if (!myNode.coor.equalsEpsilon(otherNode.coor)) {
-				myNode.coor = otherNode.coor;
-				myNode.modified = otherNode.modified;
-			}
-		}
-	}
-
-	/**
-	 * Merge the line segment if id matches or if both nodes are the same (and the
+			if (!my.coor.equalsEpsilon(other.coor)) {
+				my.coor = other.coor;
+				my.eastNorth = other.eastNorth;
+				my.modified = other.modified;
+			}
+		}
+	}
+
+	/**
+	 * Merge the segment if id matches or if both nodes are the same (and the
 	 * id is zero of either segment). Nodes are the "same" when they @see match
 	 */
-	public void visit(LineSegment otherLs) {
-		LineSegment myLs = null;
-		for (LineSegment ls : ds.lineSegments) {
-			if (match(otherLs, ls)) {
-				myLs = ls;
+	public void visit(Segment other) {
+		if (mergeAfterId(mergedSegments, ds.segments, other))
+			return;
+
+		Segment my = null;
+		for (Segment ls : ds.segments) {
+			if (match(other, ls)) {
+				my = ls;
 				break;
 			}
 		}
-		if (myLs == null)
-			ds.lineSegments.add(otherLs);
-		else if (myLs.incomplete && !otherLs.incomplete) {
-			mergedLineSegments.put(otherLs, myLs);
-			myLs.cloneFrom(otherLs);
-		} else if (!otherLs.incomplete) {
-			mergedLineSegments.put(otherLs, myLs);
-			mergeCommon(myLs, otherLs);
-			if (myLs.modified && !otherLs.modified)
+		if (my == null)
+			ds.segments.add(other);
+		else if (my.incomplete && !other.incomplete) {
+			mergedSegments.put(other, my);
+			my.cloneFrom(other);
+		} else if (!other.incomplete) {
+			mergedSegments.put(other, my);
+			mergeCommon(my, other);
+			if (my.modified && !other.modified)
 				return;
-			if (!match(myLs.from, otherLs.from)) {
-				myLs.from = otherLs.from;
-				myLs.modified = otherLs.modified;
-			}
-			if (!match(myLs.to, otherLs.to)) {
-				myLs.to = otherLs.to;
-				myLs.modified = otherLs.modified;
-			}
-		}
-	}
-
-	/**
-	 * Merge the way if id matches or if all line segments matches and the
+			if (!match(my.from, other.from)) {
+				my.from = other.from;
+				my.modified = other.modified;
+			}
+			if (!match(my.to, other.to)) {
+				my.to = other.to;
+				my.modified = other.modified;
+			}
+		}
+	}
+
+	/**
+	 * Merge the way if id matches or if all segments matches and the
 	 * id is zero of either way.
 	 */
-	public void visit(Way otherWay) {
-		Way myWay = null;
+	public void visit(Way other) {
+		if (mergeAfterId(null, ds.ways, other))
+			return;
+
+		Way my = null;
 		for (Way t : ds.ways) {
-			if (match(otherWay, t)) {
-				myWay = t;
+			if (match(other, t)) {
+				my = t;
 				break;
 			}
 		}
-		if (myWay == null)
-			ds.ways.add(otherWay);
+		if (my == null)
+			ds.ways.add(other);
 		else {
-			mergeCommon(myWay, otherWay);
-			if (myWay.modified && !otherWay.modified)
+			mergeCommon(my, other);
+			if (my.modified && !other.modified)
 				return;
 			boolean same = true;
-			Iterator<LineSegment> it = otherWay.segments.iterator();
-			for (LineSegment ls : myWay.segments) {
+			Iterator<Segment> it = other.segments.iterator();
+			for (Segment ls : my.segments) {
 				if (!match(ls, it.next()))
 					same = false;
 			}
 			if (!same) {
-				myWay.segments.clear();
-				myWay.segments.addAll(otherWay.segments);
-				myWay.modified = otherWay.modified;
+				my.segments.clear();
+				my.segments.addAll(other.segments);
+				my.modified = other.modified;
 			}
 		}
@@ -135,32 +153,41 @@
 	 */
 	public void fixReferences() {
-		for (LineSegment ls : ds.lineSegments) {
-			if (mergedNodes.containsKey(ls.from))
-				ls.from = mergedNodes.get(ls.from);
-			if (mergedNodes.containsKey(ls.to))
-				ls.to = mergedNodes.get(ls.to);
-		}
-		for (Way t : ds.ways) {
-			boolean replacedSomething = false;
-			LinkedList<LineSegment> newSegments = new LinkedList<LineSegment>();
-			for (LineSegment ls : t.segments) {
-				LineSegment otherLs = mergedLineSegments.get(ls);
-				newSegments.add(otherLs == null ? ls : otherLs);
-				if (otherLs != null)
-					replacedSomething = true;
-			}
-			if (replacedSomething) {
-				t.segments.clear();
-				t.segments.addAll(newSegments);
-			}
-			for (LineSegment ls : t.segments) {
-				if (mergedNodes.containsKey(ls.from))
-					ls.from = mergedNodes.get(ls.from);
-				if (mergedNodes.containsKey(ls.to))
-					ls.to = mergedNodes.get(ls.to);
-			}
-		}
-	}
-	
+		for (Segment s : ds.segments)
+			fixSegment(s);
+		for (OsmPrimitive osm : conflicts.values())
+			if (osm instanceof Segment)
+				fixSegment((Segment)osm);
+		for (Way w : ds.ways)
+			fixWay(w);
+		for (OsmPrimitive osm : conflicts.values())
+			if (osm instanceof Way)
+				fixWay((Way)osm);
+	}
+
+	private void fixWay(Way t) {
+	    boolean replacedSomething = false;
+	    LinkedList<Segment> newSegments = new LinkedList<Segment>();
+	    for (Segment ls : t.segments) {
+	    	Segment otherLs = mergedSegments.get(ls);
+	    	newSegments.add(otherLs == null ? ls : otherLs);
+	    	if (otherLs != null)
+	    		replacedSomething = true;
+	    }
+	    if (replacedSomething) {
+	    	t.segments.clear();
+	    	t.segments.addAll(newSegments);
+	    }
+	    for (Segment ls : t.segments) {
+	    	fixSegment(ls);
+	    }
+    }
+
+	private void fixSegment(Segment ls) {
+	    if (mergedNodes.containsKey(ls.from))
+	    	ls.from = mergedNodes.get(ls.from);
+	    if (mergedNodes.containsKey(ls.to))
+	    	ls.to = mergedNodes.get(ls.to);
+    }
+
 	/**
 	 * @return Whether the nodes matches (in sense of "be mergable").
@@ -171,9 +198,9 @@
 		return n1.id == n2.id;
 	}
-	
-	/**
-	 * @return Whether the line segments matches (in sense of "be mergable").
-	 */
-	private boolean match(LineSegment ls1, LineSegment ls2) {
+
+	/**
+	 * @return Whether the segments matches (in sense of "be mergable").
+	 */
+	private boolean match(Segment ls1, Segment ls2) {
 		if (ls1.id == ls2.id)
 			return true;
@@ -190,6 +217,6 @@
 			if (t1.segments.size() != t2.segments.size())
 				return false;
-			Iterator<LineSegment> it = t1.segments.iterator();
-			for (LineSegment ls : t2.segments)
+			Iterator<Segment> it = t1.segments.iterator();
+			for (Segment ls : t2.segments)
 				if (!match(ls, it.next()))
 					return false;
@@ -201,27 +228,66 @@
 	/**
 	 * Merge the common parts of an osm primitive.
-	 * @param myOsm The object, the information gets merged into
-	 * @param otherOsm The object, the information gets merged from
-	 */
-	private void mergeCommon(OsmPrimitive myOsm, OsmPrimitive otherOsm) {
-		if (otherOsm.isDeleted())
-			myOsm.setDeleted(true);
-		if (!myOsm.modified || otherOsm.modified) {
-			if (myOsm.id == 0 && otherOsm.id != 0)
-				myOsm.id = otherOsm.id; // means not ncessary the object is now modified
-			else if (myOsm.id != 0 && otherOsm.id != 0 && otherOsm.modified)
-				myOsm.modified = true;
-		}
-		if (myOsm.modifiedProperties && !otherOsm.modifiedProperties)
-			return;
-		if (otherOsm.keys == null)
-			return;
-		if (myOsm.keys != null && myOsm.keys.entrySet().containsAll(otherOsm.keys.entrySet()))
-			return;
-		if (myOsm.keys == null)
-			myOsm.keys = otherOsm.keys;
+	 * @param my The object, the information gets merged into
+	 * @param other The object, the information gets merged from
+	 */
+	private void mergeCommon(OsmPrimitive my, OsmPrimitive other) {
+		if (other.deleted)
+			my.delete(true);
+		if (my.id == 0 || !my.modified || other.modified) {
+			if (my.id == 0 && other.id != 0) {
+				my.id = other.id;
+				my.modified = other.modified; // match a new node
+			} else if (my.id != 0 && other.id != 0 && other.modified)
+				my.modified = true;
+		}
+		if (other.keys == null)
+			return;
+		if (my.keySet().containsAll(other.keys.entrySet()))
+			return;
+		if (my.keys == null)
+			my.keys = other.keys;
 		else
-			myOsm.keys.putAll(otherOsm.keys);
-		myOsm.modifiedProperties = true;
+			my.keys.putAll(other.keys);
+		my.modified = true;
+	}
+
+	private <P extends OsmPrimitive> boolean mergeAfterId(Map<P,P> merged, Collection<P> primitives, P other) {
+		for (P my : primitives) {
+			if (my.realEqual(other))
+				return true; // no merge needed.
+			if (my.id == other.id) {
+				Date d1 = my.timestamp == null ? new Date(0) : my.timestamp;
+				Date d2 = other.timestamp == null ? new Date(0) : other.timestamp;
+				if (my.modified && other.modified) {
+					conflicts.put(my, other);
+					if (merged != null)
+						merged.put(other, my);
+				} else if (!my.modified && !other.modified) {
+					if (d1.before(d2)) {
+						my.cloneFrom(other);
+						if (merged != null)
+							merged.put(other, my);
+					}
+				} else if (other.modified) {
+					if (d1.after(d2)) {
+						conflicts.put(my, other);
+						if (merged != null)
+							merged.put(other, my);
+					} else {
+						my.cloneFrom(other);
+						if (merged != null)
+							merged.put(other, my);
+					}
+				} else if (my.modified) {
+					if (d2.after(d1)) {
+						conflicts.put(my, other);
+						if (merged != null)
+							merged.put(other, my);
+					}
+				}
+				return true;
+			}
+		}
+		return false;
 	}
 }
Index: /src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java	(revision 86)
@@ -7,5 +7,5 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -30,9 +30,9 @@
 	
 	/**
-	 * If the line segment has a key named "name", its value is displayed. 
+	 * If the segment has a key named "name", its value is displayed. 
 	 * Otherwise, if it has "id", this is used. If none of these available, 
 	 * "(x1,y1) -> (x2,y2)" is displayed with the nodes coordinates.
 	 */
-	public void visit(LineSegment ls) {
+	public void visit(Segment ls) {
 		name = ls.get("name");
 		if (name == null) {
@@ -65,5 +65,5 @@
 			AllNodesVisitor.getAllNodes(w.segments);
 			Set<Node> nodes = new HashSet<Node>();
-			for (LineSegment ls : w.segments) {
+			for (Segment ls : w.segments) {
 				if (!ls.incomplete) {
 					nodes.add(ls.from);
Index: /src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 86)
@@ -6,5 +6,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -32,5 +32,5 @@
 	 */
 	private final NavigatableComponent nc;
-	
+
 	/**
 	 * Construct the painter visitor.
@@ -42,5 +42,5 @@
 		this.nc = mv;
 	}
-	
+
 	/**
 	 * Draw a small rectangle. 
@@ -50,5 +50,5 @@
 	 */
 	public void visit(Node n) {
-		drawNode(n, n.isSelected() ? getPreferencesColor("selected", Color.WHITE)
+		drawNode(n, n.selected ? getPreferencesColor("selected", Color.WHITE)
 				: getPreferencesColor("node", Color.RED));
 	}
@@ -58,16 +58,16 @@
 	 * White if selected (as always) or green otherwise.
 	 */
-	public void visit(LineSegment ls) {
-		drawLineSegment(ls, getPreferencesColor("segment", darkgreen));
+	public void visit(Segment ls) {
+		drawSegment(ls, getPreferencesColor("segment", darkgreen));
 	}
 
 	/**
-	 * Draw a darkblue line for all line segments.
-	 * @param t The way to draw.
+	 * Draw a darkblue line for all segments.
+	 * @param w The way to draw.
 	 */
-	public void visit(Way t) {
+	public void visit(Way w) {
 		// only to overwrite with blue
 		Color wayColor = getPreferencesColor("way", darkblue);
-		for (LineSegment ls : t.segments) {
+		for (Segment ls : w.segments) {
 			if (ls.incomplete) {
 				wayColor = getPreferencesColor("incomplete way", darkerblue);
@@ -75,7 +75,7 @@
 			}
 		}
-		for (LineSegment ls : t.segments)
-			if (!ls.isSelected()) // selected already in good color
-				drawLineSegment(ls, t.isSelected() ? getPreferencesColor("selected", Color.WHITE) : wayColor);
+		for (Segment ls : w.segments)
+			if (!ls.selected) // selected already in good color
+				drawSegment(ls, w.selected ? getPreferencesColor("selected", Color.WHITE) : wayColor);
 	}
 
@@ -95,8 +95,8 @@
 	 * Draw a line with the given color.
 	 */
-	private void drawLineSegment(LineSegment ls, Color col) {
+	private void drawSegment(Segment ls, Color col) {
 		if (ls.incomplete)
 			return;
-		if (ls.isSelected())
+		if (ls.selected)
 			col = getPreferencesColor("selected", Color.WHITE);
 		g.setColor(col);
@@ -105,6 +105,6 @@
 		g.drawLine(p1.x, p1.y, p2.x, p2.y);
 	}
-	
-	private Color getPreferencesColor(String colName, Color def) {
+
+	public static Color getPreferencesColor(String colName, Color def) {
 		String colStr = Main.pref.get("color."+colName);
 		if (colStr.equals(""))
Index: /src/org/openstreetmap/josm/data/osm/visitor/Visitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 86)
@@ -1,5 +1,5 @@
 package org.openstreetmap.josm.data.osm.visitor;
 
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -13,5 +13,5 @@
 public interface Visitor {
 	void visit(Node n);
-	void visit(LineSegment ls);
+	void visit(Segment s);
 	void visit(Way w);
 }
Index: /src/org/openstreetmap/josm/data/projection/Epsg4326.java
===================================================================
--- /src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 86)
@@ -19,6 +19,5 @@
 	}
 
-	@Override
-	public String toString() {
+	@Override public String toString() {
 		return "EPSG:4326";
 	}
Index: /src/org/openstreetmap/josm/data/projection/Mercator.java
===================================================================
--- /src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 85)
+++ /src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 86)
@@ -27,6 +27,5 @@
 	}
 
-	@Override
-	public String toString() {
+	@Override public String toString() {
 		return "Mercator";
 	}
Index: /src/org/openstreetmap/josm/gui/BookmarkList.java
===================================================================
--- /src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 86)
@@ -47,6 +47,5 @@
 		setVisibleRowCount(7);
 		setCellRenderer(new DefaultListCellRenderer(){
-			@Override
-			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+			@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
 				Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 				if (c instanceof JLabel) {
Index: /src/org/openstreetmap/josm/gui/ConflictResolver.java
===================================================================
--- /src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 86)
+++ /src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 86)
@@ -0,0 +1,242 @@
+package org.openstreetmap.josm.gui;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.Map.Entry;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableModel;
+
+import org.openstreetmap.josm.data.conflict.ConflictItem;
+import org.openstreetmap.josm.data.conflict.DeleteConflict;
+import org.openstreetmap.josm.data.conflict.FromConflict;
+import org.openstreetmap.josm.data.conflict.PositionConflict;
+import org.openstreetmap.josm.data.conflict.PropertyConflict;
+import org.openstreetmap.josm.data.conflict.SegmentConflict;
+import org.openstreetmap.josm.data.conflict.ToConflict;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * A panel which implement the conflict resolving of a set of primitive-pairs. There will be
+ * three tables in the screen, one for each both sides and one resulting table. The user can
+ * move items from either one of the sides ("my" and "their") to the resulting table.
+ * 
+ * @author Imi
+ */
+public class ConflictResolver extends JPanel {
+
+	public static enum Resolution {MY, THEIR}
+
+	private final class ConflictTableModel implements TableModel {
+		private final Resolution resolution;
+		public ConflictTableModel(Resolution resolution) {
+			this.resolution = resolution;
+		}
+
+		public int getRowCount() {
+			return conflicts.size();
+		}
+
+		public Object getValueAt(int rowIndex, int columnIndex) {
+			ConflictItem ci = conflicts.get(rowIndex);
+			if (columnIndex == 0)
+				return ci.key();
+			Resolution r = resolution == null ? ci.resolution : resolution;
+			if (r == null)
+				return "<html><i>???</i></html>";
+			JLabel l = new JLabel(r == Resolution.MY ? ci.my : ci.their);
+			if (ci.resolution == resolution && resolution != null)
+				l.setFont(l.getFont().deriveFont(Font.BOLD));
+			return l;
+		}
+
+		public String getColumnName(int columnIndex) {return columnIndex == 0 ? "Key" : "Value";}
+		public int getColumnCount() {return 2;}
+		public boolean isCellEditable(int row, int column) {return false;}
+		public Class<?> getColumnClass(int columnIndex) {return Object.class;}
+
+		public void addTableModelListener(TableModelListener l) {}
+		public void removeTableModelListener(TableModelListener l) {}
+		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {}
+	}
+
+	private final class DblClickListener extends MouseAdapter {
+		private final Resolution resolution;
+		public DblClickListener(Resolution resolution) {
+			this.resolution = resolution;
+		}
+		@Override public void mouseClicked(MouseEvent e) {
+			if (e.getClickCount() >= 2) {
+				int sel = ((JTable)e.getSource()).getSelectedRow();
+				if (sel == -1)
+					return;
+				ConflictResolver.this.conflicts.get(sel).resolution = resolution;
+				repaint();
+			}
+		}
+	}
+	private final class ResolveAction extends AbstractAction {
+		private final Resolution resolution;
+		public ResolveAction(String name, Resolution resolution) {
+			super(null, ImageProvider.get("dialogs", name));
+			this.resolution = resolution;
+		}
+		public void actionPerformed(ActionEvent e) {
+			int sel = myTable.getSelectedRow();
+			if (sel == -1)
+				return;
+			conflicts.get(sel).resolution = resolution;
+			if (sel == myTable.getRowCount()-1)
+				myTable.clearSelection();
+			else
+				myTable.getSelectionModel().setSelectionInterval(sel+1, sel+1);
+			repaint();
+		}
+	}
+
+	public final List<ConflictItem> conflicts;
+
+	private final ConflictTableModel my = new ConflictTableModel(Resolution.MY);
+	private final JTable myTable = new JTable(my);
+	private final ConflictTableModel their = new ConflictTableModel(Resolution.THEIR);
+	private final JTable theirTable = new JTable(their);
+	private final ConflictTableModel resolve = new ConflictTableModel(null);
+	private final JTable resolveTable = new JTable(resolve);
+
+	
+	public ConflictResolver(Map<OsmPrimitive, OsmPrimitive> conflicts) {
+		super(new GridBagLayout());
+		this.conflicts = new ArrayList<ConflictItem>();
+		Collection<ConflictItem> possibleConflicts = new ArrayList<ConflictItem>();
+		possibleConflicts.add(new DeleteConflict());
+		possibleConflicts.add(new PositionConflict());
+		possibleConflicts.add(new FromConflict());
+		possibleConflicts.add(new ToConflict());
+		possibleConflicts.add(new SegmentConflict());
+		TreeSet<String> allkeys = new TreeSet<String>();
+		for (Entry<OsmPrimitive, OsmPrimitive> e : conflicts.entrySet()) {
+			allkeys.addAll(e.getKey().keySet());
+			allkeys.addAll(e.getValue().keySet());
+		}
+		for (String s : allkeys)
+			possibleConflicts.add(new PropertyConflict(s));
+		
+		for (Entry<OsmPrimitive, OsmPrimitive> e : conflicts.entrySet()) {
+			for (Iterator<ConflictItem> it = possibleConflicts.iterator(); it.hasNext();) {
+				ConflictItem ci = it.next();
+				if (ci.hasConflict(e.getKey(), e.getValue())) {
+					ci.initialize(conflicts);
+					this.conflicts.add(ci);
+					it.remove();
+				}
+			}
+		}
+		
+		if (this.conflicts.isEmpty())
+			throw new RuntimeException("No conflicts but in conflict list:\n" + Arrays.toString(conflicts.entrySet().toArray()));
+
+		myTable.setPreferredScrollableViewportSize(new Dimension(250,70));
+		theirTable.setPreferredScrollableViewportSize(new Dimension(250,70));
+		resolveTable.setPreferredScrollableViewportSize(new Dimension(250,70));
+
+		TableCellRenderer renderer = new DefaultTableCellRenderer(){
+			final Font defFont = new JLabel().getFont();
+			@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+				JLabel c = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+				c.setIcon(null);
+				c.setFont(defFont);
+				if (value instanceof JLabel) {
+					JLabel l = (JLabel)value;
+					String text = l.getText();
+					c.setText(text);
+					c.setFont(l.getFont());
+					if (text.startsWith("<html>") && l.getFont().isBold())
+						c.setText("<html>"+"<b>"+text.substring(6, text.length()-12));
+				} else {
+					String s = value.toString();
+					int i = s.indexOf('|');
+					if (i != -1) {
+						c.setIcon(ImageProvider.get("data", s.substring(0,i)));
+						c.setText(s.substring(i+1));
+					}
+				}
+				return c;
+			}
+		};
+		myTable.setDefaultRenderer(Object.class, renderer);
+		theirTable.setDefaultRenderer(Object.class, renderer);
+		resolveTable.setDefaultRenderer(Object.class, renderer);
+
+		myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		theirTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		resolveTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		ListSelectionListener selListener = new ListSelectionListener(){
+			public void valueChanged(ListSelectionEvent e) {
+				if (((ListSelectionModel)e.getSource()).isSelectionEmpty()) {
+					myTable.clearSelection();
+					theirTable.clearSelection();
+					resolveTable.clearSelection();
+				} else {
+					int i = ((ListSelectionModel)e.getSource()).getMinSelectionIndex();
+					myTable.scrollRectToVisible(myTable.getCellRect(i, 0, true));
+					myTable.getSelectionModel().setSelectionInterval(i, i);
+					theirTable.scrollRectToVisible(theirTable.getCellRect(i, 0, true));
+					theirTable.getSelectionModel().setSelectionInterval(i, i);
+					resolveTable.scrollRectToVisible(resolveTable.getCellRect(i, 0, true));
+					resolveTable.getSelectionModel().setSelectionInterval(i, i);
+				}
+			}
+		};
+		myTable.getSelectionModel().addListSelectionListener(selListener);
+		theirTable.getSelectionModel().addListSelectionListener(selListener);
+		resolveTable.getSelectionModel().addListSelectionListener(selListener);
+		myTable.getSelectionModel().setSelectionInterval(0,0);
+
+		myTable.addMouseListener(new DblClickListener(Resolution.MY));
+		theirTable.addMouseListener(new DblClickListener(Resolution.THEIR));
+		resolveTable.addMouseListener(new DblClickListener(null));
+
+		add(new JLabel(conflicts.size()+" object"+(conflicts.size()==1?" has":"s have")+" conflicts:"), GBC.eol().insets(0,0,0,10));
+
+		JPanel p = new JPanel(new GridBagLayout());
+		p.add(new JLabel("my version:"), GBC.eol());
+		p.add(new JScrollPane(myTable), GBC.eol().fill(GBC.BOTH));
+		p.add(new JButton(new ResolveAction("down", Resolution.MY)), GBC.eol().anchor(GBC.CENTER).insets(0,5,0,0));
+		add(p, GBC.std().insets(0,0,5,0));
+
+		p = new JPanel(new GridBagLayout());
+		p.add(new JLabel("their version:"), GBC.eol());
+		p.add(new JScrollPane(theirTable), GBC.eol().fill(GBC.BOTH));
+		p.add(new JButton(new ResolveAction("down", Resolution.THEIR)), GBC.eol().anchor(GBC.CENTER).insets(0,5,0,0));
+		add(p, GBC.eop().insets(5,0,0,0));
+
+		add(new JButton(new ResolveAction("up", null)), GBC.eol().anchor(GBC.CENTER));
+		add(new JLabel("resolved version:"), GBC.eol().insets(0,5,0,0));
+		add(new JScrollPane(resolveTable), GBC.eol().anchor(GBC.CENTER).fill(GBC.BOTH));
+	}
+}
Index: /src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/MapFrame.java	(revision 86)
@@ -15,5 +15,5 @@
 
 import org.openstreetmap.josm.actions.AutoScaleAction;
-import org.openstreetmap.josm.actions.mapmode.AddLineSegmentAction;
+import org.openstreetmap.josm.actions.mapmode.AddSegmentAction;
 import org.openstreetmap.josm.actions.mapmode.AddNodeAction;
 import org.openstreetmap.josm.actions.mapmode.AddWayAction;
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.actions.mapmode.SelectionAction;
 import org.openstreetmap.josm.actions.mapmode.ZoomAction;
+import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerList;
 import org.openstreetmap.josm.gui.dialogs.PropertiesDialog;
@@ -53,4 +54,7 @@
 	 */
 	public MapStatus statusLine;
+	
+	public ConflictDialog conflictDialog;
+	
 	/**
 	 * Construct a map with a given DataSet. The set cannot be replaced after 
@@ -73,5 +77,5 @@
 		toolBarActions.add(new IconToggleButton(new MoveAction(this)));
 		toolBarActions.add(new IconToggleButton(new AddNodeAction(this)));
-		toolBarActions.add(new IconToggleButton(new AddLineSegmentAction(this)));
+		toolBarActions.add(new IconToggleButton(new AddSegmentAction(this)));
 		toolBarActions.add(new IconToggleButton(new AddWayAction(this, selectionAction)));
 		toolBarActions.add(new IconToggleButton(new DeleteAction(this)));
@@ -104,4 +108,5 @@
 		addIconToggle(toggleDialogs, new PropertiesDialog(this));
 		addIconToggle(toggleDialogs, new SelectionListDialog(this));
+		addIconToggle(toggleDialogs, conflictDialog = new ConflictDialog());
 
 		// status line below the map
@@ -119,6 +124,5 @@
 	 * Fires an property changed event "visible".
 	 */
-	@Override
-	public void setVisible(boolean aFlag) {
+	@Override public void setVisible(boolean aFlag) {
 		boolean old = isVisible();
 		super.setVisible(aFlag);
Index: /src/org/openstreetmap/josm/gui/MapMover.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapMover.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/MapMover.java	(revision 86)
@@ -64,6 +64,5 @@
 	 * Start the movement, if it was the 3rd button (right button).
 	 */
-	@Override
-	public void mousePressed(MouseEvent e) {
+	@Override public void mousePressed(MouseEvent e) {
 		int offMask = MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
 		if (e.getButton() == MouseEvent.BUTTON3 && (e.getModifiersEx() & offMask) == 0)
@@ -74,6 +73,5 @@
 	 * Change the cursor back to it's pre-move cursor.
 	 */
-	@Override
-	public void mouseReleased(MouseEvent e) {
+	@Override public void mouseReleased(MouseEvent e) {
 		if (e.getButton() == MouseEvent.BUTTON3)
 			endMovement();
Index: /src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapStatus.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/MapStatus.java	(revision 86)
@@ -14,4 +14,5 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.ConcurrentModificationException;
@@ -135,5 +136,5 @@
 							osm.visit(visitor);
 							final StringBuilder text = new StringBuilder();
-							if (osm.id == 0 || osm.modified || osm.modifiedProperties)
+							if (osm.id == 0 || osm.modified)
 								visitor.name = "<i><b>"+visitor.name+"*</b></i>";
 							text.append(visitor.name);
@@ -147,16 +148,12 @@
 							l.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
 							l.addMouseListener(new MouseAdapter(){
-								@Override
-								public void mouseEntered(MouseEvent e) {
+								@Override public void mouseEntered(MouseEvent e) {
 									l.setText("<html><u color='blue'>"+text.toString()+"</u></html>");
 								}
-								@Override
-								public void mouseExited(MouseEvent e) {
+								@Override public void mouseExited(MouseEvent e) {
 									l.setText("<html>"+text.toString()+"</html>");
 								}
-								@Override
-								public void mouseClicked(MouseEvent e) {
-									Main.main.ds.clearSelection();
-									osm.setSelected(true);
+								@Override public void mouseClicked(MouseEvent e) {
+									Main.ds.setSelected(Arrays.asList(new OsmPrimitive[]{osm}));
 									mv.repaint();
 								}
Index: /src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /src/org/openstreetmap/josm/gui/MapView.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/MapView.java	(revision 86)
@@ -13,7 +13,9 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.data.projection.Projection;
@@ -76,6 +78,5 @@
 	public MapView(Layer layer) {
 		addComponentListener(new ComponentAdapter(){
-			@Override
-			public void componentResized(ComponentEvent e) {
+			@Override public void componentResized(ComponentEvent e) {
 				recalculateCenterScale();
 			}
@@ -83,4 +84,11 @@
 		new MapMover(this);
 		addLayer(layer);
+		
+		// listend to selection changes to redraw the map
+		Main.ds.addSelectionChangedListener(new SelectionChangedListener(){
+			public void selectionChanged(Collection<OsmPrimitive> newSelection) {
+				repaint();
+            }
+		});
 	}
 
@@ -155,6 +163,5 @@
 	 * Draw the component.
 	 */
-	@Override
-	public void paint(Graphics g) {
+	@Override public void paint(Graphics g) {
 		g.setColor(Color.BLACK);
 		g.fillRect(0, 0, getWidth(), getHeight());
@@ -218,5 +225,5 @@
 			double oldScale = this.scale;
 			
-			if (v.min == null || v.max == null) {
+			if (v.min == null || v.max == null || v.min.equals(v.max)) {
 				// no bounds means whole world 
 				center = getProjection().latlon2eastNorth(new LatLon(0,0));
@@ -225,5 +232,4 @@
 				double scaleY = world.north()*2/h;
 				scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
-				
 			} else {
 				center = new EastNorth(v.min.east()/2+v.max.east()/2, v.min.north()/2+v.max.north()/2);
@@ -277,5 +283,5 @@
 		activeLayer = layer;
 		if (layer instanceof OsmDataLayer)
-			Main.main.ds = ((OsmDataLayer)layer).data;
+			Main.ds = ((OsmDataLayer)layer).data;
 		if (old != layer) {
 			for (LayerChangeListener l : listeners)
@@ -306,6 +312,5 @@
 	 * feature.
 	 */
-	@Override
-	public void zoomTo(EastNorth newCenter, double scale) {
+	@Override public void zoomTo(EastNorth newCenter, double scale) {
 		boolean oldAutoScale = autoScale;
 		EastNorth oldCenter = center;
Index: /src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- /src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 86)
@@ -10,5 +10,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -109,12 +109,12 @@
 	 * nearest node is returned.
 	 * 
-	 * If no node is found, search for pending line segments.
-	 * 
-	 * If no such line segment is found, and a non-pending line segment is 
+	 * If no node is found, search for pending segments.
+	 * 
+	 * If no such segment is found, and a non-pending segment is 
 	 * within 10 pixel to p, this segment is returned, except when 
 	 * <code>wholeWay</code> is <code>true</code>, in which case the 
 	 * corresponding Way is returned.
 	 * 
-	 * If no line segment is found and the point is within an area, return that
+	 * If no segment is found and the point is within an area, return that
 	 * area.
 	 * 
@@ -122,5 +122,5 @@
 	 * 
 	 * @param p				 The point on screen.
-	 * @param segmentInsteadWay Whether the line segment (true) or only the whole
+	 * @param segmentInsteadWay Whether the segment (true) or only the whole
 	 * 					 	 way should be returned.
 	 * @return	The primitive, that is nearest to the point p.
@@ -131,6 +131,6 @@
 	
 		// nodes
-		for (Node n : Main.main.ds.nodes) {
-			if (n.isDeleted())
+		for (Node n : Main.ds.nodes) {
+			if (n.deleted)
 				continue;
 			Point sp = getPoint(n.eastNorth);
@@ -147,9 +147,9 @@
 		minDistanceSq = Double.MAX_VALUE;
 		if (!segmentInsteadWay) {
-			for (Way w : Main.main.ds.ways) {
-				if (w.isDeleted())
+			for (Way w : Main.ds.ways) {
+				if (w.deleted)
 					continue;
-				for (LineSegment ls : w.segments) {
-					if (ls.isDeleted() || ls.incomplete)
+				for (Segment ls : w.segments) {
+					if (ls.deleted || ls.incomplete)
 						continue;
 					Point A = getPoint(ls.from.eastNorth);
@@ -170,7 +170,7 @@
 		
 		minDistanceSq = Double.MAX_VALUE;
-		// line segments
-		for (LineSegment ls : Main.main.ds.lineSegments) {
-			if (ls.isDeleted() || ls.incomplete)
+		// segments
+		for (Segment ls : Main.ds.segments) {
+			if (ls.deleted || ls.incomplete)
 				continue;
 			Point A = getPoint(ls.from.eastNorth);
@@ -194,11 +194,11 @@
 	 * determined.
 	 * 
-	 * If its a node, return all line segments and
+	 * If its a node, return all segments and
 	 * streets the node is part of, as well as all nodes
-	 * (with their line segments and ways) with the same
+	 * (with their segments and ways) with the same
 	 * location.
 	 * 
-	 * If its a line segment, return all ways this segment 
-	 * belongs to as well as all line segments that are between
+	 * If its a segment, return all ways this segment 
+	 * belongs to as well as all segments that are between
 	 * the same nodes (in both direction) with all their ways.
 	 * 
@@ -215,24 +215,24 @@
 		if (osm instanceof Node) {
 			Node node = (Node)osm;
-			for (Node n : Main.main.ds.nodes)
-				if (!n.isDeleted() && n.coor.equals(node.coor))
+			for (Node n : Main.ds.nodes)
+				if (!n.deleted && n.coor.equals(node.coor))
 					c.add(n);
-			for (LineSegment ls : Main.main.ds.lineSegments)
-				// line segments never match nodes, so they are skipped by contains
-				if (!ls.isDeleted() && !ls.incomplete && (c.contains(ls.from) || c.contains(ls.to)))
+			for (Segment ls : Main.ds.segments)
+				// segments never match nodes, so they are skipped by contains
+				if (!ls.deleted && !ls.incomplete && (c.contains(ls.from) || c.contains(ls.to)))
 					c.add(ls);
 		} 
-		if (osm instanceof LineSegment) {
-			LineSegment line = (LineSegment)osm;
-			for (LineSegment ls : Main.main.ds.lineSegments)
-				if (!ls.isDeleted() && ls.equalPlace(line))
+		if (osm instanceof Segment) {
+			Segment line = (Segment)osm;
+			for (Segment ls : Main.ds.segments)
+				if (!ls.deleted && ls.equalPlace(line))
 					c.add(ls);
 		}
-		if (osm instanceof Node || osm instanceof LineSegment) {
-			for (Way t : Main.main.ds.ways) {
-				if (t.isDeleted())
+		if (osm instanceof Node || osm instanceof Segment) {
+			for (Way t : Main.ds.ways) {
+				if (t.deleted)
 					continue;
-				for (LineSegment ls : t.segments) {
-					if (!ls.isDeleted() && !ls.incomplete && c.contains(ls)) {
+				for (Segment ls : t.segments) {
+					if (!ls.deleted && !ls.incomplete && c.contains(ls)) {
 						c.add(t);
 						break;
Index: /src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 86)
@@ -18,6 +18,5 @@
 	private SelectionComponentVisitor visitor = new SelectionComponentVisitor();
 
-	@Override
-	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+	@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
 		Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 		if (c instanceof JLabel && value != null) {
Index: /src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 86)
@@ -153,5 +153,5 @@
 	 * The checkbox stating whether raw gps lines should be forced.
 	 */
-	private JCheckBox forceRawGpsLines = new JCheckBox("Force lines if no line segments imported.");
+	private JCheckBox forceRawGpsLines = new JCheckBox("Force lines if no segments imported.");
 
 	private JTable colors;
Index: /src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- /src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 86)
@@ -16,5 +16,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -257,5 +257,5 @@
 	 * @param alt Whether the alt key was pressed, which means select all objects
 	 * 		that are touched, instead those which are completly covered. Also 
-	 * 		select whole ways instead of line segments.
+	 * 		select whole ways instead of segments.
 	 */
 	public Collection<OsmPrimitive> getObjectsInRectangle(Rectangle r, boolean alt) {
@@ -272,19 +272,19 @@
 		} else {
 			// nodes
-			for (Node n : Main.main.ds.nodes) {
+			for (Node n : Main.ds.nodes) {
 				if (r.contains(nc.getPoint(n.eastNorth)))
 					selection.add(n);
 			}
 			
-			// pending line segments
-			for (LineSegment ls : Main.main.ds.lineSegments)
-				if (rectangleContainLineSegment(r, alt, ls))
+			// pending segments
+			for (Segment ls : Main.ds.segments)
+				if (rectangleContainSegment(r, alt, ls))
 					selection.add(ls);
 
 			// ways
-			for (Way t : Main.main.ds.ways) {
+			for (Way t : Main.ds.ways) {
 				boolean wholeWaySelected = !t.segments.isEmpty();
-				for (LineSegment ls : t.segments)
-					if (rectangleContainLineSegment(r, alt, ls))
+				for (Segment ls : t.segments)
+					if (rectangleContainSegment(r, alt, ls))
 						selection.add(ls);
 					else
@@ -300,13 +300,13 @@
 
 	/**
-	 * Decide whether the line segment is in the rectangle Return 
+	 * Decide whether the segment is in the rectangle Return 
 	 * <code>true</code>, if it is in or false if not.
 	 * 
-	 * @param r			The rectangle, in which the line segment has to be.
+	 * @param r			The rectangle, in which the segment has to be.
 	 * @param alt		Whether user pressed the Alt key
-	 * @param ls		The line segment.
-	 * @return <code>true</code>, if the LineSegment was added to the selection.
-	 */
-	private boolean rectangleContainLineSegment(Rectangle r, boolean alt, LineSegment ls) {
+	 * @param ls		The segment.
+	 * @return <code>true</code>, if the Segment was added to the selection.
+	 */
+	private boolean rectangleContainSegment(Rectangle r, boolean alt, Segment ls) {
 		if (ls.incomplete)
 			return false;
Index: /src/org/openstreetmap/josm/gui/ShowModifiers.java
===================================================================
--- /src/org/openstreetmap/josm/gui/ShowModifiers.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/ShowModifiers.java	(revision 86)
@@ -131,6 +131,5 @@
 	}
 
-	@Override
-	public void paint(Graphics g) {
+	@Override public void paint(Graphics g) {
 		super.paint(g);
 		paintMouse(g);
Index: /src/org/openstreetmap/josm/gui/WorldChooser.java
===================================================================
--- /src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 86)
@@ -72,6 +72,5 @@
 						p.east()*360/world.getIconWidth() - 180);
 			}
-			@Override
-			public String toString() {
+			@Override public String toString() {
 				return "WorldChooser";
 			}
@@ -87,6 +86,5 @@
 	 * Set the scale as well as the preferred size.
 	 */
-	@Override
-	public void setPreferredSize(Dimension preferredSize) {
+	@Override public void setPreferredSize(Dimension preferredSize) {
 		super.setPreferredSize(preferredSize);
 		scale = world.getIconWidth()/preferredSize.getWidth();
@@ -98,6 +96,5 @@
 	 * Draw the current selected region.
 	 */
-	@Override
-	public void paint(Graphics g) {
+	@Override public void paint(Graphics g) {
 		EastNorth tl = getEastNorth(0,0);
 		EastNorth br = getEastNorth(getWidth(),getHeight());
@@ -122,6 +119,5 @@
 
 
-	@Override
-	public void zoomTo(EastNorth newCenter, double scale) {
+	@Override public void zoomTo(EastNorth newCenter, double scale) {
 		if (getWidth() != 0 && scale > scaleMax) {
 			scale = scaleMax;
@@ -158,6 +154,5 @@
 		// messages are dispatched and so text fields are updated.
 		KeyListener listener = new KeyAdapter(){
-			@Override
-			public void keyTyped(KeyEvent e) {
+			@Override public void keyTyped(KeyEvent e) {
 				SwingUtilities.invokeLater(new Runnable(){
 					public void run() {
@@ -216,6 +211,5 @@
 	 * Always use our image projection mode.
 	 */
-	@Override
-	protected Projection getProjection() {
+	@Override protected Projection getProjection() {
 		return projection;
 	}
Index: /src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 86)
+++ /src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 86)
@@ -0,0 +1,157 @@
+package org.openstreetmap.josm.gui.dialogs;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.ConflictResolveCommand;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+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.data.osm.visitor.SimplePaintVisitor;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.gui.ConflictResolver;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public final class ConflictDialog extends ToggleDialog {
+
+	public final Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
+	public final DefaultListModel model = new DefaultListModel();
+	private final JList displaylist = new JList(model);
+
+	public ConflictDialog() {
+		super("Conflict", "Conflict Dialog", "merge", "Merging conflicts.", "C", KeyEvent.VK_C, "conflict");
+		displaylist.setCellRenderer(new OsmPrimitivRenderer());
+		displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		displaylist.addMouseListener(new MouseAdapter(){
+			@Override public void mouseClicked(MouseEvent e) {
+				if (e.getClickCount() >= 2)
+					resolve();
+			}
+		});
+		add(new JScrollPane(displaylist), BorderLayout.CENTER);
+
+		JPanel buttonPanel = new JPanel(new GridLayout(1,2));
+		JButton button = new JButton("Resolve", ImageProvider.get("dialogs", "merge"));
+		button.setToolTipText("Open a merge dialog of all selected items in the list above.");
+		button.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				resolve();
+			}
+		});
+		buttonPanel.add(button);
+
+		button = new JButton("Select", ImageProvider.get("mapmode", "selection"));
+		button.setToolTipText("Set the selected elements on the map to the selected items in the list above.");
+		button.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+				for (Object o : displaylist.getSelectedValues())
+					sel.add((OsmPrimitive)o);
+				Main.ds.setSelected(sel);
+			}
+		});
+		buttonPanel.add(button);
+
+		add(buttonPanel, BorderLayout.SOUTH);
+
+		Main.ds.addSelectionChangedListener(new SelectionChangedListener(){
+			public void selectionChanged(Collection<OsmPrimitive> newSelection) {
+				displaylist.clearSelection();
+				for (OsmPrimitive osm : newSelection) {
+					if (conflicts.containsKey(osm)) {
+						int pos = model.indexOf(osm);
+						displaylist.addSelectionInterval(pos, pos);
+					}
+				}
+			}
+		});
+		displaylist.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
+			public void valueChanged(ListSelectionEvent e) {
+				Main.main.getMapFrame().mapView.repaint();
+			}
+		});
+	}
+
+	private final void resolve() {
+		if (displaylist.getSelectedIndex() == -1) {
+			JOptionPane.showMessageDialog(Main.main, "Please select something from the conflict list.");
+			return;
+		}
+		Map<OsmPrimitive, OsmPrimitive> sel = new HashMap<OsmPrimitive, OsmPrimitive>();
+		for (int i : displaylist.getSelectedIndices()) {
+			OsmPrimitive s = (OsmPrimitive)model.get(i);
+			sel.put(s, conflicts.get(s));
+		}
+		ConflictResolver resolver = new ConflictResolver(sel);
+		int answer = JOptionPane.showConfirmDialog(Main.main, resolver, "Resolve Conflicts", JOptionPane.OK_CANCEL_OPTION);
+		if (answer != JOptionPane.OK_OPTION)
+			return;
+		MapView mv = Main.main.getMapFrame().mapView;
+		mv.editLayer().add(new ConflictResolveCommand(resolver.conflicts, sel));
+		mv.repaint();
+	}
+
+	public final void add(Map<OsmPrimitive, OsmPrimitive> conflicts) {
+		this.conflicts.putAll(conflicts);
+		model.removeAllElements();
+		for (OsmPrimitive osm : this.conflicts.keySet())
+			model.addElement(osm);
+	}
+
+	/**
+	 * Paint all conflicts that can be expressed on the main window. 
+	 */
+	public void paintConflicts(final Graphics g, final NavigatableComponent nc) {
+		Color preferencesColor = SimplePaintVisitor.getPreferencesColor("conflict", Color.GRAY);
+		if (preferencesColor.equals(Color.BLACK))
+			return;
+		g.setColor(preferencesColor);
+		Visitor conflictPainter = new Visitor(){
+			public void visit(Node n) {
+				Point p = nc.getPoint(n.eastNorth);
+				g.drawRect(p.x-1, p.y-1, 2, 2);
+			}
+			public void visit(Segment ls) {
+				if (ls.incomplete)
+					return;
+				Point p1 = nc.getPoint(ls.from.eastNorth);
+				Point p2 = nc.getPoint(ls.to.eastNorth);
+				g.drawLine(p1.x, p1.y, p2.x, p2.y);
+			}
+			public void visit(Way w) {
+				for (Segment ls : w.segments)
+					visit(ls);
+			}
+		};
+		for (Object o : displaylist.getSelectedValues())
+			conflicts.get(o).visit(conflictPainter);
+	}
+}
Index: /src/org/openstreetmap/josm/gui/dialogs/LayerList.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/dialogs/LayerList.java	(revision 86)
@@ -59,5 +59,5 @@
         	if (layers.getModel().getSize() == 1) {
         		Main.main.setMapFrame(null);
-        		Main.main.ds = new DataSet();
+        		Main.ds = new DataSet();
         	} else {
         	    int sel = layers.getSelectedIndex();
@@ -133,6 +133,5 @@
 		layers.setBackground(UIManager.getColor("Button.background"));
 		layers.setCellRenderer(new DefaultListCellRenderer(){
-			@Override
-			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+			@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
 				Layer layer = (Layer)value;
 				JLabel label = (JLabel)super.getListCellRendererComponent(list, 
Index: /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java	(revision 86)
@@ -1,22 +1,13 @@
 package org.openstreetmap.josm.gui.dialogs;
 
-import java.awt.Color;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 
-import javax.swing.JColorChooser;
+import javax.swing.AbstractAction;
 import javax.swing.JList;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.GpxExportAction;
-import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.layer.RawGpsDataLayer;
-import org.openstreetmap.josm.gui.layer.WmsServerLayer;
-import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -26,49 +17,21 @@
 public class LayerListPopup extends JPopupMenu {
 
+	public final static class InfoAction extends AbstractAction {
+	    private final Layer layer;
+	    public InfoAction(Layer layer) {
+	    	super("Info", ImageProvider.get("info"));
+		    this.layer = layer;
+	    }
+	    public void actionPerformed(ActionEvent e) {
+	    	JOptionPane.showMessageDialog(Main.main, layer.getInfoComponent());
+	    }
+    }
+
 	public LayerListPopup(final JList layers, final Layer layer) {
-        add(new LayerList.ShowHideLayerAction(layers, layer));
-        add(new LayerList.DeleteLayerAction(layers, layer));
-        addSeparator();
-        
-		if (layer instanceof OsmDataLayer)
-			add(new JMenuItem(new SaveAction()));
+		add(new LayerList.ShowHideLayerAction(layers, layer));
+		add(new LayerList.DeleteLayerAction(layers, layer));
+		addSeparator();
 
-        if (!(layer instanceof WmsServerLayer))
-            add(new JMenuItem(new GpxExportAction(layer)));
-
-		if (layer instanceof RawGpsDataLayer) {
-			JMenuItem color = new JMenuItem("Customize Color", ImageProvider.get("colorchooser"));
-			color.addActionListener(new ActionListener(){
-				public void actionPerformed(ActionEvent e) {
-					String col = Main.pref.get("color.layer "+layer.name, Main.pref.get("color.gps point", ColorHelper.color2html(Color.gray)));
-					JColorChooser c = new JColorChooser(ColorHelper.html2color(col));
-					Object[] options = new Object[]{"OK", "Cancel", "Default"};
-					int answer = JOptionPane.showOptionDialog(Main.main, c, "Choose a color", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
-					switch (answer) {
-					case 0:
-						Main.pref.put("color.layer "+layer.name, ColorHelper.color2html(c.getColor()));
-						break;
-					case 1:
-						return;
-					case 2:
-						Main.pref.put("color.layer "+layer.name, null);
-						break;
-					}
-					Main.main.repaint();
-				}
-			});
-			add(color);
-		}
-
-        if (!(layer instanceof WmsServerLayer))
-            addSeparator();
-
-		JMenuItem info = new JMenuItem("Info", ImageProvider.get("info"));
-		info.addActionListener(new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				JOptionPane.showMessageDialog(Main.main, layer.getInfoComponent());
-			}
-		});
-		add(info);
+		layer.addMenuEntries(this);
 	}
 }
Index: /src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 86)
@@ -36,5 +36,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.ChangeKeyValueCommand;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -68,6 +68,5 @@
 	 */
 	public class DblClickWatch extends MouseAdapter {
-		@Override
-		public void mouseClicked(MouseEvent e) {
+		@Override public void mouseClicked(MouseEvent e) {
 			if (e.getClickCount() < 2)
 				return;
@@ -87,5 +86,5 @@
 	void edit(int row) {
 		String key = data.getValueAt(row, 0).toString();
-		Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
 		String msg = "<html>This will change "+sel.size()+" object"+(sel.size()==1?"":"s")+".<br><br>"+
 		"Please select a new value for '"+key+"'.<br>(Empty string deletes the key.)";
@@ -125,5 +124,5 @@
 		if (value.equals(""))
 			value = null; // delete the key
-		mv.editLayer().add(new ChangeKeyValueCommand(sel, key, value));
+		mv.editLayer().add(new ChangePropertyCommand(sel, key, value));
 
 		if (value == null)
@@ -138,5 +137,5 @@
 	 */
 	void add() {
-		Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
 		
 		JPanel p = new JPanel(new BorderLayout());
@@ -144,5 +143,5 @@
 		"Please select a key"), BorderLayout.NORTH);
 		Vector<String> allKeys = new Vector<String>();
-		for (OsmPrimitive osm : Main.main.ds.allNonDeletedPrimitives())
+		for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives())
 			allKeys.addAll(osm.keySet());
 		for (Iterator<String> it = allKeys.iterator(); it.hasNext();) {
@@ -172,5 +171,5 @@
 		if (value.equals(""))
 			return;
-		mv.editLayer().add(new ChangeKeyValueCommand(sel, key, value));
+		mv.editLayer().add(new ChangePropertyCommand(sel, key, value));
 		selectionChanged(sel); // update table
 	}
@@ -182,6 +181,6 @@
 	private void delete(int row) {
 		String key = data.getValueAt(row, 0).toString();
-		Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
-		mv.editLayer().add(new ChangeKeyValueCommand(sel, key, null));
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
+		mv.editLayer().add(new ChangePropertyCommand(sel, key, null));
 		selectionChanged(sel); // update table
 	}
@@ -191,10 +190,8 @@
 	 */
 	private final DefaultTableModel data = new DefaultTableModel(){
-		@Override
-		public boolean isCellEditable(int row, int column) {
+		@Override public boolean isCellEditable(int row, int column) {
 			return false;
 		}
-		@Override
-		public Class<?> getColumnClass(int columnIndex) {
+		@Override public Class<?> getColumnClass(int columnIndex) {
 			return columnIndex == 1 ? JComboBox.class : String.class;
 		}
@@ -221,6 +218,5 @@
 		propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 		propertyTable.setDefaultRenderer(JComboBox.class, new DefaultTableCellRenderer(){
-			@Override
-			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+			@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 				Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
 				if (c instanceof JLabel) {
@@ -234,6 +230,5 @@
 		});
 		propertyTable.setDefaultRenderer(String.class, new DefaultTableCellRenderer(){
-			@Override
-			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+			@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 				return super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
 			}
@@ -279,11 +274,10 @@
 	}
 
-	@Override
-	public void setVisible(boolean b) {
+	@Override public void setVisible(boolean b) {
 		if (b) {
-			Main.main.ds.addSelectionChangedListener(this);
-			selectionChanged(Main.main.ds.getSelected());
+			Main.ds.addSelectionChangedListener(this);
+			selectionChanged(Main.ds.getSelected());
 		} else {
-			Main.main.ds.removeSelectionChangedListener(this);
+			Main.ds.removeSelectionChangedListener(this);
 		}
 		super.setVisible(b);
@@ -291,4 +285,6 @@
 
 	public void selectionChanged(Collection<OsmPrimitive> newSelection) {
+		if (propertyTable == null)
+			return; // selection changed may be received in base class constructor before init
 		if (propertyTable.getCellEditor() != null)
 			propertyTable.getCellEditor().cancelCellEditing();
Index: /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 86)
@@ -11,4 +11,5 @@
 import java.awt.event.MouseEvent;
 import java.util.Collection;
+import java.util.LinkedList;
 
 import javax.swing.ButtonGroup;
@@ -61,6 +62,5 @@
 		displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 		displaylist.addMouseListener(new MouseAdapter(){
-			@Override
-			public void mouseClicked(MouseEvent e) {
+			@Override public void mouseClicked(MouseEvent e) {
 				if (e.getClickCount() < 2)
 					return;
@@ -122,14 +122,17 @@
 				lastSearch = input.getText();
 				SearchCompiler.Match matcher = SearchCompiler.compile(lastSearch);
-				for (OsmPrimitive osm : Main.main.ds.allNonDeletedPrimitives()) {
-					if (replace.isSelected())
-						osm.setSelected(matcher.match(osm));
-					else if (add.isSelected() && !osm.isSelected() && matcher.match(osm))
-						osm.setSelected(true);
-					else if (remove.isSelected() && osm.isSelected() && matcher.match(osm))
-						osm.setSelected(false);
+				Collection<OsmPrimitive> sel = Main.ds.getSelected();
+				for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) {
+					if (replace.isSelected()) {
+						if (matcher.match(osm))
+							sel.add(osm);
+						else
+							sel.remove(osm);
+					} else if (add.isSelected() && !osm.selected && matcher.match(osm))
+						sel.add(osm);
+					else if (remove.isSelected() && osm.selected && matcher.match(osm))
+						sel.remove(osm);
 				}
-				selectionChanged(Main.main.ds.getSelected());
-				Main.main.getMapFrame().repaint();
+				Main.ds.setSelected(sel);
 			}
 		});
@@ -137,14 +140,13 @@
 		
 		add(buttonPanel, BorderLayout.SOUTH);
-		selectionChanged(Main.main.ds.getSelected());
+		selectionChanged(Main.ds.getSelected());
 	}
 
-	@Override
-	public void setVisible(boolean b) {
+	@Override public void setVisible(boolean b) {
 		if (b) {
-			Main.main.ds.addSelectionChangedListener(this);
-			selectionChanged(Main.main.ds.getSelected());
+			Main.ds.addSelectionChangedListener(this);
+			selectionChanged(Main.ds.getSelected());
 		} else {
-			Main.main.ds.removeSelectionChangedListener(this);
+			Main.ds.removeSelectionChangedListener(this);
 		}
 		super.setVisible(b);
@@ -158,4 +160,6 @@
 	 */
 	public void selectionChanged(Collection<OsmPrimitive> newSelection) {
+		if (list == null)
+			return; // selection changed may be received in base class constructor before init
 		list.removeAllElements();
 		list.setSize(newSelection.size());
@@ -169,9 +173,9 @@
 	 */
 	public void updateMap() {
-		Main.main.ds.clearSelection();
+		Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
 		for (int i = 0; i < list.getSize(); ++i)
 			if (displaylist.isSelectedIndex(i))
-				((OsmPrimitive)list.get(i)).setSelected(true);
-		Main.main.getMapFrame().repaint();
+				sel.add((OsmPrimitive)list.get(i));
+		Main.ds.setSelected(sel);
 	}
 }
Index: /src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- /src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 86)
@@ -32,5 +32,4 @@
 	 * @param title The title of the dialog.
      * @param prefName Name of the base preference setting string (prefix)
-     *      with the final . (e.g.: "layerlist.")
 	 */
 	public ToggleDialog(String title, String name, String iconName, String tooltip, String shortCutName, int shortCut, final String prefName) {
@@ -41,5 +40,5 @@
 					show = ((AbstractButton)e.getSource()).isSelected();
 				setVisible(show);
-                Main.pref.put(prefName+"visible", show);
+                Main.pref.put(prefName+".visible", show);
 			}
 		};
@@ -48,5 +47,5 @@
 		setVisible(false);
 		setBorder(BorderFactory.createEtchedBorder());
-		if (Main.pref.getBoolean(prefName+"visible")) {
+		if (Main.pref.getBoolean(prefName+".visible")) {
 		    EventQueue.invokeLater(new Runnable(){
 		        public void run() {
Index: /src/org/openstreetmap/josm/gui/layer/Layer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/layer/Layer.java	(revision 86)
@@ -4,4 +4,5 @@
 
 import javax.swing.Icon;
+import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
@@ -80,3 +81,5 @@
 
 	abstract public Object getInfoComponent();
+	
+	abstract public void addMenuEntries(JPopupMenu menu);
 }
Index: /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 86)
@@ -12,10 +12,14 @@
 import javax.swing.Icon;
 import javax.swing.JLabel;
+import javax.swing.JMenuItem;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.GpxExportAction;
+import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -26,4 +30,5 @@
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -37,8 +42,32 @@
 public class OsmDataLayer extends Layer {
 
+	public final static class DataCountVisitor implements Visitor {
+		public final int[] normal = new int[3];		
+		public final int[] deleted = new int[3];
+		public final String[] names = {"node", "segment", "way"};
+
+		private void inc(OsmPrimitive osm, int i) {
+			normal[i]++;
+			if (osm.deleted)
+				deleted[i]++;
+		}
+
+		public void visit(Node n) {
+			inc(n, 0);
+		}
+
+		public void visit(Segment ls) {
+			inc(ls, 1);
+		}
+
+		public void visit(Way w) {
+			inc(w, 2);
+		}
+	}
+
 	public interface ModifiedChangedListener {
 		void modifiedChanged(boolean value, OsmDataLayer source);
 	}
-	
+
 	private static Icon icon;
 
@@ -75,5 +104,5 @@
 	LinkedList<ModifiedChangedListener> listener;
 
-	
+
 	/**
 	 * Construct a OsmDataLayer.
@@ -89,6 +118,5 @@
 	 * 		updated by a background thread to not disturb the running programm.
 	 */
-	@Override
-	public Icon getIcon() {
+	@Override public Icon getIcon() {
 		if (icon == null)
 			icon = ImageProvider.get("layer", "osmdata");
@@ -99,45 +127,44 @@
 	 * Draw all primitives in this layer but do not draw modified ones (they
 	 * are drawn by the edit layer).
-	 * Draw nodes last to overlap the line segments they belong to.
-	 */
-	@Override
-	public void paint(Graphics g, MapView mv) {
+	 * Draw nodes last to overlap the segments they belong to.
+	 */
+	@Override public void paint(Graphics g, MapView mv) {
 		SimplePaintVisitor visitor = new SimplePaintVisitor(g, mv);
-		for (OsmPrimitive osm : data.lineSegments)
-			if (!osm.isDeleted())
+		for (OsmPrimitive osm : data.segments)
+			if (!osm.deleted)
 				osm.visit(visitor);
 		for (OsmPrimitive osm : data.ways)
-			if (!osm.isDeleted())
+			if (!osm.deleted)
 				osm.visit(visitor);
 		for (OsmPrimitive osm : data.nodes)
-			if (!osm.isDeleted())
+			if (!osm.deleted)
 				osm.visit(visitor);
 		for (OsmPrimitive osm : data.getSelected())
-			if (!osm.isDeleted())
+			if (!osm.deleted)
 				osm.visit(visitor);
-	}
-
-	@Override
-	public String getToolTipText() {
+		Main.main.getMapFrame().conflictDialog.paintConflicts(g, mv);
+	}
+
+	@Override public String getToolTipText() {
 		return undeletedSize(data.nodes)+" nodes, "+
-			undeletedSize(data.lineSegments)+" segments, "+
-			undeletedSize(data.ways)+" streets.";
-	}
-
-	@Override
-	public void mergeFrom(Layer from) {
-		MergeVisitor visitor = new MergeVisitor(data);
+		undeletedSize(data.segments)+" segments, "+
+		undeletedSize(data.ways)+" streets.";
+	}
+
+	@Override public void mergeFrom(Layer from) {
+		final MergeVisitor visitor = new MergeVisitor(data);
 		for (OsmPrimitive osm : ((OsmDataLayer)from).data.allPrimitives())
 			osm.visit(visitor);
 		visitor.fixReferences();
-	}
-
-	@Override
-	public boolean isMergable(Layer other) {
+		if (visitor.conflicts.isEmpty())
+			return;
+		Main.main.getMapFrame().conflictDialog.add(visitor.conflicts);
+	}
+
+	@Override public boolean isMergable(Layer other) {
 		return other instanceof OsmDataLayer;
 	}
 
-	@Override
-	public void visitBoundingBox(BoundingXYVisitor v) {
+	@Override public void visitBoundingBox(BoundingXYVisitor v) {
 		for (Node n : data.nodes)
 			v.visit(n);
@@ -150,5 +177,5 @@
 		return commands.isEmpty() ? null : commands.getLast();
 	}
-	
+
 	/**
 	 * Execute the command and add it to the intern command queue. Also mark all
@@ -214,5 +241,5 @@
 			for (Iterator<Node> it = data.nodes.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
-			for (Iterator<LineSegment> it = data.lineSegments.iterator(); it.hasNext();)
+			for (Iterator<Segment> it = data.segments.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
 			for (Iterator<Way> it = data.ways.iterator(); it.hasNext();)
@@ -221,8 +248,8 @@
 
 		// update the modified flag
-		
+
 		if (fromDisk && processed != null && !dataAdded)
 			return; // do nothing when uploading non-harmful changes.
-		
+
 		// modified if server changed the data (esp. the id).
 		uploadedModified = fromDisk && processed != null && dataAdded;
@@ -246,6 +273,5 @@
 			return;
 		osm.modified = false;
-		osm.modifiedProperties = false;
-		if (osm.isDeleted())
+		if (osm.deleted)
 			it.remove();
 	}
@@ -280,42 +306,29 @@
 		int size = 0;
 		for (OsmPrimitive osm : list)
-			if (!osm.isDeleted())
+			if (!osm.deleted)
 				size++;
 		return size;
 	}
 
-	@Override
-	public Object getInfoComponent() {
-		final int[] normal = new int[3];		
-		final int[] deleted = new int[3];
-		final String[] names = {"node", "segment", "way"};
-		Visitor counter = new Visitor(){
-			private void inc(OsmPrimitive osm, int i) {
-				normal[i]++;
-				if (osm.isDeleted())
-					deleted[i]++;
-			}
-			public void visit(Node n) {
-				inc(n, 0);
-			}
-			public void visit(LineSegment ls) {
-				inc(ls, 1);
-			}
-			public void visit(Way w) {
-				inc(w, 2);
-			}
-		};
+	@Override public Object getInfoComponent() {
+		DataCountVisitor counter = new DataCountVisitor();
 		for (OsmPrimitive osm : data.allPrimitives())
 			osm.visit(counter);
-
 		JPanel p = new JPanel(new GridBagLayout());
 		p.add(new JLabel(name+" consists of:"), GBC.eol());
-		for (int i = 0; i < normal.length; ++i) {
-			String s = normal[i]+" "+names[i]+(normal[i] != 1 ?"s":"");
-			if (deleted[i] > 0)
-				s += " ("+deleted[i]+" deleted)";
-			p.add(new JLabel(s, ImageProvider.get("data", names[i]), JLabel.HORIZONTAL), GBC.eol().insets(15,0,0,0));
+		for (int i = 0; i < counter.normal.length; ++i) {
+			String s = counter.normal[i]+" "+counter.names[i]+(counter.normal[i] != 1 ?"s":"");
+			if (counter.deleted[i] > 0)
+				s += " ("+counter.deleted[i]+" deleted)";
+			p.add(new JLabel(s, ImageProvider.get("data", counter.names[i]), JLabel.HORIZONTAL), GBC.eol().insets(15,0,0,0));
 		}
 		return p;
 	}
+
+	@Override public void addMenuEntries(JPopupMenu menu) {
+		menu.add(new JMenuItem(new SaveAction()));
+		menu.add(new JMenuItem(new GpxExportAction(this)));
+		menu.addSeparator();
+		menu.add(new LayerListPopup.InfoAction(this));
+	}
 }
Index: /src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java	(revision 86)
@@ -4,9 +4,16 @@
 import java.awt.Graphics;
 import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.util.Collection;
 
 import javax.swing.Icon;
+import javax.swing.JColorChooser;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.GpxExportAction;
 import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -14,4 +21,5 @@
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -57,6 +65,5 @@
 	 * Return a static icon.
 	 */
-	@Override
-	public Icon getIcon() {
+	@Override public Icon getIcon() {
 		if (icon == null)
 			icon = ImageProvider.get("layer", "rawgps");
@@ -64,6 +71,5 @@
 	}
 
-	@Override
-	public void paint(Graphics g, MapView mv) {
+	@Override public void paint(Graphics g, MapView mv) {
 		String gpsCol = Main.pref.get("color.gps point");
 		String gpsColSpecial = Main.pref.get("color.layer "+name);
@@ -89,6 +95,5 @@
 	}
 
-	@Override
-	public String getToolTipText() {
+	@Override public String getToolTipText() {
 		int points = 0;
 		for (Collection<GpsPoint> c : data)
@@ -97,17 +102,14 @@
 	}
 
-	@Override
-	public void mergeFrom(Layer from) {
+	@Override public void mergeFrom(Layer from) {
 		RawGpsDataLayer layer = (RawGpsDataLayer)from;
 		data.addAll(layer.data);
 	}
 
-	@Override
-	public boolean isMergable(Layer other) {
+	@Override public boolean isMergable(Layer other) {
 		return other instanceof RawGpsDataLayer;
 	}
 
-	@Override
-	public void visitBoundingBox(BoundingXYVisitor v) {
+	@Override public void visitBoundingBox(BoundingXYVisitor v) {
 		for (Collection<GpsPoint> c : data)
 			for (GpsPoint p : c)
@@ -115,6 +117,5 @@
 	}
 
-	@Override
-	public Object getInfoComponent() {
+	@Override public Object getInfoComponent() {
 		StringBuilder b = new StringBuilder();
 		int points = 0;
@@ -126,3 +127,32 @@
 		return "<html>"+name+" consists of "+data.size()+" tracks ("+points+" points)<br>"+b.toString();
 	}
+
+	@Override public void addMenuEntries(JPopupMenu menu) {
+		menu.add(new JMenuItem(new GpxExportAction(this)));
+		
+		JMenuItem color = new JMenuItem("Customize Color", ImageProvider.get("colorchooser"));
+		color.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				String col = Main.pref.get("color.layer "+name, Main.pref.get("color.gps point", ColorHelper.color2html(Color.gray)));
+				JColorChooser c = new JColorChooser(ColorHelper.html2color(col));
+				Object[] options = new Object[]{"OK", "Cancel", "Default"};
+				int answer = JOptionPane.showOptionDialog(Main.main, c, "Choose a color", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
+				switch (answer) {
+				case 0:
+					Main.pref.put("color.layer "+name, ColorHelper.color2html(c.getColor()));
+					break;
+				case 1:
+					return;
+				case 2:
+					Main.pref.put("color.layer "+name, null);
+					break;
+				}
+				Main.main.repaint();
+			}
+		});
+		menu.add(color);
+		
+		menu.addSeparator();
+		menu.add(new LayerListPopup.InfoAction(this));
+    }
 }
Index: /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java	(revision 85)
+++ /src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java	(revision 86)
@@ -6,4 +6,5 @@
 
 import javax.swing.Icon;
+import javax.swing.JPopupMenu;
 
 import org.openstreetmap.josm.Main;
@@ -13,4 +14,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.TileCache;
@@ -43,25 +45,20 @@
 	}
 
-	@Override
-	public Icon getIcon() {
+	@Override public Icon getIcon() {
 		return icon;
 	}
 
-	@Override
-	public String getToolTipText() {
+	@Override public String getToolTipText() {
 		return "WMS layer: "+url;
 	}
 
-	@Override
-	public boolean isMergable(Layer other) {
+	@Override public boolean isMergable(Layer other) {
 		return false;
 	}
 
-	@Override
-	public void mergeFrom(Layer from) {
+	@Override public void mergeFrom(Layer from) {
 	}
 
-	@Override
-	public void paint(Graphics g, final MapView mv) {
+	@Override public void paint(Graphics g, final MapView mv) {
 //		EastNorth max = mv.getEastNorth(mv.getWidth(),0);
 //		EastNorth min = mv.getEastNorth(0,mv.getHeight());
@@ -90,12 +87,15 @@
 	}
 
-	@Override
-	public void visitBoundingBox(BoundingXYVisitor v) {
+	@Override public void visitBoundingBox(BoundingXYVisitor v) {
 		// doesn't have a bounding box
 	}
 
-	@Override
-	public Object getInfoComponent() {
+	@Override public Object getInfoComponent() {
 		return getToolTipText();
 	}
+
+	@Override public void addMenuEntries(JPopupMenu menu) {
+		menu.addSeparator();
+		menu.add(new LayerListPopup.InfoAction(this));
+    }
 }
Index: /src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/GpxReader.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/GpxReader.java	(revision 86)
@@ -15,5 +15,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -104,5 +104,5 @@
 		}
 
-		// read ways (and line segments)
+		// read ways (and segments)
 		for (Object wayElement : e.getChildren("trk", GPX))
 			parseWay((Element)wayElement, data);
@@ -114,7 +114,7 @@
 		
 		// clean up the data a bit (remove broken stuff)
-		// remove line segments with from==to
-		for (Iterator<LineSegment> it = data.lineSegments.iterator(); it.hasNext();) {
-			LineSegment ls = it.next();
+		// 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();
@@ -123,9 +123,9 @@
 			}
 		}
-		// remove double line segments (remove only subsequent doubles yet)
+		// remove double segments (remove only subsequent doubles yet)
 		for (Iterator<Way> it = data.ways.iterator(); it.hasNext();) {
-			LineSegment ls = null;
-			for (Iterator<LineSegment> its = it.next().segments.iterator(); its.hasNext();) {
-				LineSegment cur = its.next();
+			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();
@@ -150,5 +150,5 @@
 	private void parseWay(Element e, DataSet ds) {
 		Way way = new Way();
-		boolean realLineSegment = false; // is this way just a fake?
+		boolean realSegment = false; // is this way just a fake?
 
 		for (Object o : e.getChildren()) {
@@ -162,8 +162,8 @@
 						start = node;
 					else {
-						LineSegment lineSegment = new LineSegment(start, node);
-						parseKeyValueExtensions(lineSegment, child.getChild("extensions", GPX));
-						lineSegment = (LineSegment)getNewIfSeenBefore(lineSegment);
-						way.segments.add(lineSegment);
+						Segment segment = new Segment(start, node);
+						parseKeyValueExtensions(segment, child.getChild("extensions", GPX));
+						segment = (Segment)getNewIfSeenBefore(segment);
+						way.segments.add(segment);
 						start = node;
 					}
@@ -172,5 +172,5 @@
 				parseKeyValueExtensions(way, child);
 				if (child.getChild("segment", JOSM) != null)
-					realLineSegment = true;
+					realSegment = true;
 			} else if (child.getName().equals("link"))
 				parseKeyValueLink(way, child);
@@ -179,6 +179,6 @@
 		}
 		way = (Way)getNewIfSeenBefore(way);
-		ds.lineSegments.addAll(way.segments);
-		if (!realLineSegment)
+		ds.segments.addAll(way.segments);
+		if (!realSegment)
 			ds.ways.add(way);
 	}
@@ -240,6 +240,5 @@
 				newCreatedPrimitives.put(osm.id, osm);
 			osm.modified = e.getChild("modified", JOSM) != null;
-			osm.setDeleted(e.getChild("deleted", JOSM) != null);
-			osm.modifiedProperties = e.getChild("modifiedProperties", JOSM) != null;
+			osm.delete(e.getChild("deleted", JOSM) != null);
 		}
 	}
Index: /src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/GpxWriter.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/GpxWriter.java	(revision 86)
@@ -19,5 +19,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -108,10 +108,10 @@
 		// for getting all unreferenced waypoints in the wpt-list
 		LinkedList<Node> unrefNodes = new LinkedList<Node>(ds.nodes);
-		// for getting all unreferenced line segments
-		LinkedList<LineSegment> unrefLs = new LinkedList<LineSegment>(ds.lineSegments);
+		// for getting all unreferenced segments
+		LinkedList<Segment> unrefLs = new LinkedList<Segment>(ds.segments);
 
 		// ways
 		for (Way t : ds.ways) {
-			if (t.isDeleted() && t.id == 0)
+			if (t.deleted && t.id == 0)
 				continue;
 			Element tElem = new Element("trk", GPX);
@@ -129,7 +129,7 @@
 			addPropertyExtensions(tElem, keys, t);
 
-			// line segments
-			for (LineSegment ls : t.segments) {
-				tElem.getChildren().add(parseLineSegment(ls));
+			// segments
+			for (Segment ls : t.segments) {
+				tElem.getChildren().add(parseSegment(ls));
 				unrefNodes.remove(ls.from);
 				unrefNodes.remove(ls.to);
@@ -140,10 +140,10 @@
 		}
 		
-		// encode pending line segments as ways
-		for (LineSegment ls : unrefLs) {
-			if (ls.isDeleted() && ls.id == 0)
+		// 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(parseLineSegment(ls));
+			t.getChildren().add(parseSegment(ls));
 			unrefNodes.remove(ls.from);
 			unrefNodes.remove(ls.to);
@@ -156,5 +156,5 @@
 		// waypoints (missing nodes)
 		for (Node n : unrefNodes) {
-			if (n.isDeleted() && n.id == 0)
+			if (n.deleted && n.id == 0)
 				continue;
 			e.getChildren().add(parseWaypoint(n, "wpt"));
@@ -179,8 +179,8 @@
 
 	/**
-	 * Parse a line segment and store it into a JDOM-Element. Return that element.
+	 * Parse a segment and store it into a JDOM-Element. Return that element.
 	 */
 	@SuppressWarnings("unchecked")
-	private Element parseLineSegment(LineSegment ls) {
+	private Element parseSegment(Segment ls) {
 		Element lsElem = new Element("trkseg", GPX);
 		addPropertyExtensions(lsElem, ls.keys, ls);
@@ -306,10 +306,6 @@
 			extensions.add(modElement);
 		}
-		if (osm.isDeleted()) {
+		if (osm.deleted) {
 			Element modElement = new Element("deleted", JOSM);
-			extensions.add(modElement);
-		}
-		if (osm.modifiedProperties) {
-			Element modElement = new Element("modifiedProperties", JOSM);
 			extensions.add(modElement);
 		}
@@ -355,8 +351,8 @@
 
 	/**
-	 * Export the dataset to gpx. Only the physical line segment structure is
+	 * Export the dataset to gpx. Only the physical segment structure is
 	 * exported. To do this, the list of ways is processed. If a way span a 
-	 * sequence of line segments, this is added as one trkseg.
-	 * Then, all remaining line segments are added in one extra trk. Finally,
+	 * sequence of segments, this is added as one trkseg.
+	 * Then, all remaining segments are added in one extra trk. Finally,
 	 * all remaining nodes are added as wpt.
 	 */
@@ -371,5 +367,5 @@
 		Bounds b = new Bounds(new LatLon(Double.MAX_VALUE, Double.MAX_VALUE), new LatLon(Double.MIN_VALUE, Double.MIN_VALUE));
 		for (Node n : data.nodes)
-			if (!n.isDeleted())
+			if (!n.deleted)
 				b.extend(n.coor);
 		out.println("    <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
@@ -378,9 +374,9 @@
 		// add ways
 		for (Way w : data.ways) {
-			if (w.isDeleted())
+			if (w.deleted)
 				continue;
 			out.println("  <trk>");
-			LineSegment oldLs = null;
-			for (LineSegment ls : w.segments) {
+			Segment oldLs = null;
+			for (Segment ls : w.segments) {
 				// end old segemnt, if no longer match a chain
 				if (oldLs != null && !oldLs.to.coor.equals(ls.from.coor)) {
@@ -408,12 +404,12 @@
 		}
 		
-		// add remaining line segments
-		Collection<LineSegment> lineSegments = new LinkedList<LineSegment>();
+		// add remaining segments
+		Collection<Segment> segments = new LinkedList<Segment>();
 		for (OsmPrimitive osm : all)
-			if (osm instanceof LineSegment)
-				lineSegments.add((LineSegment)osm);
-		if (!lineSegments.isEmpty()) {
+			if (osm instanceof Segment)
+				segments.add((Segment)osm);
+		if (!segments.isEmpty()) {
 			out.println("  <trk>");
-			for (LineSegment ls : lineSegments) {
+			for (Segment ls : segments) {
 				out.println("    <trkseg>");
 				outputNode(ls.from, false);
Index: /src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmConnection.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/OsmConnection.java	(revision 86)
@@ -37,6 +37,5 @@
 		boolean cancelled = false;
 
-		@Override
-		protected PasswordAuthentication getPasswordAuthentication() {
+		@Override protected PasswordAuthentication getPasswordAuthentication() {
 			String username = Main.pref.get("osm-server.username");
 			String password = Main.pref.get("osm-server.password");
Index: /src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmReader.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/OsmReader.java	(revision 86)
@@ -11,5 +11,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -50,5 +50,5 @@
 	 * All read segents so far.
 	 */
-	private Map<Long, LineSegment> lineSegments = new HashMap<Long, LineSegment>();
+	private Map<Long, Segment> segments = new HashMap<Long, Segment>();
 	
 	/**
@@ -70,6 +70,5 @@
 	}
 
-	@Override
-	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+	@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
 		try {
 			if (qName.equals("osm")) {
@@ -89,7 +88,7 @@
 				if (from == null || to == null)
 					throw new SAXException("Segment "+atts.getValue("id")+" is missing its nodes.");
-				current = new LineSegment(from, to);
+				current = new Segment(from, to);
 				readCommon(atts);
-				lineSegments.put(current.id, (LineSegment)current);
+				segments.put(current.id, (Segment)current);
 			} else if (qName.equals("way")) {
 				current = new Way();
@@ -99,9 +98,9 @@
 					long id = getLong(atts, "id");
 					if (id == 0)
-						throw new SAXException("Incomplete line segment with id=0");
-					LineSegment ls = lineSegments.get(id);
+						throw new SAXException("Incomplete segment with id=0");
+					Segment ls = segments.get(id);
 					if (ls == null) {
-						ls = new LineSegment(id); // incomplete line segment
-						lineSegments.put(id, ls);
+						ls = new Segment(id); // incomplete segment
+						segments.put(id, ls);
 						adder.visit(ls);
 					}
@@ -119,6 +118,5 @@
 
 	
-	@Override
-	public void endElement(String namespaceURI, String localName, String qName) {
+	@Override public void endElement(String namespaceURI, String localName, String qName) {
 		if (qName.equals("node") || qName.equals("segment") || qName.equals("way") || qName.equals("area")) {
 			current.visit(adder);
@@ -138,5 +136,5 @@
 			try {
 				DateFormat df = new SimpleDateFormat("y-M-d H:m:s");
-	            current.lastModified = df.parse(time);
+	            current.timestamp = df.parse(time);
             } catch (ParseException e) {
 	            e.printStackTrace();
@@ -146,13 +144,10 @@
 		
 		String action = atts.getValue("action");
-		if ("delete".equals(action))
-			current.setDeleted(true);
-		else if ("modify".equals(action)) {
+		if (action == null)
+			return;
+		if (action.equals("delete"))
+			current.delete(true);
+		else if (action.startsWith("modify"))
 			current.modified = true;
-			current.modifiedProperties = true;
-		} else if ("modify/object".equals(action))
-			current.modified = true;
-		else if ("modify/property".equals(action))
-			current.modifiedProperties = true;
 	}
 
Index: /src/org/openstreetmap/josm/io/OsmReaderOld.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmReaderOld.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/OsmReaderOld.java	(revision 86)
@@ -11,5 +11,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -80,5 +80,5 @@
 			return parseNode(e);
 		else if (e.getName().equals("segment"))
-			return parseLineSegment(e, data);
+			return parseSegment(e, data);
 		else if (e.getName().equals("way"))
 			return parseWay(e, data);
@@ -115,12 +115,12 @@
 
 	/**
-	 * Parse and return an line segment. The node information of the "from" and
+	 * Parse and return an segment. The node information of the "from" and
 	 * "to" attributes must already be in the dataset.
-	 * @param e		The line segment element to parse.
+	 * @param e		The segment element to parse.
 	 * @param data	The dataset to obtain the node information from.
-	 * @return The parsed line segment.
+	 * @return The parsed segment.
 	 * @throws JDOMException In case of parsing errors.
 	 */
-	private LineSegment parseLineSegment(Element e, DataSet data) throws JDOMException {
+	private Segment parseSegment(Element e, DataSet data) throws JDOMException {
 		long startId = Long.parseLong(e.getAttributeValue("from"));
 		long endId = Long.parseLong(e.getAttributeValue("to"));
@@ -135,5 +135,5 @@
 		if (start == null || end == null)
 			throw new JDOMException("The 'from' or 'to' object has not been transfered before.");
-		LineSegment ls = new LineSegment(start, end);
+		Segment ls = new Segment(start, end);
 		parseCommon(ls, e);
 		return ls;
@@ -154,5 +154,5 @@
 			Element child = (Element)o;
 			long id = Long.parseLong(child.getAttributeValue("uid"));
-			LineSegment ls = findLineSegment(data.lineSegments, id);
+			Segment ls = findSegment(data.segments, id);
 			way.segments.add(ls);
 		}
@@ -189,11 +189,9 @@
 		
 		String action = e.getAttributeValue("action");
-		if ("delete".equals(action))
-			data.setDeleted(true);
-		else if ("modify".equals(action))
-			data.modified = data.modifiedProperties = true;
-		else if ("modify/property".equals(action))
-			data.modifiedProperties = true;
-		else if ("modify/object".equals(action))
+		if (action == null)
+			return;
+		if (action.equals("delete"))
+			data.delete(true);
+		else if (action.startsWith("modify"))
 			data.modified = true;
 	}
@@ -218,5 +216,5 @@
 			if (osm.id == id)
 				return osm;
-		for (OsmPrimitive osm : data.lineSegments)
+		for (OsmPrimitive osm : data.segments)
 			if (osm.id == id)
 				return osm;
@@ -230,9 +228,9 @@
 	 * Search for a segment in a collection by comparing the id.
 	 */
-	private LineSegment findLineSegment(Collection<LineSegment> segments, long id) throws JDOMException {
-		for (LineSegment ls : segments)
+	private Segment findSegment(Collection<Segment> segments, long id) throws JDOMException {
+		for (Segment ls : segments)
 			if (ls.id == id)
 				return ls;
-		throw new JDOMException("Unknown line segment reference: "+id);
+		throw new JDOMException("Unknown segment reference: "+id);
 	}
 }
Index: /src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 86)
@@ -16,5 +16,5 @@
 import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -65,8 +65,8 @@
 	 */
 	public void visit(Node n) {
-		if (n.id == 0 && !n.isDeleted() && n.get("created_by") == null) {
+		if (n.id == 0 && !n.deleted && n.get("created_by") == null) {
 			n.put("created_by", "JOSM");
 			sendRequest("PUT", "node", n, true);
-		} else if (n.isDeleted()) {
+		} else if (n.deleted) {
 			sendRequest("DELETE", "node", n, false);
 		} else {
@@ -77,11 +77,11 @@
 
 	/**
-	 * Upload a line segment (without the nodes).
+	 * Upload a segment (without the nodes).
 	 */
-	public void visit(LineSegment ls) {
-		if (ls.id == 0 && !ls.isDeleted() && ls.get("created_by") == null) {
+	public void visit(Segment ls) {
+		if (ls.id == 0 && !ls.deleted && ls.get("created_by") == null) {
 			ls.put("created_by", "JOSM");
 			sendRequest("PUT", "segment", ls, true);
-		} else if (ls.isDeleted()) {
+		} else if (ls.deleted) {
 			sendRequest("DELETE", "segment", ls, false);
 		} else {
@@ -92,11 +92,11 @@
 
 	/**
-	 * Upload a whole way with the complete line segment id list.
+	 * Upload a whole way with the complete segment id list.
 	 */
 	public void visit(Way w) {
-		if (w.id == 0 && !w.isDeleted() && w.get("created_by") == null) {
+		if (w.id == 0 && !w.deleted && w.get("created_by") == null) {
 			w.put("created_by", "JOSM");
 			sendRequest("PUT", "way", w, true);
-		} else if (w.isDeleted()) {
+		} else if (w.deleted) {
 			sendRequest("DELETE", "way", w, false);
 		} else {
Index: /src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- /src/org/openstreetmap/josm/io/OsmWriter.java	(revision 85)
+++ /src/org/openstreetmap/josm/io/OsmWriter.java	(revision 86)
@@ -8,5 +8,5 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -51,5 +51,5 @@
 		for (Node n : ds.nodes)
 			writer.visit(n);
-		for (LineSegment ls : ds.lineSegments)
+		for (Segment ls : ds.segments)
 			writer.visit(ls);
 		for (Way w : ds.ways)
@@ -80,7 +80,7 @@
 	}
 
-	public void visit(LineSegment ls) {
+	public void visit(Segment ls) {
 		if (ls.incomplete)
-			return; // Do not write an incomplete line segment
+			return; // Do not write an incomplete segment
 		addCommon(ls, "segment");
 		out.print(" from='"+getUsedId(ls.from)+"' to='"+getUsedId(ls.to)+"'");
@@ -91,5 +91,5 @@
 		addCommon(w, "way");
 		out.println(">");
-		for (LineSegment ls : w.segments)
+		for (Segment ls : w.segments)
 			out.println("    <seg id='"+getUsedId(ls)+"' />");
 		addTags(w, "way", false);
@@ -130,17 +130,13 @@
 		if (!osmConform) {
 			String action = null;
-			if (osm.isDeleted())
+			if (osm.deleted)
 				action = "delete";
-			else if (osm.modified && osm.modifiedProperties)
+			else if (osm.modified)
 				action = "modify";
-			else if (osm.modified && !osm.modifiedProperties)
-				action = "modify/object";
-			else if (!osm.modified && osm.modifiedProperties)
-				action = "modify/property";
 			if (action != null)
 				out.print(" action='"+action+"'");
 		}
-		if (osm.lastModified != null) {
-			String time = new SimpleDateFormat("y-M-d H:m:s").format(osm.lastModified);
+		if (osm.timestamp != null) {
+			String time = new SimpleDateFormat("y-M-d H:m:s").format(osm.timestamp);
 			out.print(" timestamp='"+time+"'");
 		}
Index: /src/org/openstreetmap/josm/test/GpxWriterTest.java
===================================================================
--- /src/org/openstreetmap/josm/test/GpxWriterTest.java	(revision 86)
+++ /src/org/openstreetmap/josm/test/GpxWriterTest.java	(revision 86)
@@ -0,0 +1,84 @@
+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: /src/org/openstreetmap/josm/test/MergeVisitorTest.java
===================================================================
--- /src/org/openstreetmap/josm/test/MergeVisitorTest.java	(revision 86)
+++ /src/org/openstreetmap/josm/test/MergeVisitorTest.java	(revision 86)
@@ -0,0 +1,180 @@
+package org.openstreetmap.josm.test;
+
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+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.visitor.MergeVisitor;
+import org.openstreetmap.josm.test.framework.Bug;
+import org.openstreetmap.josm.test.framework.DataSetTestCaseHelper;
+
+public class MergeVisitorTest extends TestCase {
+
+	
+	private DataSet ds;
+	private Node dsNode;
+	private Node n;
+	private MergeVisitor v;
+
+	@Override protected void setUp() throws Exception {
+		ds = new DataSet();
+		dsNode = DataSetTestCaseHelper.createNode(ds);
+		v = new MergeVisitor(ds);
+		n = DataSetTestCaseHelper.createNode(null);
+    }
+
+
+	public void testNodesMergeUpdate() {
+		dsNode.id = 1;
+		n.id = 1;
+		n.timestamp = new Date();
+		v.visit(n);
+		assertEquals(dsNode, n);
+	}
+	public void testNodesMergeModified() {
+		dsNode.id = 1;
+		n.id = 1;
+		n.modified = true;
+		v.visit(n);
+		assertEquals(dsNode, n);
+	}
+	public void testNodesConflictBothModified() {
+		n.modified = true;
+		dsNode.modified = true;
+		v.visit(n);
+		assertEquals(1, v.conflicts.size());
+		assertFalse(n.equals(dsNode));
+	}
+	public void testNodesConflict() {
+		dsNode.id = 1;
+		dsNode.timestamp = new Date();
+		n.id = 1;
+		n.modified = true;
+		n.timestamp = new Date(dsNode.timestamp.getTime()-1);
+		v.visit(n);
+		assertEquals(1, v.conflicts.size());
+		assertSame(dsNode, v.conflicts.keySet().iterator().next());
+		assertSame(n, v.conflicts.values().iterator().next());
+	}
+	public void testNodesConflict2() {
+		dsNode.id = 1;
+		dsNode.timestamp = new Date();
+		dsNode.modified = true;
+		n.id = 1;
+		n.timestamp = new Date(dsNode.timestamp.getTime()+1);
+		v.visit(n);
+		assertEquals(1, v.conflicts.size());
+	}
+	public void testNodesConflictModifyDelete() {
+		dsNode.id = 1;
+		dsNode.modified = true;
+		n.id = 1;
+		n.delete(true);
+		v.visit(n);
+		assertEquals(1, v.conflicts.size());
+	}
+	public void testNodesMergeSamePosition() {
+		n.id = 1; // new node comes from server
+		dsNode.modified = true; // our node is modified
+		dsNode.coor = new LatLon(n.coor.lat(), n.coor.lon());
+		v.visit(n);
+		v.fixReferences();
+		assertEquals(0, v.conflicts.size());
+		assertEquals(1, dsNode.id);
+		assertFalse("updating a new node clear the modified state", dsNode.modified);
+	}
+
+	public void testFixReferencesConflicts() {
+		// make two nodes mergable
+		dsNode.id = 1;
+		n.id = 1;
+		n.timestamp = new Date();
+		// have an old segment with the old node
+		Segment sold = new Segment(dsNode, dsNode);
+		sold.id = 23;
+		sold.modified = true;
+		ds.segments.add(sold);
+		// have a conflicting segment point to the new node
+		Segment s = new Segment(n,n);
+		s.id = 23;
+		s.modified = true;
+
+		v.visit(n); // merge
+		assertEquals(n.timestamp, dsNode.timestamp);
+		v.visit(s);
+		v.fixReferences();
+		assertSame(s.from, dsNode);
+		assertSame(s.to, dsNode);
+	}
+	
+	public void testNoConflictForSame() {
+		dsNode.id = 1;
+		dsNode.modified = true;
+		n.cloneFrom(dsNode);
+		v.visit(n);
+		assertEquals(0, v.conflicts.size());
+	}
+
+	/**
+	 * Merge of an old segment with a new one. This should
+	 * be mergable (if the nodes matches).
+	 */
+	public void testMergeOldSegmentsWithNew() {
+		Node[] n = createNodes(ds, 2);
+		Segment ls1 = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
+		ls1.id = 3;
+
+		Node newnode = new Node(new LatLon(n[1].coor.lat(), n[1].coor.lon()));
+		Segment newls = new Segment(n[0], newnode);
+
+		v.visit(newls);
+		assertEquals("segment should have been merged.", 1, ds.segments.size());
+	}
+	
+	/**
+	 * Nodes beeing merged are equal but should be the same.
+	 */
+	@Bug(54)
+	public void testEqualNotSame() {
+		ds = new DataSet();
+		// create a dataset with segment a-b
+		Node n[] = createNodes(ds, 2);
+		Segment ls1 = DataSetTestCaseHelper.createSegment(ds, n[0], n[1]);
+		ls1.id = 1;
+
+		// create an other dataset with segment a'-c (a' is equal, but not same to a)
+		DataSet ds2 = new DataSet();
+		Node n2[] = createNodes(ds2, 2);
+		n2[0].coor = new LatLon(n[0].coor.lat(), n[0].coor.lon());
+		n2[0].id = 0;
+		n2[1].id = 42;
+
+		Segment ls2 = DataSetTestCaseHelper.createSegment(ds, n2[0], n2[1]);
+		v = new MergeVisitor(ds);
+		for (OsmPrimitive osm : ds2.allPrimitives())
+			osm.visit(v);
+		v.fixReferences();
+
+		assertSame(ls1.from, ls2.from);
+	}
+	
+	
+	/**
+	 * Create that amount of nodes and add them to the dataset. The id will be 1,2,3,4...
+	 * @param amount Number of nodes to create.
+	 * @return The created nodes.
+	 */
+	private Node[] createNodes(DataSet ds, int amount) {
+		Node[] nodes = new Node[amount];
+		for (int i = 0; i < amount; ++i) {
+			nodes[i] = DataSetTestCaseHelper.createNode(ds);
+			nodes[i].id = i+1;
+		}
+		return nodes;
+	}
+}
Index: /src/org/openstreetmap/josm/test/OsmWriterTest.java
===================================================================
--- /src/org/openstreetmap/josm/test/OsmWriterTest.java	(revision 86)
+++ /src/org/openstreetmap/josm/test/OsmWriterTest.java	(revision 86)
@@ -0,0 +1,214 @@
+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/test/framework/Bug.java
===================================================================
--- /src/org/openstreetmap/josm/test/framework/Bug.java	(revision 86)
+++ /src/org/openstreetmap/josm/test/framework/Bug.java	(revision 86)
@@ -0,0 +1,13 @@
+package org.openstreetmap.josm.test.framework;
+
+/**
+ * Annotation that indicate that a specific test case function was a bug.
+ * @author Imi
+ */
+public @interface Bug {
+	/**
+	 * The revision this bug was detected. (Can be later than the actual first occourence.
+	 * This number is just to have a revision where the bug actually happen.)
+	 */
+	int value();
+}
Index: /src/org/openstreetmap/josm/test/framework/DataSetTestCaseHelper.java
===================================================================
--- /src/org/openstreetmap/josm/test/framework/DataSetTestCaseHelper.java	(revision 86)
+++ /src/org/openstreetmap/josm/test/framework/DataSetTestCaseHelper.java	(revision 86)
@@ -0,0 +1,71 @@
+package org.openstreetmap.josm.test.framework;
+
+import java.util.Arrays;
+
+import org.openstreetmap.josm.Main;
+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.Way;
+import org.openstreetmap.josm.data.projection.Mercator;
+
+
+/**
+ * Test cases that need to manupulate a data set can use this helper.
+ *  
+ * @author Imi
+ */
+public class DataSetTestCaseHelper {
+
+	/**
+	 * Create a common dataset consisting of:
+	 * - 5 random nodes
+	 * - ls between node 0 and 1
+	 * - ls between node 1 and 2
+	 * - ls between node 3 and 4
+	 * - a way with ls 0 and 1
+	 */
+	public static DataSet createCommon() {
+		DataSet ds = new DataSet();
+		Node n1 = createNode(ds);
+		Node n2 = createNode(ds);
+		Node n3 = createNode(ds);
+		Node n4 = createNode(ds);
+		Node n5 = createNode(ds);
+		Segment ls1 = createSegment(ds, n1, n2);
+		Segment ls2 = createSegment(ds, n2, n3);
+		createSegment(ds, n4, n5);
+		createWay(ds, ls1, ls2);
+		return ds;
+	}
+
+	public static Way createWay(DataSet ds, Segment... segments) {
+		Way t = new Way();
+		t.segments.addAll(Arrays.asList(segments));
+		ds.ways.add(t);
+		return t;
+	}
+	
+	/**
+	 * Create a segment with out of the given nodes.
+	 */
+	public static Segment createSegment(DataSet ds, Node n1, Node n2) {
+		Segment ls = new Segment(n1, n2);
+		ds.segments.add(ls);
+		return ls;
+	}
+
+	/**
+	 * Add a random node.
+	 */
+	public static Node createNode(DataSet ds) {
+		if (Main.proj == null)
+			Main.proj = new Mercator();
+		Node node = new Node(new LatLon(Math.random(), Math.random()));
+		if (ds != null)
+			ds.nodes.add(node);
+		return node;
+	}
+
+}
Index: /src/org/openstreetmap/josm/tools/SearchCompiler.java
===================================================================
--- /src/org/openstreetmap/josm/tools/SearchCompiler.java	(revision 85)
+++ /src/org/openstreetmap/josm/tools/SearchCompiler.java	(revision 86)
@@ -6,5 +6,5 @@
 import java.util.Map.Entry;
 
-import org.openstreetmap.josm.data.osm.LineSegment;
+import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -99,5 +99,5 @@
 			if (osm instanceof Node)
 				return type.equals("node");
-			if (osm instanceof LineSegment)
+			if (osm instanceof Segment)
 				return type.equals("segment");
 			if (osm instanceof Way)
