Index: src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- src/org/openstreetmap/josm/data/Bounds.java	(revision 6207)
+++ src/org/openstreetmap/josm/data/Bounds.java	(working copy)
@@ -364,15 +364,23 @@
         if (b.maxLat < minLat || b.minLat > maxLat)
             return false;
 
-        if (crosses180thMeridian() && !b.crosses180thMeridian()) {
-            return intersectsLonCrossing(this, b);
-        } else if (!crosses180thMeridian() && b.crosses180thMeridian()) {
-            return intersectsLonCrossing(b, this);
-        } else if (crosses180thMeridian() && b.crosses180thMeridian()) {
-            return true;
-        } else {
-            return b.maxLon >= minLon && b.minLon <= maxLon;
+        boolean bcross = b.crosses180thMeridian();
+        if (crosses180thMeridian()){
+            if (bcross){
+                return true;
+            }
+            else {
+                return intersectsLonCrossing(this, b);
+            }
         }
+        else {
+            if (bcross){
+                return intersectsLonCrossing(b, this);
+            }
+            else {
+                return b.maxLon >= minLon && b.minLon <= maxLon;
+            }            
+        }
     }
 
     /**
@@ -389,7 +397,7 @@
      * @return the bounding box to Rectangle2D.Double
      */
     public Rectangle2D.Double asRect() {
-        double w = maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0);
+        double w = maxLon - minLon + (crosses180thMeridian() ? 360.0 : 0.0);
         return new Rectangle2D.Double(minLon, minLat, w, maxLat-minLat);
     }
 
Index: src/org/openstreetmap/josm/data/osm/BBox.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/BBox.java	(revision 6207)
+++ src/org/openstreetmap/josm/data/osm/BBox.java	(working copy)
@@ -50,8 +50,8 @@
         this.ymax = copy.ymax;
     }
 
-    public BBox(double a_x, double a_y, double b_x, double b_y)  {
-        
+    public BBox(double a_x, double a_y, double b_x, double b_y) {
+
         if (a_x > b_x) {
             xmax = a_x;
             xmin = b_x;
@@ -59,7 +59,7 @@
             xmax = b_x;
             xmin = a_x;
         }
-        
+
         if (a_y > b_y) {
             ymax = a_y;
             ymin = b_y;
@@ -67,7 +67,7 @@
             ymax = b_y;
             ymin = a_y;
         }
-        
+
         sanity();
     }
 
@@ -77,8 +77,9 @@
             if (coor == null) {
                 continue;
             }
-            add(coor);
+            addNoSanity(coor.lon(), coor.lat());
         }
+        sanity();
     }
 
     public BBox(Node n) {
@@ -88,21 +89,22 @@
         } else {
             xmin = xmax = coor.lon();
             ymin = ymax = coor.lat();
+            sanity();
         }
     }
 
