Index: /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManagerTest.java
===================================================================
--- /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManagerTest.java	(revision 2690)
+++ /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManagerTest.java	(revision 2690)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs.changeset;
+
+import javax.swing.JFrame;
+
+public class ChangesetCacheManagerTest extends JFrame {
+
+    private ChangesetCacheManager manager;
+
+    public ChangesetCacheManagerTest() {
+    }
+
+    public void start() {
+        manager = new ChangesetCacheManager();
+        manager.setVisible(true);
+    }
+
+    static public void main(String args[]) {
+        new ChangesetCacheManagerTest().start();
+    }
+}
Index: /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialogTest.java
===================================================================
--- /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialogTest.java	(revision 2690)
+++ /trunk/test/functional/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialogTest.java	(revision 2690)
@@ -0,0 +1,26 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs.changeset.query;
+
+import javax.swing.JFrame;
+
+import org.openstreetmap.josm.fixtures.JOSMFixture;
+
+public class ChangesetQueryDialogTest extends JFrame {
+
+    private ChangesetQueryDialog dialog;
+
+    public ChangesetQueryDialogTest() {
+    }
+
+    public void start() {
+        JOSMFixture fixture = JOSMFixture.createFunctionalTestFixture();
+        dialog = new ChangesetQueryDialog(this);
+        dialog.initForUserInput();
+        dialog.setVisible(true);
+    }
+
+
+    static public void main(String args[]) {
+        new ChangesetQueryDialogTest().start();
+    }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/gui/JosmUserIdentityManagerTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/JosmUserIdentityManagerTest.groovy	(revision 2690)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/JosmUserIdentityManagerTest.groovy	(revision 2690)
@@ -0,0 +1,317 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui;
+
+import org.junit.BeforeClass;
+import org.junit.Test 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.UserInfo;
+import org.openstreetmap.josm.fixtures.JOSMFixture;
+
+import static org.junit.Assert.*;
+
+class JosmUserIdentityManagerTest {
+	
+	final shouldFail = new GroovyTestCase().&shouldFail
+	
+	private static JOSMFixture josmFixture
+	
+	@BeforeClass
+	public static void initTestCase() {
+	    josmFixture = JOSMFixture.createFunctionalTestFixture()
+	}
+	
+	@Test
+	public void test_SingletonAccess() {
+		
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()		
+
+		// created ?
+		assert im != null
+		
+		// registered as listener ? 
+		assert Main.pref.@listeners.contains(im)
+		
+		JosmUserIdentityManager im2 = JosmUserIdentityManager.getInstance()
+
+		// only one instance
+		assert im == im2		
+	}
+	
+	@Test
+	public void test_setAnonymouse() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		im.setPartiallyIdentified "test"
+		im.setAnonymous()
+				
+		assert im.isAnonymous()
+		assert ! im.isPartiallyIdentified()
+		assert ! im.isFullyIdentified()
+		
+		assert im.getUserId() == 0
+		assert im.getUserName() == null
+		assert im.getUserInfo() == null
+	}
+	
+	@Test
+	public void test_setPartiallyIdentified() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		im.setPartiallyIdentified "test"
+		
+		shouldFail(IllegalArgumentException) {
+		    im.setPartiallyIdentified null
+		}
+		
+		shouldFail(IllegalArgumentException) {
+			im.setPartiallyIdentified ""
+		}
+		
+		shouldFail(IllegalArgumentException) {
+			im.setPartiallyIdentified "  \t  "
+		}
+		
+		im.setPartiallyIdentified "test"
+		
+		assert ! im.isAnonymous()
+		assert im.isPartiallyIdentified()
+		assert ! im.isFullyIdentified()
+		
+		assert im.getUserId() == 0
+		assert im.getUserName() == "test"
+		assert im.getUserInfo() == null
+	}
+	
+	
+	@Test
+	public void test_setFullyIdentified() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+
+		UserInfo userInfo = new UserInfo(id: 1, description: "a description")
+		
+		im.setFullyIdentified "test", userInfo
+		
+		shouldFail(IllegalArgumentException) {
+			im.setFullyIdentified null, userInfo
+		}
+		shouldFail(IllegalArgumentException) {
+			im.setFullyIdentified "", userInfo
+		}
+		shouldFail(IllegalArgumentException) {
+			im.setFullyIdentified " \t ", userInfo
+		}
+		shouldFail(IllegalArgumentException) {
+			im.setFullyIdentified "test", null
+		}
+		
+		im.setFullyIdentified "test", userInfo
+		
+		assert ! im.isAnonymous()
+		assert ! im.isPartiallyIdentified()
+		assert im.isFullyIdentified()
+		
+		assert im.getUserId() == 1
+		assert im.getUserName() == "test"
+		assert im.getUserInfo() == userInfo
+	}
+	
+	/**
+	 * Preferences include neither an url nor a user name => we have
+	 * an anonymous user 
+	 */
+	@Test 
+	public void initFromPreferences_1() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		// reset it 
+		im.@userName = null
+		im.@userInfo = null
+		
+		Main.pref.put "osm-server.url", null
+		Main.pref.put "osm-server.username", null
+		
+		im.initFromPreferences()
+		
+		assert im.isAnonymous()
+	}
+	
+	/**
+	 * Preferences include neither an url nor a user name => we have
+	 * an annoymous user 
+	 */
+	@Test 
+	public void initFromPreferences_2() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		// reset it 
+		im.@userName = null
+		im.@userInfo = null
+		
+		// for this test we disable the listener
+		Main.pref.removePreferenceChangeListener im
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		Main.pref.put "osm-server.username", null
+		
+		im.initFromPreferences()
+		
+		assert im.isAnonymous()
+	}
+	
+	/**
+	 * Preferences include an user name => we have a partially identified user 
+	 */
+	@Test 
+	public void initFromPreferences_3() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+
+        // for this test we disable the listener
+		Main.pref.removePreferenceChangeListener im
+
+		// reset it 
+		im.@userName = null
+		im.@userInfo = null
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		Main.pref.put "osm-server.username", "test"
+		
+		im.initFromPreferences()
+		
+		assert im.isPartiallyIdentified()
+	}
+	
+	/**
+	 * Preferences include an user name which is different from the current
+	 * user name and we are currently fully identifed => josm user becomes
+	 * partially identified  
+	 */
+	@Test 
+	public void initFromPreferences_4() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+
+        // for this test we disable the listener
+		Main.pref.removePreferenceChangeListener im
+
+		im.setFullyIdentified "test1", new UserInfo(id: 1)
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		Main.pref.put "osm-server.username", "test2"
+		
+		im.initFromPreferences()
+		
+		assert im.isPartiallyIdentified()
+	}
+	
+	/**
+	 * Preferences include an user name which is the same as the current
+	 * user name and we are currently fully identifed => josm user remains
+	 * fully identified
+	 */
+	@Test 
+	public void initFromPreferences_5() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+
+        // for this test we disable the listener
+		Main.pref.removePreferenceChangeListener im
+    	
+		im.setFullyIdentified "test1", new UserInfo(id: 1)
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		Main.pref.put "osm-server.username", "test1"
+		
+		im.initFromPreferences()
+		
+		assert im.isFullyIdentified()
+	}
+	
+	@Test 
+	public void apiUrlChanged() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		// make sure im is a preference change listener 
+		Main.pref.addPreferenceChangeListener im
+		
+		// reset it 
+		im.@userName = null
+		im.@userInfo = null
+				
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		assert im.isAnonymous()
+		
+         Main.pref.put "osm-server.url", null
+         assert im.isAnonymous()
+		
+		// reset it 
+		im.@userName = "test"
+		im.@userInfo = null
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		assert im.isPartiallyIdentified()
+		assert im.getUserName() == "test"
+		
+		Main.pref.put "osm-server.url", null
+		assert im.isAnonymous()
+		
+		// reset it 
+		im.@userName = "test"
+		im.@userInfo = new UserInfo(id:1)
+		
+		Main.pref.put "osm-server.url", "http://api.openstreetmap.org"
+		assert im.isPartiallyIdentified()
+		assert im.getUserName() == "test"
+		
+		// reset it 
+		im.@userName = "test"
+		im.@userInfo = new UserInfo(id:1)
+		
+		
+		Main.pref.put "osm-server.url", null
+		assert im.isAnonymous()				
+	}
+	
+	@Test 
+	public void userNameChanged() {
+		JosmUserIdentityManager im = JosmUserIdentityManager.getInstance()
+		
+		// make sure im is a preference change listener 
+		Main.pref.addPreferenceChangeListener im
+		
+		// reset it 
+		im.@userName = null
+		im.@userInfo = null
+		
+		Main.pref.put "osm-server.username", "test"
+		assert im.isPartiallyIdentified()
+		assert im.getUserName() == "test"
+		
+		Main.pref.put "osm-server.username", null
+		assert im.isAnonymous()
+		
+		// reset it 
+		im.@userName = "test1"
+		im.@userInfo = null
+		
+		Main.pref.put "osm-server.username", "test2"
+		assert im.isPartiallyIdentified()
+		assert im.getUserName() == "test2"
+		
+		Main.pref.put "osm-server.username", null
+		assert im.isAnonymous()
+		
+		// reset it 
+		im.@userName = "test1"
+		im.@userInfo = new UserInfo(id:1)
+		
+		Main.pref.put "osm-server.username", "test2"
+		assert im.isPartiallyIdentified()
+		assert im.getUserName() == "test2"
+		
+		// reset it 
+		im.@userName = "test1"
+		im.@userInfo = new UserInfo(id:1)
+		
+		
+		Main.pref.put "osm-server.username", null
+		assert im.isAnonymous()             
+	}
+}
Index: /trunk/test/unit/org/openstreetmap/josm/io/ChangsetQueryUrlParserTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/ChangsetQueryUrlParserTest.groovy	(revision 2690)
+++ /trunk/test/unit/org/openstreetmap/josm/io/ChangsetQueryUrlParserTest.groovy	(revision 2690)
@@ -0,0 +1,191 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.junit.Test 
+import org.openstreetmap.josm.io.ChangesetQuery.ChangesetQueryUrlException;
+import org.openstreetmap.josm.io.ChangesetQuery.ChangesetQueryUrlParser;
+
+
+import static org.junit.Assert.*;
+
+class ChangsetQueryUrlParserTest {
+	final shouldFail = new GroovyTestCase().&shouldFail
+	
+	@Test
+	public void test_constructor() {
+	    ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+	}
+	
+	@Test
+	public void test_parse_basic() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		
+		// OK
+		parser.parse ""
+		
+		// should be OK
+		ChangesetQuery q = parser.parse(null)
+		assert q != null
+		
+		// should be OK
+		q = parser.parse("")
+		assert q != null
+	}
+	
+	@Test 
+	public void test_uid() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("uid=1234")
+		assert q != null
+		
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("uid=0")				
+		}
+		
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("uid=-1")               
+		}
+		
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("uid=abc")               
+		}
+	}
+	
+	@Test 
+	public void test_display_name() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("display_name=abcd")
+		assert q != null
+		assert q.@userName == "abcd"
+	}
+	
+	
+	@Test 
+	public void test_open() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("open=true")
+		assert q != null
+		assert q.@open == true
+		
+		// OK
+		q = parser.parse("open=false")
+		assert q != null
+		assert q.@open == false
+		
+		// illegal value for open 
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("open=abcd")               
+		}   		
+	}
+	
+	@Test 
+	public void test_closed() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("closed=true")
+		assert q != null
+		assert q.@closed == true
+		
+		// OK
+		q = parser.parse("closed=false")
+		assert q != null
+		assert q.@closed == false
+		
+		// illegal value for open 
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("closed=abcd")               
+		}           
+	}
+	
+	
+	@Test 
+	public void test_uid_and_display_name() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// we can't have both an uid and a display name 
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("uid=1&display_name=abcd")               
+		}		
+	}
+	
+	@Test 
+	public void test_time() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("time=2009-12-25T10:00:00Z")
+		assert q != null
+		assert q.@closedAfter != null   
+		Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
+		cal.setTime(q.@closedAfter);
+		assert cal.get(Calendar.YEAR) == 2009
+		assert cal.get(Calendar.MONTH) == 11 // calendar is 0-based
+		assert cal.get(Calendar.DAY_OF_MONTH) == 25
+		assert cal.get(Calendar.HOUR_OF_DAY) == 10
+		assert cal.get(Calendar.MINUTE) == 0
+		assert cal.get(Calendar.SECOND) == 0
+		
+		// OK
+		q = parser.parse("time=2009-12-25T10:00:00Z,2009-11-25T10:00:00Z")
+		assert q!= null
+		assert q.@closedAfter != null
+		assert q.@createdBefore != null
+		
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("time=asdf")               
+		}   		
+	}
+	
+	@Test 
+	public void test_bbox() {
+		ChangesetQueryUrlParser parser = new ChangesetQueryUrlParser();
+		def ChangesetQuery q
+		
+		// OK
+		q = parser.parse("bbox=-1,-1,1,1")
+		assert q != null
+		assert q.@bounds != null
+		
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("bbox=-91,-1,1,1")               
+		}           
+				
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("bbox=-1,-181,1,1")               
+		}           
+		
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("bbox=-1,-1,91,1")               
+		}           
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("bbox=-1,-1,1,181")               
+		}  
+		// should fail
+		shouldFail(ChangesetQueryUrlException) {
+			q = parser.parse("bbox=-1,-1,1")               
+		}  
+	}
+}
Index: /trunk/test/unit/org/openstreetmap/josm/io/OsmChangeBuilderTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/OsmChangeBuilderTest.groovy	(revision 2689)
+++ /trunk/test/unit/org/openstreetmap/josm/io/OsmChangeBuilderTest.groovy	(revision 2690)
@@ -1,14 +1,10 @@
-// License: GPL. For details, see LICENSE file.
-
 package org.openstreetmap.josm.io;
 
 import org.junit.Test 
