Index: /data/empty.xml
===================================================================
--- /data/empty.xml	(revision 145)
+++ /data/empty.xml	(revision 146)
@@ -1,18 +1,18 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <osm version='0.3' generator='JOSM'>
+  <node id='-1' lat='19.054463960754692' lon='-66.94382022471912' />
+  <node id='2' lat='43.00883564541926' lon='-6.269662921348315' />
+  <node id='-2' lat='-34.84314824807727' lon='-13.146067415730338' />
   <node id='1' lat='67.99839775928415' lon='-59.66292134831462' />
-  <node id='2' lat='43.00883564541926' lon='-6.269662921348315' />
-  <node id='-3' lat='19.054463960754692' lon='-66.94382022471912' />
-  <node id='-4' lat='-24.68228648077048' lon='-40.651685393258425' />
-  <node id='-5' lat='-34.84314824807727' lon='-13.146067415730338' />
-  <segment id='-6' from='1' to='2' />
-  <segment id='-7' from='2' to='-3' />
-  <segment id='-8' from='-5' to='-4' />
-  <way id='-9'>
+  <node id='-3' lat='-24.68228648077048' lon='-40.651685393258425' />
+  <segment id='-4' from='1' to='2' />
+  <segment id='-5' from='-2' to='-3' />
+  <segment id='-6' from='2' to='-1' />
+  <way id='-7'>
+    <seg id='-4' />
     <seg id='-6' />
-    <seg id='-7' />
   </way>
-  <way id='-10'>
-    <seg id='-8' />
+  <way id='-8'>
+    <seg id='-5' />
   </way>
 </osm>
Index: /src/org/openstreetmap/josm/Main.java
===================================================================
--- /src/org/openstreetmap/josm/Main.java	(revision 145)
+++ /src/org/openstreetmap/josm/Main.java	(revision 146)
@@ -31,4 +31,5 @@
 
 import org.openstreetmap.josm.actions.AboutAction;
+import org.openstreetmap.josm.actions.AlignInCircleAction;
 import org.openstreetmap.josm.actions.DownloadAction;
 import org.openstreetmap.josm.actions.ExitAction;
@@ -174,4 +175,5 @@
 		annotationTesterAction.putValue(Action.SMALL_ICON, ImageProvider.get("annotation-tester"));
 		final Action reverseSegmentAction = new ReverseSegmentAction();
+		final Action alignInCircleAction = new AlignInCircleAction();
 		final Action uploadAction = new UploadAction();
 		final Action saveAction = new SaveAction();
@@ -211,4 +213,5 @@
 		editMenu.addSeparator();
 		editMenu.add(reverseSegmentAction);
+		editMenu.add(alignInCircleAction);
 		editMenu.addSeparator();
 		editMenu.add(preferencesAction);
@@ -239,6 +242,4 @@
 		toolBar.add(undoAction);
 		toolBar.add(redoAction);
-		toolBar.addSeparator();
-		toolBar.add(reverseSegmentAction);
 		toolBar.addSeparator();
 		toolBar.add(preferencesAction);