-    private void sanity()  {
+    private void sanity() {
         if (xmin < -180.0) {
             xmin = -180.0;
         }
-        if (xmax >  180.0) {
-            xmax =  180.0;
+        if (xmax > 180.0) {
+            xmax = 180.0;
         }
-        if (ymin <  -90.0) {
-            ymin =  -90.0;
+        if (ymin < -90.0) {
+            ymin = -90.0;
         }
-        if (ymax >   90.0) {
-            ymax =   90.0;
+        if (ymax > 90.0) {
+            ymax = 90.0;
         }
     }
 
@@ -111,14 +113,18 @@
     }
 
     /**
-     * Extends this bbox to include the point (x, y)
+     * Extends this bbox to include the point (x, y).
      */
     public void add(double x, double y) {
+        addNoSanity(x, y);
+        sanity();
+    }
+
+    private void addNoSanity(double x, double y) {
         xmin = Math.min(xmin, x);
         xmax = Math.max(xmax, x);
         ymin = Math.min(ymin, y);
         ymax = Math.max(ymax, y);
-        sanity();
     }
 
     public void add(BBox box) {
@@ -131,16 +137,17 @@
 
     public void addPrimitive(OsmPrimitive primitive, double extraSpace) {
         BBox primBbox = primitive.getBBox();
-        add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace);
-        add(primBbox.xmax + extraSpace, primBbox.ymax + extraSpace);
+        addNoSanity(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace);
+        addNoSanity(primBbox.xmax + extraSpace, primBbox.ymax + extraSpace);
+        sanity();
     }
 
     public double height() {
-        return ymax-ymin;
+        return ymax - ymin;
     }
 
     public double width() {
-        return xmax-xmin;
+        return xmax - xmin;
     }
 
     /**
@@ -148,10 +155,7 @@
      * this bbox.
      */
     public boolean bounds(BBox b) {
-        if (!(xmin <= b.xmin) ||
-                !(xmax >= b.xmax) ||
-                !(ymin <= b.ymin) ||
-                !(ymax >= b.ymax))
+        if (!(xmin <= b.xmin) || !(xmax >= b.xmax) || !(ymin <= b.ymin) || !(ymax >= b.ymax))
             return false;
         return true;
     }
@@ -160,10 +164,7 @@
      * Tests, weather the Point c lies within the bbox.
      */
     public boolean bounds(LatLon c) {
-        if ((xmin <= c.lon()) &&
-                (xmax >= c.lon()) &&
-                (ymin <= c.lat()) &&
-                (ymax >= c.lat()))
+        if ((xmin <= c.lon()) && (xmax >= c.lon()) && (ymin <= c.lat()) && (ymax >= c.lat()))
             return true;
         return false;
     }
@@ -237,7 +238,7 @@
     }
 
     public LatLon getCenter() {
-        return new LatLon(ymin + (ymax-ymin)/2.0, xmin + (xmax-xmin)/2.0);
+        return new LatLon((ymin + ymax) / 2, (xmin + xmax) / 2);
     }
 
     int getIndex(final int level) {
@@ -259,15 +260,40 @@
         return idx1;
     }
 
+    /**
+     *  
+     * 
+     * @param index
+     * @return
+     */
+    public BBox quadrant(int index) {
+
+        final double cx = (xmin + xmax) / 2;
+        final double cy = (ymin + ymax) / 2;
+
+        switch (index) {
+        case QuadBuckets.SE_INDEX:
+            return new BBox(cx, ymin, xmax, cy);
+        case QuadBuckets.SW_INDEX:
+            return new BBox(xmin, ymin, cx, cy);
+        case QuadBuckets.NE_INDEX:
+            return new BBox(cx, cy, xmax, ymax);
+        case QuadBuckets.NW_INDEX:
+            return new BBox(xmin, cy, cx, ymax);
+        }
+
+        return null;
+    }
+
     @Override
     public int hashCode() {
-        return (int)(ymin * xmin);
+        return (int) (ymin * xmin);
     }
 
     @Override
     public boolean equals(Object o) {
         if (o instanceof BBox) {
-            BBox b = (BBox)o;
+            BBox b = (BBox) o;
             return b.xmax == xmax && b.ymax == ymax && b.xmin == xmin && b.ymin == ymin;
         } else
             return false;
@@ -275,15 +301,13 @@
 
     @Override
     public String toString() {
-        return "[ x: " + xmin + " -> " + xmax +
-        ", y: " + ymin + " -> " + ymax + " ]";
+        return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]";
     }
 
     public String toStringCSV(String separator) {
-        return Utils.join(separator, Arrays.asList(
-                LatLon.cDdFormatter.format(xmin),
-                LatLon.cDdFormatter.format(ymin),
-                LatLon.cDdFormatter.format(xmax),
-                LatLon.cDdFormatter.format(ymax)));
+        return Utils.join(
+                separator,
+                Arrays.asList(LatLon.cDdFormatter.format(xmin), LatLon.cDdFormatter.format(ymin),
+                        LatLon.cDdFormatter.format(xmax), LatLon.cDdFormatter.format(ymax)));
     }
 }
Index: src/org/openstreetmap/josm/data/osm/QuadBuckets.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 6207)
+++ src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(working copy)
@@ -20,10 +20,11 @@
  */
 public class QuadBuckets<T extends OsmPrimitive> implements Collection<T> {
     private static final boolean consistency_testing = false;
-    private static final int NW_INDEX = 1;
-    private static final int NE_INDEX = 3;
-    private static final int SE_INDEX = 2;
-    private static final int SW_INDEX = 0;
+    
+    static final int NW_INDEX = 1;
+    static final int NE_INDEX = 3;
+    static final int SE_INDEX = 2;
+    static final int SW_INDEX = 0;
 
     static void abort(String s) {
         throw new AssertionError(s);
@@ -35,7 +36,6 @@
         private final int level;
         private final int index;
         private final BBox bbox;
-        private final long quad;
         private final QBLevel<T> parent;
         private boolean isLeaf = true;
 
@@ -88,7 +88,6 @@
         public QBLevel(final QuadBuckets<T> buckets) {
             level = 0;
             index = 0;
-            quad = 0;
             parent = null;
             bbox = new BBox(-180, 90, 180, -90);
             this.buckets = buckets;
@@ -99,26 +98,12 @@
             this.level = parent.level + 1;
             this.index = parent_index;
             this.buckets = buckets;
-
-            int shift = (QuadTiling.NR_LEVELS - level) * 2;
-            long mult = 1;
-            // Java blows the big one. It seems to wrap when you shift by > 31
-            if (shift >= 30) {
-                shift -= 30;
-                mult = 1 << 30;
-            }
-            long this_quadpart = mult * (parent_index << shift);
-            this.quad = parent.quad | this_quadpart;
-            this.bbox = calculateBBox(); // calculateBBox reference quad
+            
+            this.bbox = parent.bbox.quadrant(parent_index);
+            
+            //System.out.println(parent_index + "\t" + parent.bbox + " -> " + bbox);
         }
 
-        private BBox calculateBBox() {
-            LatLon bottom_left = this.coor();
-            double lat = bottom_left.lat() + parent.height() / 2;
-            double lon = bottom_left.lon() + parent.width() / 2;
-            return new BBox(bottom_left.lon(), bottom_left.lat(), lon, lat);
-        }
-
         QBLevel<T> findBucket(BBox bbox) {
             if (!hasChildren())
                 return this;
@@ -267,9 +252,9 @@
         }
 
         QBLevel<T> nextNode() {
-            if (!this.hasChildren())
-                return this.nextSibling();
-            return this.firstChild();
+            final QBLevel<T> firstChild = this.firstChild();
+            
+            return firstChild != null ? firstChild : nextSibling();
         }
 
         QBLevel<T> nextContentNode() {
@@ -301,9 +286,9 @@
         }
 
         private void search(BBox search_bbox, List<T> result) {
-            if (!this.bbox().intersects(search_bbox))
+            if (!bbox.intersects(search_bbox))
                 return;
-            else if (bbox().bounds(search_bbox)) {
+            else if (bbox.bounds(search_bbox)) {
                 buckets.search_cache = this;
             }
 
@@ -327,10 +312,6 @@
             }
         }
 
-        public String quads() {
-            return Long.toHexString(quad);
-        }
-
         int index_of(QBLevel<T> find_this) {
             QBLevel<T>[] children = getChildren();
             for (int i = 0; i < QuadTiling.TILES_PER_LEVEL; i++) {
@@ -352,14 +333,6 @@
             return bbox;
         }
 
-        /*
-         * This gives the coordinate of the bottom-left
-         * corner of the box
-         */
-        LatLon coor() {
-            return QuadTiling.tile2LatLon(this.quad);
-        }
-
         void remove_from_parent() {
             if (parent == null)
                 return;
