Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 365)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 366)
@@ -26,5 +26,5 @@
 	/**
 	 * Map from primitives in the database to visited primitives. (Attention: The other way 
-	 * round than mergedNodes)
+	 * round than mergedPrims)
 	 */
 	public Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
@@ -38,5 +38,6 @@
 	 * in ds.nodes instead.
 	 */
-	private final Map<Node, Node> mergedNodes = new HashMap<Node, Node>();
+	private final Map<OsmPrimitive, OsmPrimitive> mergedPrims
+		= new HashMap<OsmPrimitive, OsmPrimitive>();
 
 	public MergeVisitor(DataSet ds, DataSet mergeds) {
@@ -50,5 +51,5 @@
 	 */
 	public void visit(Node other) {
-		if (mergeAfterId(mergedNodes, ds.nodes, other))
+		if (mergeAfterId(mergedPrims, ds.nodes, other))
 			return;
 
@@ -63,5 +64,5 @@
 			ds.nodes.add(other);
 		else {
-			mergedNodes.put(other, my);
+			mergedPrims.put(other, my);
 			mergeCommon(my, other);
 			if (my.modified && !other.modified)
@@ -75,11 +76,8 @@
 	}
 
-	/**
-	 * Simply calls cloneFrom() for now.
-	 * Might be useful to keep around to facilitate merge with the relations
-	 * branch.
-	 */
 	private <T extends OsmPrimitive> void cloneFromExceptIncomplete(T myOsm, T otherOsm) {
-		myOsm.cloneFrom(otherOsm);
+		if (!otherOsm.incomplete) {
+			myOsm.cloneFrom(otherOsm);
+		}
     }
 
@@ -89,5 +87,5 @@
 	 */
 	public void visit(Way other) {
-		if (mergeAfterId(null, ds.ways, other))
+		if (mergeAfterId(mergedPrims, ds.ways, other))
 			return;
 
@@ -102,4 +100,5 @@
 			ds.ways.add(other);
 		} else {
+			mergedPrims.put(other, my);
 			mergeCommon(my, other);
 			if (my.modified && !other.modified)
@@ -151,4 +150,5 @@
 			}*/
 		} else {
+			mergedPrims.put(other, my);
 			mergeCommon(my, other);
 			if (my.modified && !other.modified)
@@ -191,9 +191,11 @@
 	 */
 	public void fixReferences() {
-		for (Way w : ds.ways)
-			fixWay(w);
+		for (Way w : ds.ways) fixWay(w);
+		for (Relation r : ds.relations) fixRelation(r);
 		for (OsmPrimitive osm : conflicts.values())
 			if (osm instanceof Way)
 				fixWay((Way)osm);
+			else if (osm instanceof Relation)
+				fixRelation((Relation) osm);
 	}
 
@@ -202,5 +204,5 @@
 	    LinkedList<Node> newNodes = new LinkedList<Node>();
 	    for (Node n : w.nodes) {
-	    	Node otherN = mergedNodes.get(n);
+	    	Node otherN = (Node) mergedPrims.get(n);
 	    	newNodes.add(otherN == null ? n : otherN);
 	    	if (otherN != null)
@@ -210,6 +212,26 @@
 	    	w.nodes.clear();
 	    	w.nodes.addAll(newNodes);
+		}
     }
-    }
+
+	private void fixRelation(Relation r) {
+	    boolean replacedSomething = false;
+	    LinkedList<RelationMember> newMembers = new LinkedList<RelationMember>();
+	    for (RelationMember m : r.members) {
+	    	OsmPrimitive otherP = mergedPrims.get(m.member);
+			if (otherP == null) {
+				newMembers.add(m);
+			} else {
+				RelationMember mnew = new RelationMember(m);
+				mnew.member = otherP;
+				newMembers.add(mnew);
+	    		replacedSomething = true;
+			}
+	    }
+	    if (replacedSomething) {
+	    	r.members.clear();
+	    	r.members.addAll(newMembers);
+		}
+	}
 
 	/**
@@ -286,6 +308,8 @@
 	 * @return <code>true</code>, if no merge is needed or merge is performed already.
 	 */
-	private <P extends OsmPrimitive> boolean mergeAfterId(Map<P,P> merged, Collection<P> primitives, P other) {
+	private <P extends OsmPrimitive> boolean mergeAfterId(Map<OsmPrimitive,OsmPrimitive> merged, Collection<P> primitives, P other) {
 		for (P my : primitives) {
+			Date myd = my.timestamp == null ? new Date(0) : my.getTimestamp();
+			Date otherd = other.timestamp == null ? new Date(0) : other.getTimestamp();
 			if (my.realEqual(other, false)) {
 				if (merged != null)
@@ -297,5 +321,5 @@
 				if (merged != null)
 					merged.put(other, my);
-				if (my.getTimestamp().before(other.getTimestamp())) {
+				if (myd.before(otherd)) {
 					my.modified = other.modified;
 					my.timestamp = other.timestamp;
@@ -304,31 +328,25 @@
 			}
 			if (my.id == other.id && my.id != 0) {
-				if (my.modified && other.modified) {
+				if (my.incomplete) {
+					return false;
+				} else if (my.modified && other.modified) {
 					conflicts.put(my, other);
-					if (merged != null)
-						merged.put(other, my);
 				} else if (!my.modified && !other.modified) {
-					if (my.getTimestamp().before(other.getTimestamp())) {
+					if (myd.before(otherd)) {
 						cloneFromExceptIncomplete(my, other);
-						if (merged != null)
-							merged.put(other, my);
 					}
 				} else if (other.modified) {
-					if (my.getTimestamp().after(other.getTimestamp())) {
+					if (myd.after(otherd)) {
 						conflicts.put(my, other);
-						if (merged != null)
-							merged.put(other, my);
 					} else {
 						cloneFromExceptIncomplete(my, other);
-						if (merged != null)
-							merged.put(other, my);
 					}
 				} else if (my.modified) {
-					if (my.getTimestamp().before(other.getTimestamp())) {
+					if (myd.before(otherd)) {
 						conflicts.put(my, other);
-						if (merged != null)
-							merged.put(other, my);
-					}
-				}
+					}
+				}
+				if (merged != null)
+					merged.put(other, my);
 				return true;
 			}