-import org.openstreetmap.josm.data.osm.Changeset
-import org.openstreetmap.josm.data.osm.Node
-import org.openstreetmap.josm.data.coor.LatLon
-
+import org.openstreetmap.josm.data.coor.LatLon 
+import org.openstreetmap.josm.data.osm.Changeset 
 
 import static org.junit.Assert.*;
-
+ 
 class OsmChangeBuilderTest {
 	
@@ -30,5 +26,5 @@
 		builder = new OsmChangeBuilder(cs, null)
 		
-		builder = new OsmChangeBuilder(null, null)		
+		builder = new OsmChangeBuilder(null, null)      
 	}
 	
@@ -43,5 +39,5 @@
 		
 		final shouldFail = new GroovyTestCase().&shouldFail
-				
+		
 		// should be OK 
 		builder.start()
@@ -51,5 +47,5 @@
 		
 		shouldFail(IllegalStateException) {
-		    builder = new OsmChangeBuilder(cs)
+			builder = new OsmChangeBuilder(cs)
 			builder.append n
 		}
@@ -61,5 +57,5 @@
 		
 		shouldFail(IllegalStateException) {
-		    builder = new OsmChangeBuilder(cs)
+			builder = new OsmChangeBuilder(cs)
 			builder.finish()
 		}