Index: /src/org/openstreetmap/josm/actions/AlignInCircleAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(revision 146)
+++ /src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(revision 146)
@@ -0,0 +1,73 @@
+package org.openstreetmap.josm.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.MoveCommand;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+/**
+ * Aligns all selected nodes within a circle. (Usefull for roundabouts)
+ * 
+ * @author Matthew Newton
+ */
+public final class AlignInCircleAction extends JosmAction {
+
+	public AlignInCircleAction() {
+		super(tr("Align Nodes in Circle"), "aligncircle", tr("Move the selected nodes into a circle."), KeyEvent.VK_O, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK);
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
+		Collection<Node> nodes = new LinkedList<Node>();
+		for (OsmPrimitive osm : sel)
+			if (osm instanceof Node)
+				nodes.add((Node)osm);
+		if (nodes.size() < 4) {
+			JOptionPane.showMessageDialog(Main.parent, tr("Please select at least four nodes."));
+			return;
+		}
+
+		// Get average position of all nodes
+		Node avn = new Node(new LatLon(0,0));
+		for (Node n : nodes) {
+			avn.eastNorth = new EastNorth(avn.eastNorth.east()+n.eastNorth.east(), avn.eastNorth.north()+n.eastNorth.north());
+			avn.coor = Main.proj.eastNorth2latlon(avn.eastNorth);
+		}
+		avn.eastNorth = new EastNorth(avn.eastNorth.east()/nodes.size(), avn.eastNorth.north()/nodes.size());
+		avn.coor = Main.proj.eastNorth2latlon(avn.eastNorth);
+		// Node "avn" now is central to all selected nodes.
+
+		// Now calculate the average distance to each node from the
+		// centre.
+		double avdist = 0;
+		for (Node n : nodes)
+			avdist += Math.sqrt(avn.eastNorth.distance(n.eastNorth));
+		avdist = avdist / nodes.size();
+
+		Collection<Command> cmds = new LinkedList<Command>();
+		// Move each node to that distance from the centre.
+		for (Node n : nodes) {
+			double dx = n.eastNorth.east() - avn.eastNorth.east();
+			double dy = n.eastNorth.north() - avn.eastNorth.north();
+			double dist = Math.sqrt(avn.eastNorth.distance(n.eastNorth));
+			cmds.add(new MoveCommand(n, (dx * (avdist / dist)) - dx, (dy * (avdist / dist)) - dy));
+		}
+
+		Main.main.editLayer().add(new SequenceCommand(tr("Align Nodes in Circle"), cmds));
+		Main.ds.setSelected(avn);
+		Main.map.repaint();
+	}
+}
Index: /src/org/openstreetmap/josm/actions/ExternalToolsAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 145)
+++ /src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 146)
@@ -76,5 +76,28 @@
 				final boolean addGpx = flags.contains("gpx");
 
-				AddVisitor adder = new AddVisitor(fromDataSet, flags.contains("include_references"));
+				AddVisitor adder = new AddVisitor(fromDataSet);
+				if (flags.contains("include_references")) {
+					adder = new AddVisitor(fromDataSet){
+						@Override public void visit(Node n) {
+							if (!ds.nodes.contains(n))
+								super.visit(n);
+                        }
+						@Override public void visit(Segment s) {
+	                        super.visit(s);
+	                		if (!s.incomplete) {
+	                			if (!ds.nodes.contains(s.from))
+	                				s.from.visit(this);
+	                			if (!ds.nodes.contains(s.to))
+	                				s.to.visit(this);
+	                		}
+                        }
+						@Override public void visit(Way w) {
+	                        super.visit(w);
+	            			for (Segment s : w.segments)
+	            				if (!ds.segments.contains(s))
+	            					s.visit(this);
+                        }
+					};
+				}
 				if (input.contains("selection")) {
 					Collection<OsmPrimitive> sel = Main.ds.getSelected();
Index: /src/org/openstreetmap/josm/command/Command.java
===================================================================
--- /src/org/openstreetmap/josm/command/Command.java	(revision 145)
+++ /src/org/openstreetmap/josm/command/Command.java	(revision 146)
@@ -2,11 +2,16 @@
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.visitor.CloneVisitor;
+import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
 
@@ -23,4 +28,18 @@
 abstract public class Command {
 
+	private static final 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));
+	    }
+	}
+	
 	private CloneVisitor orig; 
 	
Index: /src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- /src/org/openstreetmap/josm/command/MoveCommand.java	(revision 145)
+++ /src/org/openstreetmap/josm/command/MoveCommand.java	(revision 146)
@@ -4,4 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.trn;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
@@ -56,4 +57,8 @@
 	private List<OldState> oldState = new LinkedList<OldState>();
 
