Index: /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2387)
+++ /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 2388)
@@ -17,4 +17,5 @@
 
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
 
 /**
@@ -65,4 +66,8 @@
     }
 
+    public List<Node> searchNodes(BBox bbox) {
+        return nodes.search(bbox);
+    }
+
     /**
      * All ways (Streets etc.) in the DataSet.
@@ -76,4 +81,8 @@
     public Collection<Way> getWays() {
         return Collections.unmodifiableCollection(ways);
+    }
+
+    public List<Way> searchWays(BBox bbox) {
+        return ways.search(bbox);
     }
 
@@ -438,11 +447,11 @@
         DataSet ds = new DataSet();
         for (Node n : nodes) {
-            ds.nodes.add(new Node(n));
+            ds.addPrimitive(new Node(n));
         }
         for (Way w : ways) {
-            ds.ways.add(new Way(w));
+            ds.addPrimitive(new Way(w));
         }
         for (Relation e : relations) {
-            ds.relations.add(new Relation(e));
+            ds.addPrimitive(new Relation(e));
         }
         for (DataSource source : dataSources) {
@@ -667,3 +676,30 @@
         return ret;
     }
+
+    /**
+     * Reindex all nodes and ways after their coordinates were changed. This is a temporary solution, reindexing should
+     * be automatic in the future
+     */
+    public void reindexAll() {
+        List<Node> ntmp = new ArrayList<Node>(nodes);
+        nodes.clear();
+        nodes.addAll(ntmp);
+        List<Way> wtmp = new ArrayList<Way>(ways);
+        ways.clear();
+        ways.addAll(wtmp);
+    }
+
+    public void clenupDeletedPrimitives() {
+        cleanupDeleted(nodes.iterator());
+        cleanupDeleted(ways.iterator());
+        cleanupDeleted(relations.iterator());
+    }
+
+    private void cleanupDeleted(Iterator<? extends OsmPrimitive> it) {
+        while (it.hasNext()) {
+            if (it.next().isDeleted()) {
+                it.remove();
+            }
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 2387)
+++ /trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 2388)
@@ -4,34 +4,11 @@
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.tools.Pair;
-
-import java.nio.MappedByteBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.channels.FileChannel;
-import java.io.FileOutputStream;
-import java.io.RandomAccessFile;
-
-import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-import java.util.Map.Entry;
-import java.awt.geom.Point2D;
-
-//import java.util.List;
-import java.util.*;
-import java.util.Collection;
-
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.coor.QuadTiling;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
 
 
@@ -65,5 +42,5 @@
         long now = System.currentTimeMillis();
         if ((now - last_out < 300) &&
-            ((i+1) < total))
+                ((i+1) < total))
             return;
         last_out = now;
@@ -82,5 +59,5 @@
     public static int TILES_PER_LEVEL = 1<<TILES_PER_LEVEL_SHIFT;
     // Maybe this should just be a Rectangle??