@@ -69,5 +65,5 @@
 			builder.start()
 			builder.start()
-		}		
+		}       
 	}
 	
@@ -97,10 +93,10 @@
 		assert node.@lat != null
 		assert node.@lon != null
-		assert node.@changeset == cs.id.toString()		
-	}	
-	
-    /**
-     * Test building a coument with a modified node 
-     */
+		assert node.@changeset == cs.id.toString()      
+	}   
+	
+	/**
+	 * Test building a document with a modified node 
+	 */
 	@Test
 	public void testDocumentWithModifiedNode() {
@@ -191,5 +187,5 @@
 		builder.append([n1,n2,n3])
 		builder.finish()
-  
+		
 		def doc = new XmlParser().parseText(builder.document)
 		
@@ -206,5 +202,5 @@
 		
 		node = doc.children()[2].node[0]
-		assert node.@id == n3.uniqueId.toString()		
+		assert node.@id == n3.uniqueId.toString()       
 	}
 }
Index: /trunk/test/unit/org/openstreetmap/josm/io/OsmChangesetContentParserTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/OsmChangesetContentParserTest.groovy	(revision 2690)
+++ /trunk/test/unit/org/openstreetmap/josm/io/OsmChangesetContentParserTest.groovy	(revision 2690)
@@ -0,0 +1,212 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import org.junit.Test 
+
+import static org.junit.Assert.*;
+import org.openstreetmap.josm.data.osm.ChangesetDataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType;
+import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
+import org.openstreetmap.josm.data.osm.history.HistoryRelation;
+import org.openstreetmap.josm.data.osm.history.HistoryWay;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.io.OsmChangesetContentParser;
+
+
+class OsmChangesetContentParserTest {
+	final shouldFail = new GroovyTestCase().&shouldFail
+	
+	@Test
+	public void test_Constructor() {
+	    OsmChangesetContentParser parser 
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(new ByteArrayInputStream("".bytes))
+		
+		shouldFail(IllegalArgumentException) {
+			parser = new OsmChangesetContentParser(null)
+		}
+	}
+	
+	
+	@Test
+	public void test_parse_arguments() {
+		OsmChangesetContentParser parser 
+		
+		def String doc = """
+		    <osmChange version="0.6" generator="OpenStreetMap server">
+		    </osmChange>
+		"""
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(new ByteArrayInputStream(doc.getBytes("UTF-8")))
+		parser.parse null
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(new ByteArrayInputStream(doc.getBytes("UTF-8")))		
+		parser.parse NullProgressMonitor.INSTANCE
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(doc)	
+		parser.parse null		
+	}	
+	
+	/**
+	 * A simple changeset content document with one created node 
+	 * 
+	 */
+	@Test
+	public void test_OK_OneCreatedNode() {
+		OsmChangesetContentParser parser 
+		
+		def String doc = """
+            <osmChange version="0.6" generator="OpenStreetMap server">
+		      <create>
+		        <node id="1" version="1" visible="true" changeset="1" lat="1.0" lon="1.0" timestamp="2009-12-22" />
+		      </create>
+            </osmChange>
+        """
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(doc) 
+		ChangesetDataSet ds = parser.parse()
+
+        assert ds.size() == 1		
+		HistoryOsmPrimitive p = ds.getPrimitive(new SimplePrimitiveId(1, OsmPrimitiveType.NODE));
+		assert p != null
+		assert p.getId() == 1
+		assert p.getVersion() == 1
+		assert p.getChangesetId() == 1
+		assert p.getTimestamp() != null
+		assert ds.getModificationType(p.getPrimitiveId()) == ChangesetModificationType.CREATED
+		assert ds.isCreated(p.getPrimitiveId())
+	}
+	
+	/**
+	 * A simple changeset content document with one updated node 
+	 * 
+	 */
+	@Test
+	public void test_OK_OneUpdatedNode() {
+		OsmChangesetContentParser parser 
+		
+		def String doc = """
+            <osmChange version="0.6" generator="OpenStreetMap server">
+              <modify>
+                <node id="1" version="1" visible="true" changeset="1" lat="1.0" lon="1.0" timestamp="2009-12-22" />
+              </modify>
+            </osmChange>
+        """
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(doc) 
+		ChangesetDataSet ds = parser.parse()
+		
+		assert ds.size() == 1       
+		HistoryOsmPrimitive p = ds.getPrimitive(new SimplePrimitiveId(1, OsmPrimitiveType.NODE));
+		assert p != null
+		assert p.getId() == 1
+		assert p.getVersion() == 1
+		assert p.getChangesetId() == 1
+		assert p.getTimestamp() != null
+		assert ds.getModificationType(p.getPrimitiveId()) == ChangesetModificationType.UPDATED
+		assert ds.isUpdated(p.getPrimitiveId())
+	}
+	
+	/**
+	 * A simple changeset content document with one deleted node 
+	 * 
+	 */
+	@Test
+	public void test_OK_OneDeletedNode() {
+		OsmChangesetContentParser parser 
+		
+		def String doc = """
+            <osmChange version="0.6" generator="OpenStreetMap server">
+              <delete>
+                <node id="1" version="1" visible="true" changeset="1" lat="1.0" lon="1.0" timestamp="2009-12-22" />
+              </delete>
+            </osmChange>
+        """
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(doc) 
+		ChangesetDataSet ds = parser.parse()
+		
+		assert ds.size() == 1       
+		HistoryOsmPrimitive p = ds.getPrimitive(new SimplePrimitiveId(1, OsmPrimitiveType.NODE));
+		assert p != null
+		assert p.getId() == 1
+		assert p.getVersion() == 1
+		assert p.getChangesetId() == 1
+		assert p.getTimestamp() != null
+		assert ds.getModificationType(p.getPrimitiveId()) == ChangesetModificationType.DELETED
+		assert ds.isDeleted(p.getPrimitiveId())
+	}
+	
+	/**
+	 * A more complex test with a document including nodes, ways, and relations. 
+	 * 
+	 */
+	@Test
+	public void test_OK_ComplexTestCase() {
+		OsmChangesetContentParser parser 
+		
+		def String doc = """
+            <osmChange version="0.6" generator="OpenStreetMap server">
+              <create>
+                <node id="1" version="1" visible="true" changeset="1" lat="1.0" lon="1.0" timestamp="2009-12-22">
+		          <tag k="a.key" v="a.value" />
+		        </node>
+              </create>
+              <modify>
+               <way id="2" version="2" visible="true" changeset="1" timestamp="2009-12-22">
+		          <nd ref="21"/>
+		          <nd ref="22"/>
+		       </way>
+             </modify>
+		     <delete>
+                <relation id="3" version="3" visible="true" changeset="1" timestamp="2009-12-22" />
+              </delete>
+            </osmChange>
+        """
+		
+		// should be OK 
+		parser = new OsmChangesetContentParser(doc) 
+		ChangesetDataSet ds = parser.parse()
+		
+		assert ds.size() == 3       
+		
+		HistoryOsmPrimitive p = ds.getPrimitive(new SimplePrimitiveId(1, OsmPrimitiveType.NODE));
+		assert p != null
+		assert p.getId() == 1
+		assert p.getVersion() == 1
+		assert p.getChangesetId() == 1
+		assert p.getTimestamp() != null
+		assert ds.getModificationType(p.getPrimitiveId()) == ChangesetModificationType.CREATED
+		assert ds.isCreated(p.getPrimitiveId())
+		assert p.get("a.key") == "a.value"
+		
+		HistoryWay w = (HistoryWay)ds.getPrimitive(new SimplePrimitiveId(2, OsmPrimitiveType.WAY));
+		assert w != null
+		assert w.getId() == 2
+		assert w.getVersion() == 2
+		assert w.getChangesetId() == 1
+		assert w.getTimestamp() != null
+		assert ds.getModificationType(w.getPrimitiveId()) == ChangesetModificationType.UPDATED
+		assert ds.isUpdated(w.getPrimitiveId())
+		assert w.getNumNodes() == 2
+		assert w.getNodes() == [21,22]
+		
+		HistoryRelation r = (HistoryRelation)ds.getPrimitive(new SimplePrimitiveId(3, OsmPrimitiveType.RELATION));
+		assert r != null
+		assert r.getId() == 3
+		assert r.getVersion() == 3
+		assert r.getChangesetId() == 1
+		assert r.getTimestamp() != null
+		assert ds.getModificationType(r.getPrimitiveId()) == ChangesetModificationType.DELETED
+		assert ds.isDeleted(r.getPrimitiveId())
+	}
+}
