Index: trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 2426)
+++ trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 2427)
@@ -5,4 +5,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 
@@ -175,3 +176,10 @@
         return OsmPrimitiveType.NODE;
     }
+
+    public BBox getBBox() {
+        if (coor == null)
+            return new BBox(0, 0, 0, 0);
+        else
+            return new BBox(coor, coor);
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2426)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2427)
@@ -19,4 +19,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
@@ -1007,4 +1008,6 @@
     }
 
+    public abstract BBox getBBox();
+
 }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 2426)
+++ trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 2427)
@@ -1,3 +1,4 @@
 package org.openstreetmap.josm.data.osm;
+
 import java.lang.reflect.Array;
 import java.util.ArrayList;
@@ -5,5 +6,4 @@
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -190,28 +190,4 @@
         }
     }
-    /*
-     * This is a quick hack.  The problem is that we need the
-     * way's bounding box a *bunch* of times when it gets
-     * inserted.  It gets expensive if we have to recreate
-     * them each time.
-     *
-     * An alternative would be to calculate it at .add() time
-     * and passing it down the call chain.
-     */
-    HashMap<Way,BBox> way_bbox_cache = new HashMap<Way, BBox>();
-    BBox way_bbox(Way w)
-    {
-        if (way_bbox_cache.size() > 100) {
-            way_bbox_cache.clear();
-        }
-        BBox b = way_bbox_cache.get(w);
-        if (b == null) {
-            b = new BBox(w);
-            way_bbox_cache.put(w, b);
-        }
-        return b;
-        //return new BBox(w);
-    }
-
     class QBLevel
     {
@@ -247,6 +223,7 @@
                 this.content = null;
             }
-            if (this.canRemove())
+            if (this.canRemove()) {
                 this.remove_from_parent();
+            }
             return ret;
         }
@@ -268,48 +245,31 @@
                 out("getting index for " + o + " at level: " + level);
             }
-            if (o instanceof Node) {
-                LatLon coor = ((Node)o).getCoor();
-                if (coor == null)
+            int index = -1;
+            for (LatLon c : o.getBBox().points()) {
+                if (debug) {
+                    out("getting index for point: " + c);
+                }
+                if (index == -1) {
+                    index = QuadTiling.index(c, level);
+                    if (debug) {
+                        out("set initial index to: " + index);
+                    }
+                    continue;
+                }
+                int another_index = QuadTiling.index(c, level);
+                if (debug) {
+                    out("other point index: " + another_index);
+                }
+                if (another_index != index) {
+                    // This happens at level 0 sometimes when a way has no
+                    // nodes present.
+                    if (debug) {
+                        out("primitive ("+o.getId()+") would have gone across two quads "
+                                + another_index + "/" + index + " at level: " + level + "    ");
+                    }
                     return -1;
-                return QuadTiling.index(coor, level);
-            }
-            if (o instanceof Way) {
-                Way w = (Way)o;
-                int index = -1;
-                //for (Node n : w.getNodes()) {
-                for (LatLon c : way_bbox(w).points()) {
-                    //    LatLon c = n.getCoor();
-                    if (debug) {
-                        out("getting index for point: " + c);
-                    }
-                    if (index == -1) {
-                        index = QuadTiling.index(c, level);
-                        if (debug) {
-                            out("set initial way index to: " + index);
-                        }
-                        continue;
-                    }
-                    int node_index = QuadTiling.index(c, level);
-                    if (debug) {
-                        out("other node way index: " + node_index);
-                    }
-                    if (node_index != index) {
-                        // This happens at level 0 sometimes when a way has no
-                        // nodes present.
-                        if (debug) {
-                            out("way ("+w.getId()+") would have gone across two quads "
-                                    + node_index + "/" + index + " at level: " + level + "    ");
-                            out("node count: " + w.getNodes().size());
-                            for (LatLon c2 : way_bbox(w).points()) {
-                                out("points: " + c2);
-                            }
-                        }
-                        return -1;
-                    }
-                }
-                return index;
-            }
-            abort("bad primitive: " + o);
-            return -1;
+                }
+            }
+            return index;
         }
         void split()
@@ -367,6 +327,7 @@
                 }
                 if (level >= NR_LEVELS-1) {
-                    if (debug)
+                    if (debug) {
                         out("can not split, but too deep: " + level + " size: " + content.size());
+                    }
                     return;
                 }
@@ -388,16 +349,5 @@
         boolean matches(T o, BBox search_bbox)
         {
-            if (o instanceof Node) {
-                LatLon coor = ((Node)o).getCoor();
-                if (coor == null)
-                    return false;
-                return search_bbox.bounds(coor);
-            }
-            if (o instanceof Way) {
-                BBox bbox = way_bbox((Way)o);
-                return bbox.intersects(search_bbox);
-            }
-            abort("matches() bad primitive: " + o);
-            return false;
+            return o.getBBox().intersects(search_bbox);
         }
         private List<T> search_contents(BBox search_bbox)