+	
+	public MoveCommand(OsmPrimitive osm, double x, double y) {
+		this(Arrays.asList(new OsmPrimitive[]{osm}), x, y);
+	}
 	/**
 	 * Create a MoveCommand and assign the initial object set and movement vector.
Index: /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 145)
+++ /src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 146)
@@ -17,35 +17,18 @@
 public class AddVisitor implements Visitor {
 	
-	private final DataSet ds;
-	private final boolean includeReferences;
-	
-	public AddVisitor(DataSet ds, boolean includeReferences) {
-		this.ds = ds;
-		this.includeReferences = includeReferences;
-	}
+	protected final DataSet ds;
 	
 	public AddVisitor(DataSet ds) {
-		this(ds, false);
+		this.ds = ds;
 	}
 	
 	public void visit(Node n) {
-		if (!includeReferences || !ds.nodes.contains(n))
-			ds.nodes.add(n);
+		ds.nodes.add(n);
 	}
 	public void visit(Segment s) {
 		ds.segments.add(s);
-		if (includeReferences && !s.incomplete) {
-			if (!ds.nodes.contains(s.from))
-				s.from.visit(this);
-			if (!ds.nodes.contains(s.to))
-				s.to.visit(this);
-		}
 	}
 	public void visit(Way w) {
 		ds.ways.add(w);
-		if (includeReferences)
-			for (Segment s : w.segments)
-				if (!ds.segments.contains(s))
-					s.visit(this);
 	}
 }
Index: /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 145)
+++ /src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 146)
@@ -9,6 +9,6 @@
 
 /**
- * Calculates the total bounding rectangle of a serie of OsmPrimitives, using the EastNorth values
- * as reference.
+ * Calculates the total bounding rectangle of a serie of OsmPrimitives, using the 
+ * EastNorth values as reference.
  * @author imi
  */
