Index: /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 3479)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 3480)
@@ -230,6 +230,6 @@
     {
         Bounds b= new Bounds(
-                new LatLon(zoneLimitsDegree[layoutZone][1] - cMaxOverlappingZonesDegree, -4.9074074074074059),
-                new LatLon(zoneLimitsDegree[layoutZone][0] + cMaxOverlappingZonesDegree, 10.2));
+                new LatLon(Math.max(zoneLimitsDegree[layoutZone][1] - cMaxOverlappingZonesDegree, Math.toDegrees(cMinLatZone1Radian)), Math.toDegrees(cMinLonZonesRadian)),
+                new LatLon(Math.min(zoneLimitsDegree[layoutZone][0] + cMaxOverlappingZonesDegree, Math.toDegrees(cMaxLatZone1Radian)), Math.toDegrees(cMaxLonZonesRadian)));
         return b;
     }
Index: /trunk/src/org/openstreetmap/josm/data/projection/LambertCC9Zones.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/LambertCC9Zones.java	(revision 3479)
+++ /trunk/src/org/openstreetmap/josm/data/projection/LambertCC9Zones.java	(revision 3480)
@@ -166,6 +166,6 @@
         double medLatZone = cMinLatZonesDegree + (layoutZone+1);
         return new Bounds(
-                new LatLon(medLatZone - 1.0 - cMaxOverlappingZones, -4.9),
-                new LatLon(medLatZone + 1.0 + cMaxOverlappingZones, 10.2));
+                new LatLon(Math.max(medLatZone - 1.0 - cMaxOverlappingZones, cMinLatZonesDegree), -4.9),
+                new LatLon(Math.min(medLatZone + 1.0 + cMaxOverlappingZones, Math.toDegrees(cMaxLatZonesRadian)), 10.2));
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/projection/Puwg.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Puwg.java	(revision 3479)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Puwg.java	(revision 3480)
@@ -29,5 +29,5 @@
     private int zone = DEFAULT_ZONE;
 
-    private static PuwgData[] Zones = new PuwgData[]{
+    static PuwgData[] Zones = new PuwgData[]{
         new Epsg2180(),
         new Epsg2176(),
Index: /trunk/test/unit/org/openstreetmap/josm/data/projection/EllipsoidTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/projection/EllipsoidTest.java	(revision 3480)
+++ /trunk/test/unit/org/openstreetmap/josm/data/projection/EllipsoidTest.java	(revision 3480)
@@ -0,0 +1,46 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.projection;
+
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.openstreetmap.josm.data.coor.LatLon;
+
+public class EllipsoidTest {
+
+    final double EPSILON = 1e-8;
+    
+    /**
+     * convert latlon to cartesian coordinates back and forth
+     */
+    @Test
+    public void latLon2Cart2LatLon() {
+        Random r = new Random(System.currentTimeMillis());
+        double maxErrLat = 0, maxErrLon = 0;
+        Ellipsoid ellips = Ellipsoid.WGS84;
+        for (int num=0; num<1000; ++num) {
+
+            double lat = r.nextDouble() * 180.0 - 90.0;
+            double lon = r.nextDouble() * 360.0 - 180.0;
+            LatLon ll = new LatLon(lat,lon);
+
+            for (int i=0; i<1000; ++i) {
+                double[] cart = ellips.latLon2Cart(ll);
+                ll = ellips.cart2LatLon(cart);
+                
+                if (!(Math.abs(lat - ll.lat())<EPSILON && Math.abs(lon - ll.lon())<EPSILON)) {
+                    String error = String.format("point: %s iterations: %s current: %s errorLat: %s errorLon %s",
+                            new LatLon(lat, lon), i, ll, Math.abs(lat - ll.lat()), Math.abs(lon - ll.lon()));
+                    System.err.println(error);
+                    Assert.fail();
+                }
+            }
+
+            maxErrLat = Math.max(maxErrLat, Math.abs(lat - ll.lat()));
+            maxErrLon = Math.max(maxErrLon, Math.abs(lon - ll.lon()));
+        }
+        //System.err.println(String.format("maxerror lat: %s maxerror lon: %s", maxErrLat, maxErrLon));
+    }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java	(revision 3480)
+++ /trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java	(revision 3480)
@@ -0,0 +1,105 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.projection;
+
+import java.util.Collections;
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+
+public class ProjectionTest {
+
+    private static final boolean debug = false;
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    boolean error;
+    String text;
+
+    @Test
+    public void proj() {
+        error = false;
+        text = "";
+
+        for (Projection p : new Projection[] {new Epsg4326(), new Mercator(), new LambertEST()}) {
+            testProj(p);
+        }
+
+        Lambert lam = new Lambert();
+        for (int zone=1; zone<=4; ++zone) {
+            lam.setPreferences(Collections.singletonList(Integer.toString(zone)));
+            testProj(lam);
+        }
+
+        Puwg puwg = new Puwg();
+        for (PuwgData pd : Puwg.Zones) {
+            puwg.setPreferences(Collections.singletonList(pd.toCode()));
+            testProj(puwg);
+        }
+
+        testProj(new SwissGrid());
+
+        UTM utm = new UTM();
+        for (int i=0; i<=6; ++i) {
+            int zone;
+            if (i==0) {
+                zone = 0;
+            } else if (i==6) {
+                zone = 59;
+            } else {
+                zone = rand.nextInt(60);
+            }
+            utm.setPreferences(Collections.singletonList(Integer.toString(zone)));
+            testProj(utm);
+
+        }
+        UTM_France_DOM utmFr = new UTM_France_DOM();
+        for (int zone=1; zone<=5; ++zone) {
+            utmFr.setPreferences(Collections.singletonList(Integer.toString(zone)));
+            testProj(utmFr);
+        }
+
+        LambertCC9Zones lamCC9 = new LambertCC9Zones();
+        for (int i=1; i<=9; ++i) {
+            lamCC9.setPreferences(Collections.singletonList(Integer.toString(i)));
+            testProj(lamCC9);
+        }
+
+        if (error) {
+            System.err.println(text);
+            Assert.fail();
+        }
+    }
+
+    private void testProj(Projection p) {
+        double maxErrLat = 0, maxErrLon = 0;
+
+        Bounds b = p.getWorldBoundsLatLon();
+
+        text += String.format("*** %s %s\n", p.toString(), p.toCode());
+        for (int num=0; num < 1000; ++num) {
+
+            double lat = rand.nextDouble() * (b.getMax().lat() - b.getMin().lat()) + b.getMin().lat();
+            double lon = rand.nextDouble() * (b.getMax().lon() - b.getMin().lon()) + b.getMin().lon();
+
+            LatLon ll = new LatLon(lat, lon);
+
+            for (int i=0; i<10; ++i) {
+                EastNorth en = p.latlon2eastNorth(ll);
+                ll = p.eastNorth2latlon(en);
+            }
+            maxErrLat = Math.max(maxErrLat, Math.abs(lat - ll.lat()));
+            maxErrLon = Math.max(maxErrLon, Math.abs(lon - ll.lon()));
+        }
+
+        String mark = "";
+        if (maxErrLat + maxErrLon > 1e-5) {
+            mark = "--FAILED-- ";
+            error = true;
+        }
+        text += String.format("%s errorLat: %s errorLon: %s\n", mark, maxErrLat, maxErrLon);
+    }
+}