@@ -497,9 +447,9 @@
                 if (debug) {
                     out("no siblings at level["+next.level+"], moving to parent");
-                    }
+                }
                 next = next.parent;
                 if (next == null) {
                     break;
-                    }
+                }
                 sibling = next.next_sibling();
             }
@@ -510,19 +460,23 @@
         {
             QBLevel next = this;
-            if (this.isLeaf())
+            if (this.isLeaf()) {
                 next = this.nextSibling();
+            }
             if (next == null)
                 return null;
             // Walk back down the tree
             // and find the first leaf
-            while (next != null && !next.isLeaf()) {
-                if (next.hasContent() && next != this)
+            while (!next.isLeaf()) {
+                if (next.hasContent() && next != this) {
                     break;
-                if (debug)
+                }
+                if (debug) {
                     out("["+next.level+"] next node ("+next+") is a branch (content: "+next.hasContent()+"), moving down...");
+                }
                 boolean progress = false;
                 for (QBLevel child : next.children) {
-                    if (child == null)
+                    if (child == null) {
                         continue;
+                    }
                     next = child;
                     progress = true;
@@ -817,15 +771,19 @@
             for (int i = 0; i < parent.children.length; i++) {
                 QBLevel sibling = parent.children[i];
-                if (sibling != null)
+                if (sibling != null) {
                     nr_siblings++;
-                if (sibling != this)
+                }
+                if (sibling != this) {
                     continue;
-                if (!canRemove())
+                }
+                if (!canRemove()) {
                     abort("attempt to remove non-empty child: " + this.content + " " + this.children);
+                }
                 parent.children[i] = null;
                 nr_siblings--;
             }
-            if (parent.canRemove())
+            if (parent.canRemove()) {
                 parent.remove_from_parent();
+            }
         }
         boolean canRemove()
@@ -911,47 +869,27 @@
         return true;
     }
-    boolean canStore(Object o)
-    {
-        if (o instanceof Way)
-            return true;
-        if (o instanceof Node)
-            return true;
-        return false;
-    }
     public boolean removeAll(Collection<?> objects)
     {
+        boolean changed = false;
         for (Object o : objects) {
-            if (!canStore(o))
-                return false;
-            if (!this.remove(o))
+            changed = changed | remove(o);
+        }
+        return changed;
+    }
+    public boolean addAll(Collection<? extends T> objects)
+    {
+        boolean changed = false;
+        for (Object o : objects) {
+            changed = changed | this.add(convert(o));
+        }
+        return changed;
+    }
+    public boolean containsAll(Collection<?> objects)
+    {
+        for (Object o : objects) {
+            if (!this.contains(o))
                 return false;
         }
         return true;
-    }
-    public boolean addAll(Collection<? extends T> objects)
-    {
-        for (Object o : objects) {
-            if (!canStore(o))
-                return false;
-            if (!this.add(convert(o)))
-                return false;
-        }
-        return true;
-    }
-    public boolean containsAll(Collection<?> objects)
-    {
-        for (Object o : objects) {
-            if (!canStore(o))
-                return false;
-            if (!this.contains(o))
-                return false;
-        }
-        return true;
-    }
-    private void check_type(Object o)
-    {
-        if (canStore(o))
-            return;
-        unsupported();
     }
     // If anyone has suggestions for how to fix
@@ -964,5 +902,4 @@
     public boolean remove(Object o)
     {
-        check_type(o);
         return this.remove(convert(o));
     }
@@ -991,7 +928,4 @@
          */
         QBLevel bucket = root.find_exact(o);
-        if (o instanceof Way) {
-            way_bbox_cache.remove(o);
-        }
         /*
          * That may fail because the object was
@@ -1009,6 +943,4 @@
     public boolean contains(Object o)
     {
-        if (!canStore(o))
-            return false;
         QBLevel bucket = root.find_exact(convert(o));
         if (bucket == null)
Index: trunk/src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 2426)
+++ trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 2427)
@@ -7,4 +7,5 @@
 import java.util.Set;
 
+import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.tools.CopyList;
@@ -324,3 +325,8 @@
         return OsmPrimitiveType.RELATION;
     }
+
+    @Override
+    public BBox getBBox() {
+        return new BBox(0, 0, 0, 0);
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 2426)
+++ trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 2427)
@@ -9,4 +9,5 @@
 import java.util.List;
 
+import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.tools.CopyList;
@@ -362,3 +363,9 @@
         }
     }
+
+    @Override
+    public BBox getBBox() {
+        // TODO Precalculate way bbox (and update it every time nodes are moved or edited)
+        return new BBox(this);
+    }
 }