Index: c/org/openstreetmap/josm/data/osm/visitor/CloneVisitor.java
===================================================================
--- /src/org/openstreetmap/josm/data/osm/visitor/CloneVisitor.java	(revision 145)
+++ 	(revision )
@@ -1,24 +1,0 @@
-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: /test/org/openstreetmap/josm/data/osm/DataSetTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/DataSetTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/DataSetTest.java	(revision 146)
@@ -0,0 +1,116 @@
+package org.openstreetmap.josm.data.osm;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class DataSetTest extends MotherObject {
+
+	private final class TestSelectionChangeListener implements SelectionChangedListener {
+	    public Collection<? extends OsmPrimitive> called;
+		public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+	    	called = newSelection;
+	    }
+    }
+
+	private DataSet ds;
+	private Node node1;
+	private Node node2;
+	private Node node3;
+	private Segment segment;
+	private Way way;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		ds = createDataSet();
+		Iterator<Node> it = ds.nodes.iterator();
+		node1 = it.next();
+		node2 = it.next();
+		node3 = it.next();
+		segment = ds.segments.iterator().next();
+		way = ds.ways.iterator().next();
+	}
+
+	public void testAllPrimitives() {
+		Collection<OsmPrimitive> all = ds.allPrimitives();
+		assertContainsSame(all, node1, node2, node3, segment, way);
+	}
+
+	public void testAllNonDeletedPrimitives() {
+		assertEquals(5, ds.allNonDeletedPrimitives().size());
+		node1.deleted = true;
+		assertEquals(4, ds.allNonDeletedPrimitives().size());
+	}
+
+	public void testClearSelection() {
+		node1.selected = true;
+		ds.clearSelection();
+		assertFalse(node1.selected);
+	}
+
+	public void testGetSelected() {
+		node1.selected = true;
+		segment.selected = true;
+		Collection<OsmPrimitive> sel = ds.getSelected();
+		assertContainsSame(sel, node1, segment);
+	}
+
+	public void testSetSelected() {
+		Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+		sel.add(node1);
+		sel.add(way);
+		ds.setSelected(sel);
+		assertTrue(node1.selected);
+		assertFalse(node2.selected);
+		assertTrue(way.selected);
+	}
+
+	public void testSetSelectedOsmPrimitive() {
+		ds.setSelected(node3);
+		assertTrue(node3.selected);
+		assertFalse(node2.selected);
+	}
+
+	public void testFireSelectionChanged() {
+		TestSelectionChangeListener l = new TestSelectionChangeListener();
+		ds.addSelectionChangedListener(l);
+		ds.setSelected(segment);
+		assertNotNull(l.called);
+		assertEquals(1, l.called.size());
+		assertSame(segment, l.called.iterator().next());
+	}
+
+	public void testAddRemoveSelectionChangedListener() {
+		TestSelectionChangeListener l = new TestSelectionChangeListener();
+		ds.addSelectionChangedListener(l);
+		ds.removeSelectionChangedListener(l);
+		ds.setSelected(way);
+		assertNull(l.called);
+	}
+
+	public void testAddAllSelectionListener() {
+		DataSet ds2 = new DataSet();
+		TestSelectionChangeListener l1 = new TestSelectionChangeListener();
+		TestSelectionChangeListener l2 = new TestSelectionChangeListener();
+		ds2.addSelectionChangedListener(l1);
+		ds2.addSelectionChangedListener(l2);
+		ds.addAllSelectionListener(ds2);
+		ds2.removeSelectionChangedListener(l1);
+		ds.setSelected(node2);
+		assertNotNull(l1.called);
+		assertNotNull(l2.called);
+	}
+
+	public void testRealEqual() {
+		Collection<OsmPrimitive> all = new LinkedList<OsmPrimitive>();
+		all.add(new Node(node1));
+		all.add(new Node(node2));
+		all.add(new Node(node3));
+		all.add(createSegment(segment.id, node1, node2));
+		all.add(createWay(way.id, way.segments.iterator().next()));
+		assertTrue(ds.realEqual(all));
+	}
+}
Index: /test/org/openstreetmap/josm/data/osm/NodeTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/NodeTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/NodeTest.java	(revision 146)
@@ -0,0 +1,48 @@
+package org.openstreetmap.josm.data.osm;
+
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class NodeTest extends MotherObject {
+
+	private Node node;
+
+	@Override protected void setUp() throws Exception {
+	    super.setUp();
+	    node = createNode();
+    }
+
+	public void testVisit() {
+		OsmPrimitiveTest.TestCalledVisitor v = new OsmPrimitiveTest.TestCalledVisitor();
+		node.visit(v);
+		assertEquals("Node", v.called);
+	}
+
+	public void testCloneFromRealEqual() {
+		Node node2 = createNode(23,3,4);
+		assertFalse(node2.realEqual(node));
+		assertFalse(node.realEqual(node2));
+		node.cloneFrom(node2);
+		assertTrue(node2.realEqual(node));
+		assertTrue(node.realEqual(node2));
+	}
+
+	public void testNodeNode() {
+		Node node2 = new Node(node);
+		assertTrue(node2.realEqual(node));
+	}
+
+	public void testNodeLatLon() {
+		LatLon latLon = new LatLon(1,2);
+		node = new Node(latLon);
+		assertEquals(node.coor, latLon);
+	}
+
+	public void testCompareToNodeTypeBiggestOrComparedAfterId() {
+		assertEquals(1, node.compareTo(createSegment()));
+		assertEquals(1, node.compareTo(createWay()));
+		Node node2 = createNode(23,1,2);
+		assertEquals(-1, node.compareTo(node2));
+		assertEquals(1, node2.compareTo(node));
+	}
+}
Index: /test/org/openstreetmap/josm/data/osm/OsmPrimitiveTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/OsmPrimitiveTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/OsmPrimitiveTest.java	(revision 146)
@@ -0,0 +1,94 @@
+package org.openstreetmap.josm.data.osm;
+
+import java.util.Date;
+
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class OsmPrimitiveTest extends MotherObject {
+
+	public final static class TestCalledVisitor implements Visitor {
+        public String called;
+    	
+    	public void visit(Node n) {
+    		assertNull(called);
+    		called = "Node";
+        }
+    
+        public void visit(Segment s) {
+        	assertNull(called);
+        	called = "Segment";
+        }
+    
+        public void visit(Way w) {
+        	assertNull(called);
+        	called = "Way";
+        }
+    }
+
+	private OsmPrimitive osm;
+	private boolean visited;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		osm = new OsmPrimitive() {
+			@Override public void visit(Visitor visitor) {
+				visited = true;
+			}
+
+			public int compareTo(OsmPrimitive o) {
+				return 0;
+			}
+		};
+		visited = false;
+	}
+
+	public void testHashCodeReturnsIdIfNotZeroAndNotZeroIfIdIsZero() {
+		osm.id = 23;
+		assertEquals(23, osm.hashCode());
+		osm.id = 0;
+		assertTrue(0 != osm.hashCode());
+	}
+
+	public void testVisit() {
+		osm.visit(new Visitor(){
+			public void visit(Node n) {}
+			public void visit(Segment s) {}
+			public void visit(Way w) {}});
+		assertTrue(visited);
+	}
+
+	public void testEqualsIsEqualOnlyIfIdAndClassMatchesAndIdIsNotZero() {
+		Node node = createNode(1,23,42);
+		Node node2 = createNode(1);
+		assertTrue(node.equals(node2));
+		Segment segment = createSegment(1);
+		assertFalse(node.equals(segment));
+		node2.id = 2;
+		assertFalse(node.equals(node2));
+		node2.id = 0;
+		node.id = 0;
+		assertFalse(node.equals(node2));
+	}
+
+	public void testKeysPutRemoveGet() {
+		assertTrue(osm.keySet().isEmpty());
+		osm.put("foo", "bar");
+		assertEquals(1, osm.keySet().size());
+		assertEquals("bar", osm.get("foo"));
+		assertEquals(1, osm.entrySet().size());
+		assertEquals("foo", osm.entrySet().iterator().next().getKey());
+		assertEquals("bar", osm.entrySet().iterator().next().getValue());
+		
+		osm.remove("asd");
+		assertEquals(1, osm.keySet().size());
+		osm.remove("foo");
+		assertEquals(0, osm.keySet().size());
+	}
+
+	public void testGetTimeStr() {
+		assertNull(osm.getTimeStr());
+		osm.timestamp = new Date(1);
+		assertEquals("1970-01-01 01:00:00", osm.getTimeStr());
+	}
+}
Index: /test/org/openstreetmap/josm/data/osm/SegmentTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/SegmentTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/SegmentTest.java	(revision 146)
@@ -0,0 +1,66 @@
+package org.openstreetmap.josm.data.osm;
+
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class SegmentTest extends MotherObject {
+
+	private Segment segment;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		segment = createSegment();
+	}
+
+	public void testVisit() {
+		OsmPrimitiveTest.TestCalledVisitor v = new OsmPrimitiveTest.TestCalledVisitor();
+		segment.visit(v);
+		assertEquals("Segment", v.called);
+	}
+
+	public void testCloneFromRealEqual() {
+		Segment s2 = createSegment(23, createNode(1,2,3), createNode(2,3,4));
+		segment.cloneFrom(s2);
+		assertTrue(segment.realEqual(s2));
+		assertTrue(s2.realEqual(segment));
+		assertSame(segment.from, s2.from);
+		assertSame(segment.to, s2.to);
+	}
+
+	public void testSegmentSegment() {
+		Segment s = new Segment(segment);
+		assertTrue(s.realEqual(segment));
+	}
+
+	public void testSegmentNodeNode() {
+		Segment s = new Segment(createNode(1,2,3), createNode(4,5,6));
+		assertEquals(2.0, s.from.coor.lat());
+		assertEquals(6.0, s.to.coor.lon());
+	}
+
+	public void testSegmentLong() {
+		Segment s = new Segment(23);
+		assertEquals(23, s.id);
+	}
+
+	public void testEqualPlace() {
+		Segment s = createSegment();
+		assertFalse(s.equalPlace(segment));
+		assertFalse(segment.equalPlace(s));
+		s.from.coor = segment.to.coor;
+		s.to.coor = segment.from.coor;
+		assertTrue(s.equalPlace(segment));
+		assertTrue(segment.equalPlace(s));
+	}
+
+	public void testCompareToSegmentSmallerThanNodeBiggerThanWayOrCompareAfterId() {
+		Segment s = createSegment(23);
+		assertEquals(-1, s.compareTo(createNode()));
+		assertEquals(1, s.compareTo(createWay()));
+		
+		assertEquals(1, s.compareTo(segment));
+		assertEquals(-1, segment.compareTo(s));
+		segment.id = s.id;
+		assertEquals(0, segment.compareTo(s));
+		assertEquals(0, s.compareTo(segment));
+	}
+}
Index: /test/org/openstreetmap/josm/data/osm/WayTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/WayTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/WayTest.java	(revision 146)
@@ -0,0 +1,53 @@
+package org.openstreetmap.josm.data.osm;
+
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class WayTest extends MotherObject {
+
+	private Way way;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		way = createWay();
+	}
+
+	public void testVisit() {
+		OsmPrimitiveTest.TestCalledVisitor v = new OsmPrimitiveTest.TestCalledVisitor();
+		way.visit(v);
+		assertEquals("Way", v.called);
+	}
+
+	public void testCloneFromRealEqual() {
+		Way w2 = createWay(42);
+		way.cloneFrom(w2);
+		assertTrue(way.realEqual(w2));
+		assertEquals(w2.segments.size(), way.segments.size());
+	}
+
+	public void testWayWay() {
+		Way w = new Way(way);
+		assertEquals(way.id, w.id);
+		assertTrue(way.realEqual(w));
+	}
+
+	public void testWay() {
+		Way w = new Way();
+		assertEquals(0, w.id);
+		assertEquals(0, w.segments.size());
+	}
+
+	public void testCompareToWaySmallestOrCompareAfterId() {
+		Way w = createWay(23);
+		assertEquals(-1, w.compareTo(createNode()));
+		assertEquals(-1, w.compareTo(createSegment()));
+		
+		assertEquals(1, w.compareTo(way));
+		assertEquals(-1, way.compareTo(w));
+	}
+
+	public void testIsIncomplete() {
+		way.segments.add(new Segment(23));
+		assertTrue(way.isIncomplete());
+	}
+
+}
Index: /test/org/openstreetmap/josm/data/osm/visitor/AddVisitorTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/visitor/AddVisitorTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/visitor/AddVisitorTest.java	(revision 146)
@@ -0,0 +1,42 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import java.lang.reflect.Field;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class AddVisitorTest extends MotherObject {
+
+	private AddVisitor v;
+	private DataSet ds;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		ds = new DataSet();
+		v = new AddVisitor(ds);
+	}
+
+	public void testAddVisitorDataSet() throws Exception {
+		AddVisitor v = new AddVisitor(ds);
+		Field vDs = AddVisitor.class.getDeclaredField("ds");
+		vDs.setAccessible(true);
+		assertSame(ds, vDs.get(v));
+	}
+	
+	public void testVisitNode() {
+		createNode(23).visit(v);
+		assertEquals(1, ds.nodes.size());
+		assertEquals(23, ds.nodes.iterator().next().id);
+	}
+
+	public void testVisitSegment() {
+		createSegment().visit(v);
+		assertEquals(1, ds.segments.size());
+	}
+
+	public void testVisitWay() {
+		createWay().visit(v);
+		assertEquals(1, ds.ways.size());
+	}
+
+}
Index: /test/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitorTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitorTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitorTest.java	(revision 146)
@@ -0,0 +1,58 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+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.testframework.MotherObject;
+
+public class AllNodesVisitorTest extends MotherObject {
+
+	private AllNodesVisitor v;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		v = new AllNodesVisitor();
+	}
+
+	public void testVisitNode() {
+		Node node = createNode();
+		node.visit(v);
+		assertEquals(1, v.nodes.size());
+		assertSame(node, v.nodes.iterator().next());
+	}
+
+	public void testVisitSegment() {
+		Segment s = createSegment();
+		s.visit(v);
+		assertEquals(2, v.nodes.size());
+		Iterator<Node> it = v.nodes.iterator();
+		assertSame(s.from, it.next());
+		assertSame(s.to, it.next());
+	}
+
+	public void testVisitWay() {
+		Way w = createWay(createSegment());
+		w.visit(v);
+		int numberOfNodes = 2*w.segments.size();
+		assertEquals(numberOfNodes, v.nodes.size());
+		Iterator<Node> itNodes = v.nodes.iterator();
+		Iterator<Segment> it = w.segments.iterator();
+		for (int i = 0; i < numberOfNodes; ++i)
+			assertSame(i%2==0?it.next().from:it.next().to, itNodes.next());
+	}
+
+	public void testGetAllNodes() {
+		Collection<OsmPrimitive> all = new LinkedList<OsmPrimitive>();
+		all.add(createNode());
+		all.add(createSegment());
+		Collection<Node> nodes = AllNodesVisitor.getAllNodes(all);
+		
+		assertEquals(3, nodes.size());
+	}
+
+}
Index: /test/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitorTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitorTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitorTest.java	(revision 146)
@@ -0,0 +1,61 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class BoundingXYVisitorTest extends MotherObject {
+
+	private BoundingXYVisitor v;
+
+	private void assertVisitorFilled() {
+        assertNotNull(v.max);
+    	assertNotNull(v.min);
+    }
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		v = new BoundingXYVisitor();
+	}
+
+	public void testVisitNode() {
+		Node node = createNode();
+		node.visit(v);
+		assertVisitorFilled();
+		assertEquals(node.eastNorth.east(), v.min.east());
+		assertEquals(node.eastNorth.north(), v.min.north());
+		assertEquals(v.max, v.min);
+	}
+
+	public void testVisitSegment() {
+		createSegment().visit(v);
+		assertVisitorFilled();
+		assertFalse(v.max.equals(v.min));
+	}
+
+	public void testVisitWay() {
+		createWay(createSegment()).visit(v);
+		assertVisitorFilled();
+		assertFalse(v.max.equals(v.min));
+	}
+
+	public void testVisitEastNorth() {
+		v.visit(new EastNorth(123,321));
+		v.visit(new EastNorth(124,322));
+		assertEquals(123.0, v.min.east());
+		assertEquals(124.0, v.max.east());
+		assertEquals(321.0, v.min.north());
+		assertEquals(322.0, v.max.north());
+	}
+
+	public void testGetBounds() {
+		Node node = createNode();
+		v.visit(node);
+		Bounds b = v.getBounds();
+		assertNotNull(b);
+		assertEquals(node.coor.lat(), b.min.lat());
+		assertEquals(node.coor.lon(), b.min.lon());
+	}
+
+}
Index: /test/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitorTest.java
===================================================================
--- /test/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitorTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitorTest.java	(revision 146)
@@ -0,0 +1,42 @@
+package org.openstreetmap.josm.data.osm.visitor;
+
+import java.lang.reflect.Field;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.testframework.MotherObject;
+
+public class CollectBackReferencesVisitorTest extends MotherObject {
+
+	private CollectBackReferencesVisitor v;
+	private DataSet ds;
+
+	@Override protected void setUp() throws Exception {
+		super.setUp();
+		ds = createDataSet();
+		v = new CollectBackReferencesVisitor(ds);
+	}
+
+	public void testCollectBackReferencesVisitor() throws Exception {
+		DataSet dataSet = new DataSet();
+		CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(dataSet);
+		Field f = v.getClass().getDeclaredField("ds");
+		f.setAccessible(true);
+		assertSame(dataSet, f.get(v));
+	}
+
+	public void testVisitNode() {
+		ds.nodes.iterator().next().visit(v);
+		assertContainsSame(v.data, ds.segments.iterator().next(), ds.ways.iterator().next());
+	}
+
+	public void testVisitSegment() {
+		ds.segments.iterator().next().visit(v);
+		assertContainsSame(v.data, ds.ways.iterator().next());
+	}
+
+	public void testVisitWay() {
+		ds.ways.iterator().next().visit(v);
+		assertEquals(0, v.data.size());
+	}
+
+}
Index: st/org/openstreetmap/josm/testframework/DateParserTest.java
===================================================================
--- /test/org/openstreetmap/josm/testframework/DateParserTest.java	(revision 145)
+++ 	(revision )
@@ -1,31 +1,0 @@
-package org.openstreetmap.josm.testframework;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import junit.framework.TestCase;
-
-import org.openstreetmap.josm.tools.DateParser;
-
-public class DateParserTest extends TestCase {
-
-	public void testWrong() throws Exception {
-	    try {
-	    	DateParser.parse("imi");
-	    	assertTrue(false);
-	    } catch (ParseException pe) {
-	    }
-    }
-	
-	public void testRight() throws Exception {
-		Date d = new SimpleDateFormat("dd MM yyyy HH mm ss SSS Z").parse("23 11 2001 23 05 42 123 +0100");
-		Date d2 = new Date(d.getTime()-123);
-		assertEquals(d2, DateParser.parse("11/23/2001 23:05:42"));
-		assertEquals(d2, DateParser.parse("11/23/2001T23:05:42"));
-		assertEquals(d2, DateParser.parse("11/23/2001T23:05:42+001"));
-		assertEquals(d2, DateParser.parse("2001-11-23T23:05:42+01:00"));
-        assertEquals(d, DateParser.parse("11/23/2001T23:05:42.123"));
-		assertEquals(d, DateParser.parse("11/23/2001T23:05:42.123+001"));
-    }
-}
Index: /test/org/openstreetmap/josm/testframework/MotherObject.java
===================================================================
--- /test/org/openstreetmap/josm/testframework/MotherObject.java	(revision 146)
+++ /test/org/openstreetmap/josm/testframework/MotherObject.java	(revision 146)
@@ -0,0 +1,92 @@
+package org.openstreetmap.josm.testframework;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import junit.framework.TestCase;
+
+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.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.projection.Epsg4326;
+
+public class MotherObject extends TestCase {
+
+	@Override protected void setUp() throws Exception {
+	    super.setUp();
+	    Main.proj = new Epsg4326();
+    }
+
+	public Node createNode(int id) {
+		return createNode(id, 0, 0);
+	}
+	
+	public Node createNode(int id, double lat, double lon) {
+		Node n = createNode(lat, lon);
+		n.id = id;
+		return n;
+	}
+
+	public Node createNode() {
+		return createNode(Math.random()*360-180, Math.random()*180-90);
+	}
+
+	public Node createNode(double lat, double lon) {
+	    return new Node(new LatLon(lat,lon));
+    }
+	
+	
+	public Segment createSegment(long id) {
+		Segment s = createSegment();
+		s.id = id;
+		return s;
+	}
+	public Segment createSegment(long id, Node from, Node to) {
+		Segment s = new Segment(from, to);
+		s.id = id;
+		return s;
+	}
+	public Segment createSegment() {
+		return new Segment(createNode(), createNode());
+	}
+	
+	
+	public Way createWay() {
+		return createWay(0);
+	}
+	public Way createWay(Segment... segments) {
+		return createWay(0, segments);
+	}
+	public Way createWay(long id, Segment... segments) {
+		Way way = new Way();
+		way.segments.addAll(Arrays.asList(segments));
+		way.id = id;
+		return way;
+	}
+	
+	public DataSet createDataSet() {
+	    DataSet ds = new DataSet();
+		Node node1 = createNode();
+		Node node2 = createNode();
+		Node node3 = createNode();
+		Segment segment = createSegment(23, node1, node2);
+		Way way = createWay(42, segment);
+		ds.nodes.add(node1);
+		ds.nodes.add(node2);
+		ds.nodes.add(node3);
+		ds.segments.add(segment);
+		ds.ways.add(way);
+		return ds;
+    }
+
+	public void assertContainsSame(Collection<OsmPrimitive> data, OsmPrimitive... all) {
+		Collection<OsmPrimitive> copy = new LinkedList<OsmPrimitive>(data);
+		copy.removeAll(Arrays.asList(all));
+		assertEquals(0, copy.size());
+    }
+}
Index: /test/org/openstreetmap/josm/tools/DateParserTest.java
===================================================================
--- /test/org/openstreetmap/josm/tools/DateParserTest.java	(revision 146)
+++ /test/org/openstreetmap/josm/tools/DateParserTest.java	(revision 146)
@@ -0,0 +1,31 @@
+package org.openstreetmap.josm.tools;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.openstreetmap.josm.tools.DateParser;
+
+public class DateParserTest extends TestCase {
+
+	public void testWrong() throws Exception {
+	    try {
+	    	DateParser.parse("imi");
+	    	assertTrue(false);
+	    } catch (ParseException pe) {
+	    }
+    }
+	
+	public void testRight() throws Exception {
+		Date d = new SimpleDateFormat("dd MM yyyy HH mm ss SSS Z").parse("23 11 2001 23 05 42 123 +0100");
+		Date d2 = new Date(d.getTime()-123);
+		assertEquals(d2, DateParser.parse("11/23/2001 23:05:42"));
+		assertEquals(d2, DateParser.parse("11/23/2001T23:05:42"));
+		assertEquals(d2, DateParser.parse("11/23/2001T23:05:42+001"));
+		assertEquals(d2, DateParser.parse("2001-11-23T23:05:42+01:00"));
+        assertEquals(d, DateParser.parse("11/23/2001T23:05:42.123"));
+		assertEquals(d, DateParser.parse("11/23/2001T23:05:42.123+001"));
+    }
+}