-    class BBox
+    public static class BBox
     {
         private double xmin = Double.POSITIVE_INFINITY;
@@ -90,16 +67,20 @@
         void sanity()
         {
-            if (xmin < -180.0)
+            if (xmin < -180.0) {
                 xmin = -180.0;
-            if (xmax >  180.0)
+            }
+            if (xmax >  180.0) {
                 xmax =  180.0;
-            if (ymin <  -90.0)
+            }
+            if (ymin <  -90.0) {
                 ymin =  -90.0;
-            if (ymax >   90.0)
+            }
+            if (ymax >   90.0) {
                 ymax =   90.0;
+            }
             if ((xmin < -180.0) ||
-                (xmax >  180.0) ||
-                (ymin <  -90.0) ||
-                (ymax >   90.0)) {
+                    (xmax >  180.0) ||
+                    (ymin <  -90.0) ||
+                    (ymax >   90.0)) {
                 out("bad BBox: " + this);
                 Object o = null;
@@ -107,8 +88,9 @@
             }
         }
+        @Override
         public String toString()
         {
             return "[ x: " + xmin + " -> " + xmax +
-                   ", y: " + ymin + " -> " + ymax + " ]";
+            ", y: " + ymin + " -> " + ymax + " ]";
         }
         double min(double a, double b)
@@ -149,6 +131,7 @@
             for (Node n : w.getNodes()) {
                 LatLon coor = n.getCoor();
-                if (coor == null)
+                if (coor == null) {
                     continue;
+                }
                 add(coor);
             }
@@ -166,7 +149,7 @@
         {
             if (!(xmin <= b.xmin) ||
-                !(xmax >= b.xmax) ||
-                !(ymin <= b.ymin) ||
-                !(ymax >= b.ymax))
+                    !(xmax >= b.xmax) ||
+                    !(ymin <= b.ymin) ||
+                    !(ymax >= b.ymax))
                 return false;
             return true;
@@ -175,7 +158,7 @@
         {
             if ((xmin <= c.lon()) &&
-                (xmax >= c.lon()) &&
-                (ymin <= c.lat()) &&
-                (ymax >= c.lat()))
+                    (xmax >= c.lon()) &&
+                    (ymin <= c.lat()) &&
+                    (ymax >= c.lat()))
                 return true;
             return false;
@@ -223,6 +206,7 @@
     BBox way_bbox(Way w)
     {
-        if (way_bbox_cache.size() > 100)
+        if (way_bbox_cache.size() > 100) {
             way_bbox_cache.clear();
+        }
         BBox b = way_bbox_cache.get(w);
         if (b == null) {
@@ -242,4 +226,5 @@
         public List<T> content;
         public QBLevel children[];
+        @Override
         public String toString()
         {
@@ -263,6 +248,7 @@
         {
             boolean ret = this.content.remove(o);
-            if (this.content.size() == 0)
+            if (this.content.size() == 0) {
                 this.content = null;
+            }
             return ret;
         }
@@ -282,6 +268,7 @@
         int get_index(T o, int level)
         {
-            if (debug)
+            if (debug) {
                 out("getting index for " + o + " at level: " + level);
+            }
             if (o instanceof Node) {
                 Node n = (Node)o;
@@ -296,16 +283,19 @@
                 //for (Node n : w.getNodes()) {
                 for (LatLon c : way_bbox(w).points()) {
-                //    LatLon c = n.getCoor();
-                    if (debug)
+                    //    LatLon c = n.getCoor();
+                    if (debug) {
                         out("getting index for point: " + c);
+                    }
                     if (index == -1) {
                         index = QuadTiling.index(c, level);
-                        if (debug)
+                        if (debug) {
                             out("set initial way index to: " + index);
+                        }
                         continue;
                     }
                     int node_index = QuadTiling.index(c, level);
-                    if (debug)
+                    if (debug) {
                         out("other node way index: " + node_index);
+                    }
                     if (node_index != index) {
                         // This happens at level 0 sometimes when a way has no
@@ -315,6 +305,7 @@
                                     + node_index + "/" + index + " at level: " + level + "    ");
                             out("node count: " + w.getNodes().size());
-                            for (LatLon c2 : way_bbox(w).points())
+                            for (LatLon c2 : way_bbox(w).points()) {
                                 out("points: " + c2);
+                            }
                         }
                         return -1;
@@ -328,8 +319,9 @@
         void split()
         {
-            if (debug)
+            if (debug) {
                 out("splitting "+this.bbox()+" level "+level+" with "
                         + content.size() + " entries (my dimensions: "
                         + this.bbox.width()+", "+this.bbox.height()+")");
+            }
             if (children != null) {
                 abort("overwrote children");
@@ -349,9 +341,11 @@
                     continue;
                 }
-                if (children[new_index] == null)
+                if (children[new_index] == null) {
                     children[new_index] = new QBLevel(this, new_index);
+                }
                 QBLevel child = children[new_index];
-                if (debug)
+                if (debug) {
                     out("putting "+o+"(q:"+quads(o)+") into ["+new_index+"] " + child.bbox());
+                }
                 child.add(o);
             }
@@ -360,9 +354,11 @@
         {
             boolean ret = false;
-            if (content == null)
+            if (content == null) {
                 content = new ArrayList<T>();
+            }
             ret = content.add(o);
-            if (debug && !this.isLeaf())
+            if (debug && !this.isLeaf()) {
                 pout("added "+o.getClass().getName()+" to non-leaf with size: " + content.size());
+            }
             return ret;
         }
@@ -372,6 +368,7 @@
             add_content(o);
             if (content.size() > MAX_OBJECTS_PER_LEVEL) {
-                if (debug)
+                if (debug) {
                     out("["+level+"] deciding to split");
+                }
                 if (level >= NR_LEVELS-1) {
                     out("can not split, but too deep: " + level + " size: " + content.size());
@@ -379,6 +376,7 @@
                 }
                 int before_size = -1;
-                if (consistency_testing)
+                if (consistency_testing) {
                     before_size = this.size();
+                }
                 this.split();
                 if (consistency_testing) {
@@ -410,8 +408,10 @@
         {
             String size = "null";
-            if (content != null)
+            if (content != null) {
                 size = ""+content.size();
-            if (debug)
+            }
+            if (debug) {
                 out("searching contents (size: "+size+") for " + search_bbox);
+            }
             /*
              * It is possible that this was created in a split
@@ -428,9 +428,11 @@
             List<T> ret = new LinkedList<T>();
             for (T o : content) {
-                if (matches(o, search_bbox))
+                if (matches(o, search_bbox)) {
                     ret.add(o);
-            }
-            if (debug)
+                }
+            }
+            if (debug) {
                 out("done searching quad " + Long.toHexString(this.quad));
+            }
             return ret;
         }
@@ -457,6 +459,7 @@
                 int nr = __nr-1;
                 if (sibling == null) {
-                    if (debug)
+                    if (debug) {
                         out("[" + this.level + "] null child nr: " + nr);
+                    }
                     continue;
                 }
@@ -464,16 +467,19 @@
                 // after us.
                 if (sibling == this) {
-                    if (debug)
+                    if (debug) {
                         out("[" + this.level + "] I was child nr: " + nr);
+                    }
                     found_me = true;
                     continue;
                 }
                 if (found_me) {
-                    if (debug)
+                    if (debug) {
                         out("[" + this.level + "] next sibling was child nr: " + nr);
+                    }
                     return sibling;
                 }
-                if (debug)
+                if (debug) {
                     out("[" + this.level + "] nr: " + nr + " is before me, ignoring...");
+                }
             }
             return null;
@@ -494,9 +500,11 @@
                 // a leaf or branch.
                 while (sibling == null) {
-                    if (debug)
+                    if (debug) {
                         out("no siblings at level["+next.level+"], moving to parent");
+                    }
                     next = next.parent;
-                    if (next == null)
+                    if (next == null) {
                         break;
+                    }
                     sibling = next.next_sibling();
                 }
@@ -511,11 +519,14 @@
             // and find the first leaf
             while (!next.isLeaf()) {
-                if (next.hasContent() && next != this)
+                if (next.hasContent() && next != this) {
                     break;
-                if (debug)
+                }
+                if (debug) {
                     out("["+next.level+"] next node ("+next+") is a branch (content: "+next.hasContent()+"), moving down...");
+                }
                 for (QBLevel child : next.children) {
-                    if (child == null)
+                    if (child == null) {
                         continue;
+                    }
                     next = child;
                     break;
@@ -533,10 +544,12 @@
         {
             if (content == null) {
-                if (debug)
+                if (debug) {
                     out("["+level+"] leaf size: null content, children? " + children);
+                }
                 return 0;
             }
-            if (debug)
+            if (debug) {
                 out("["+level+"] leaf size: " + content.size());
+            }
             return content.size();
         }
@@ -545,12 +558,15 @@
             int ret = 0;
             for (QBLevel l : children) {
-                if (l == null)
+                if (l == null) {
                     continue;
+                }
                 ret += l.size();
             }
-            if (content != null)
+            if (content != null) {
                 ret += content.size();
-            if (debug)
+            }
+            if (debug) {
                 out("["+level+"] branch size: " + ret);
+            }
             return ret;
         }
@@ -575,9 +591,11 @@
                 return ret;
             for (QBLevel l : children) {
-                if (l == null)
+                if (l == null) {
                     continue;
+                }
                 ret = l.find_exact(n);
-                if (ret != null)
+                if (ret != null) {
                     break;
+                }
             }
             return ret;
@@ -593,8 +611,9 @@
                 }
             }
-            if (isLeaf())
+            if (isLeaf()) {
                 add_to_leaf(n);
-            else
+            } else {
                 add_to_branch(n);
+            }
             return true;
         }
@@ -603,6 +622,7 @@
             int index = get_index(n, level);
             if (index == -1) {
-                if (debug)
+                if (debug) {
                     out("unable to get index for " + n + "at level: " + level + ", adding content to branch: " + this);
+                }
                 this.add_content(n);
                 return this;
@@ -610,9 +630,10 @@
             if (debug) {
                 out("[" + level + "]: " + n +
-                    " index " + index + " levelquad:" + this.quads() + " level bbox:" + this.bbox());
+                        " index " + index + " levelquad:" + this.quads() + " level bbox:" + this.bbox());
                 out("   put in child["+index+"]");
             }
-            if (children[index] == null)
+            if (children[index] == null) {
                 children[index] = new QBLevel(this, index);
+            }
             children[index].add(n);
             return this;
@@ -621,6 +642,7 @@
         {
             List<T> ret = null;
-            if (debug)
+            if (debug) {
                 System.out.print("[" + level + "] qb bbox: " + this.bbox() + " ");
+            }
             if (!this.bbox().intersects(search_bbox)) {
                 if (debug) {
@@ -630,31 +652,38 @@
                 return ret;
             }
-            if (this.hasContent())
+            if (this.hasContent()) {
                 ret = this.search_contents(search_bbox);
-            if (this.isLeaf()) {
+            }
+            if (this.isLeaf())
                 return ret;
-            }
             //if (this.hasContent())
             //    abort("branch had stuff");
-            if (debug)
+            if (debug) {
                 out("hit " + this.quads());
+            }
 
-            if (debug)
+            if (debug) {
                 out("[" + level + "] not leaf, moving down");
+            }
             for (int i = 0; i < children.length; i++) {
                 QBLevel q = children[i];
-                if (debug)
+                if (debug) {
                     out("child["+i+"]: " + q);
-                if (q == null)
+                }
+                if (q == null) {
                     continue;
-                if (debug)
+                }
+                if (debug) {
                     System.out.print(i+": ");
+                }
                 List<T> coors = q.search(search_bbox);
-                if (coors == null)
+                if (coors == null) {
                     continue;
-                if (ret == null)
+                }
+                if (ret == null) {
                     ret = coors;
-                else
+                } else {
                     ret.addAll(coors);
+                }
                 if (q.bbox().bounds(search_bbox)) {
                     search_cache = q;
@@ -663,6 +692,7 @@
                     // what we were looking for.
                     if (coors.size() > 0 ) {
-                        if (debug)
+                        if (debug) {
                             out("break early");
+                        }
                         break;
                     }
@@ -677,10 +707,11 @@
         public void init(QBLevel parent)
         {
-                this.parent = parent;
-                if (parent == null)
-                    this.level = 0;
-                else
-                    this.level = parent.level + 1;
-                this.quad = 0;
+            this.parent = parent;
+            if (parent == null) {
+                this.level = 0;
+            } else {
+                this.level = parent.level + 1;
+            }
+            this.quad = 0;
         }
         int index_of(QBLevel find_this)
@@ -708,9 +739,10 @@
             long this_quadpart = mult * (parent_index << shift);
             this.quad = parent.quad | this_quadpart;
-            if (debug)
+            if (debug) {
                 out("new level["+this.level+"] bbox["+parent_index+"]: " + this.bbox()
                         + " coor: " + this.coor()
                         + " quadpart: " + Long.toHexString(this_quadpart)
                         + " quad: " + Long.toHexString(this.quad));
+            }
         }
         /*
@@ -779,25 +811,31 @@
     public boolean add(T n)
     {
-        if (debug)
+        if (debug) {
             out("QuadBuckets() add: " + n + " size now: " + this.size());
+        }
         int before_size = -1;
-        if (consistency_testing)
+        if (consistency_testing) {
             before_size = root.size();
+        }
         boolean ret;
         // A way with no nodes will have an infinitely large
         // bounding box.  Just stash it in the root node.
-        if (!n.isUsable())
+        if (!n.isUsable()) {
             ret = root.add_content(n);
-        else
+        } else {
             ret = root.add(n);
+        }
         if (consistency_testing) {
             int end_size = root.size();
-            if (ret)
+            if (ret) {
                 end_size--;
-            if (before_size != end_size)
+            }
+            if (before_size != end_size) {
                 abort("size inconsistency before add: " + before_size + " after: " + end_size);
-        }
-        if (debug)
+            }
+        }
+        if (debug) {
             out("QuadBuckets() add: " + n + " size after: " + this.size());
+        }
         return ret;
     }
@@ -820,6 +858,7 @@
     {
         for (T o : this) {
-            if (objects.contains(o))
+            if (objects.contains(o)) {
                 continue;
+            }
             if (!this.remove(o))
                 return false;
@@ -890,12 +929,14 @@
         while (i.hasNext()) {
             T o = i.next();
-            if (o != removeme)
+            if (o != removeme) {
                 continue;
+            }
             i.remove();
             ret = true;
             break;
         }
-        if (debug)
+        if (debug) {
             out("qb slow remove result: " + ret);
+        }
         return ret;
     }
@@ -906,6 +947,7 @@
          */
         QBLevel bucket = root.find_exact(o);
-        if (o instanceof Way)
+        if (o instanceof Way) {
             way_bbox_cache.remove(o);
+        }
         /*
          * That may fail because the object was
@@ -916,6 +958,7 @@
             return remove_slow(o);
         boolean ret = bucket.remove_content(o);
-        if (debug)
+        if (debug) {
             out("qb remove result: " + ret);
+        }
         return ret;
     }
@@ -932,8 +975,10 @@
     {
         ArrayList<T> a = new ArrayList<T>();
-        for (T n : this)
+        for (T n : this) {
             a.add(n);
-        if (debug)
-           out("returning array list with size: " + a.size());
+        }
+        if (debug) {
+            out("returning array list with size: " + a.size());
+        }
         return a;
     }
@@ -958,18 +1003,22 @@
             QBLevel next = q.nextContentNode();
             //if (consistency_testing && (orig == next))
-            if (orig == next)
+            if (orig == next) {
                 abort("got same leaf back leaf: " + q.isLeaf());
+            }
             return next;
         }
         public QuadBucketIterator(QuadBuckets<T> qb)
         {
-            if (debug)
+            if (debug) {
                 out(this + " is a new iterator qb: " + qb + " size: " + qb.size());
-            if (qb.root.isLeaf() || qb.root.hasContent())
+            }
+            if (qb.root.isLeaf() || qb.root.hasContent()) {
                 current_node = qb.root;
-            else
+            } else {
                 current_node = next_content_node(qb.root);
-            if (debug)
+            }
+            if (debug) {
                 out("\titerator first leaf: " + current_node);
+            }
             iterated_over = 0;
         }
@@ -977,6 +1026,7 @@
         {
             if (this.peek() == null) {
-                if (debug)
-                   out(this + " no hasNext(), but iterated over so far: " + iterated_over);
+                if (debug) {
+                    out(this + " no hasNext(), but iterated over so far: " + iterated_over);
+                }
                 return false;
             }
@@ -986,20 +1036,24 @@
         {
             if (current_node == null) {
-                if (debug)
+                if (debug) {
                     out("null current leaf, nowhere to go");
+                }
                 return null;
             }
             while((current_node.content == null) ||
-                  (content_index >= current_node.content.size())) {
-                if (debug)
+                    (content_index >= current_node.content.size())) {
+                if (debug) {
                     out("moving to next leaf");
+                }
                 content_index = 0;
                 current_node = next_content_node(current_node);
-                if (current_node == null)
+                if (current_node == null) {
                     break;
+                }
             }
             if (current_node == null || current_node.content == null) {
-                if (debug)
+                if (debug) {
                     out("late nowhere to go " + current_node);
+                }
                 return null;
             }
@@ -1010,10 +1064,12 @@
             T ret = peek();
             content_index++;
-            if (debug)
+            if (debug) {
                 out("iteration["+iterated_over+"] " + content_index + " leaf: " + current_node);
+            }
             iterated_over++;
             if (ret == null) {
-                if (debug)
+                if (debug) {
                     out(this + " no next node, but iterated over so far: " + iterated_over);
+                }
             }
             return ret;
@@ -1038,6 +1094,7 @@
         // This can certainly by optimized
         int ret = root.size();
-        if (debug)
+        if (debug) {
             out(this + " QuadBuckets size: " + ret);
+        }
         return ret;
     }
@@ -1061,10 +1118,12 @@
     {
         BBox bbox = new BBox(point.lon() - radius, point.lat() - radius,
-                             point.lon() + radius, point.lat() + radius);
-        if (debug)
+                point.lon() + radius, point.lat() + radius);
+        if (debug) {
             out("search bbox before sanity: " +  bbox);
+        }
         bbox.sanity();
-        if (debug)
+        if (debug) {
             out("search bbox after sanity: " +  bbox);
+        }
         return bbox;
     }
@@ -1101,12 +1160,14 @@
         boolean cache_searches = true;
         if (cache_searches) {
-            if (search_cache == null)
+            if (search_cache == null) {
                 search_cache = root;
+            }
             // Walk back up the tree when the last
             // search spot can not cover the current
             // search
             while (!search_cache.bbox().bounds(search_bbox)) {
-                if (debug)
+                if (debug) {
                     out("bbox: " + search_bbox);
+                }
                 if (debug) {
                     out("search_cache: " + search_cache + " level: " + search_cache.level);
@@ -1114,6 +1175,7 @@
                 }
                 search_cache = search_cache.parent;
-                if (debug)
+                if (debug) {
                     out("new search_cache: " + search_cache);
+                }
             }
         } else {
@@ -1121,6 +1183,7 @@
         }
         ret = search_cache.search(search_bbox);
-        if (ret == null)
+        if (ret == null) {
             ret = new ArrayList<T>();
+        }
         // A way that spans this bucket may be stored in one
         // of the nodes which is a parent of the search cache
@@ -1128,12 +1191,14 @@
         while (tmp != null) {
             List<T> content_result = tmp.search_contents(search_bbox);
-            if (content_result != null)
+            if (content_result != null) {
                 ret.addAll(content_result);
+            }
             tmp = tmp.parent;
         }
         if (ret == null || ret.size() == 0)
             return Collections.emptyList();
-        if (debug)
+        if (debug) {
             out("search of QuadBuckets for " + search_bbox + " ret len: " + ret.size());
+        }
         return ret;
     }
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 2387)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 2388)
@@ -98,6 +98,5 @@
      */
     protected <P extends OsmPrimitive> void mergePrimitive(P other,
-            Collection<P> myPrimitives, Collection<P> otherPrimitives,
-            HashMap<Long, P> primitivesWithDefinedIds) {
+            DataSet myDataset, Collection<P> myPrimitives, HashMap<Long, P> primitivesWithDefinedIds) {
 
         if (!other.isNew() ) {
@@ -105,5 +104,5 @@
             // defined id
             //
-            if (mergeById(myPrimitives, primitivesWithDefinedIds, other))
+            if (mergeById(primitivesWithDefinedIds, other))
                 return;
         } else {
@@ -136,19 +135,19 @@
         // my dataset. Just add other to my dataset.
         //
-        myPrimitives.add(other);
+        myDataset.addPrimitive(other);
     }
 
     public void visit(Node other) {
-        mergePrimitive(other, myDataSet.nodes, theirDataSet.nodes, nodeshash);
+        mergePrimitive(other, myDataSet, myDataSet.getNodes(), nodeshash);
     }
 
     public void visit(Way other) {
         fixWay(other);
-        mergePrimitive(other, myDataSet.ways, theirDataSet.ways, wayshash);
+        mergePrimitive(other, myDataSet, myDataSet.getWays(), wayshash);
     }
 
     public void visit(Relation other) {
         fixRelation(other);
-        mergePrimitive(other, myDataSet.relations, theirDataSet.relations, relshash);
+        mergePrimitive(other, myDataSet, myDataSet.getRelations(), relshash);
     }
 
@@ -230,5 +229,4 @@
      * Tries to merge a primitive <code>other</code> into an existing primitive with the same id.
      *
-     * @param myPrimitives the complete set of my primitives (potential merge targets)
      * @param myPrimitivesWithDefinedIds the map of primitives (potential merge targets) with an id <> 0, for faster lookup
      *    by id. Key is the id, value the primitive with the given value. myPrimitives.valueSet() is a
@@ -237,6 +235,5 @@
      * @return true, if this method was able to merge <code>other</code> with an existing node; false, otherwise
      */
-    private <P extends OsmPrimitive> boolean mergeById(
-            Collection<P> myPrimitives, HashMap<Long, P> myPrimitivesWithDefinedIds, P other) {
+    private <P extends OsmPrimitive> boolean mergeById(HashMap<Long, P> myPrimitivesWithDefinedIds, P other) {
 
         // merge other into an existing primitive with the same id, if possible
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2387)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2388)
@@ -52,5 +52,4 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
@@ -458,11 +457,12 @@
         // if uploaded, clean the modified flags as well
         final Set<OsmPrimitive> processedSet = new HashSet<OsmPrimitive>(processed);
-        for (final Iterator<Node> it = data.nodes.iterator(); it.hasNext();) {
+        data.clenupDeletedPrimitives();
+        for (final Iterator<Node> it = data.getNodes().iterator(); it.hasNext();) {
             cleanIterator(it, processedSet);
         }
-        for (final Iterator<Way> it = data.ways.iterator(); it.hasNext();) {
+        for (final Iterator<Way> it = data.getWays().iterator(); it.hasNext();) {
             cleanIterator(it, processedSet);
         }
-        for (final Iterator<Relation> it = data.relations.iterator(); it.hasNext();) {
+        for (final Iterator<Relation> it = data.getRelations().iterator(); it.hasNext();) {
             cleanIterator(it, processedSet);
         }
@@ -482,7 +482,4 @@
             return;
         osm.setModified(false);
-        if (osm.isDeleted()) {
-            it.remove();
-        }
     }
 
@@ -507,14 +504,17 @@
 
         String nodeText = trn("{0} node", "{0} nodes", counter.nodes, counter.nodes);
-        if (counter.deletedNodes > 0)
+        if (counter.deletedNodes > 0) {
             nodeText += " ("+trn("{0} deleted", "{0} deleted", counter.deletedNodes, counter.deletedNodes)+")";
+        }
 
         String wayText = trn("{0} way", "{0} ways", counter.ways, counter.ways);
-        if (counter.deletedWays > 0)
+        if (counter.deletedWays > 0) {
             wayText += " ("+trn("{0} deleted", "{0} deleted", counter.deletedWays, counter.deletedWays)+")";
+        }
 
         String relationText = trn("{0} relation", "{0} relations", counter.relations, counter.relations);
-        if (counter.deletedRelations > 0)
+        if (counter.deletedRelations > 0) {
             relationText += " ("+trn("{0} deleted", "{0} deleted", counter.deletedRelations, counter.deletedRelations)+")";
+        }
 
         p.add(new JLabel(tr("{0} consists of:", getName())), GBC.eol());
Index: /trunk/test/functional/org/openstreetmap/josm/io/MultiFetchServerObjectReaderTest.java
===================================================================
--- /trunk/test/functional/org/openstreetmap/josm/io/MultiFetchServerObjectReaderTest.java	(revision 2387)
+++ /trunk/test/functional/org/openstreetmap/josm/io/MultiFetchServerObjectReaderTest.java	(revision 2388)
@@ -15,5 +15,4 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.Properties;
 import java.util.logging.Level;
@@ -241,5 +240,5 @@
     public void testMultiGet10Nodes() throws OsmTransferException {
         MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
-        ArrayList<Node> nodes = new ArrayList<Node>(ds.nodes);
+        ArrayList<Node> nodes = new ArrayList<Node>(ds.getNodes());
         for (int i =0; i< 10; i++) {
             reader.append(nodes.get(i));
@@ -247,7 +246,5 @@
         DataSet out = reader.parseOsm(NullProgressMonitor.INSTANCE);
         assertEquals(10, out.getNodes().size());
-        Iterator<Node> it = out.nodes.iterator();
-        while(it.hasNext()) {
-            Node n1 = it.next();
+        for (Node n1:out.getNodes()) {
             Node n2 = (Node)ds.getPrimitiveById(n1.getId(), OsmPrimitiveType.NODE);
             assertNotNull(n2);
@@ -302,7 +299,5 @@
         DataSet out = reader.parseOsm(NullProgressMonitor.INSTANCE);
         assertEquals(812, out.getNodes().size());
-        Iterator<Node> it = out.nodes.iterator();
-        while(it.hasNext()) {
-            Node n1 = it.next();
+        for (Node n1:out.getNodes()) {
             Node n2 = (Node)ds.getPrimitiveById(n1.getId(), OsmPrimitiveType.NODE);
             assertNotNull(n2);
Index: /trunk/test/unit/org/openstreetmap/josm/data/osm/visitor/MergeSourceBuildingVisitorTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/osm/visitor/MergeSourceBuildingVisitorTest.java	(revision 2387)
+++ /trunk/test/unit/org/openstreetmap/josm/data/osm/visitor/MergeSourceBuildingVisitorTest.java	(revision 2388)
@@ -332,7 +332,7 @@
         RelationMember m = new RelationMember("node-20", lookupByName(hull.getNodes(), "n20"));
         assertTrue(r.getMembers().contains(m));
-        m = new RelationMember("way-30", lookupByName(hull.ways, "w30"));
-        assertTrue(r.getMembers().contains(m));
-        m = new RelationMember("relation-40", lookupByName(hull.relations, "r40"));
+        m = new RelationMember("way-30", lookupByName(hull.getWays(), "w30"));
+        assertTrue(r.getMembers().contains(m));
+        m = new RelationMember("relation-40", lookupByName(hull.getRelations(), "r40"));
         assertTrue(r.getMembers().contains(m));
     }
