Index: /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1823)
@@ -628,4 +628,5 @@
      */
     private void computeHelperLine() {
+        MapView mv = Main.map.mapView;
         if (mousePos == null) {
             // Don't draw the line.
@@ -651,5 +652,5 @@
 
         if (!ctrl && mousePos != null) {
-            currentMouseNode = Main.map.mapView.getNearestNode(mousePos);
+            currentMouseNode = mv.getNearestNode(mousePos);
         }
 
@@ -657,5 +658,5 @@
         // *and* there is no node nearby (because nodes beat ways when re-using)
         if(!ctrl && currentMouseNode == null) {
-            List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(mousePos);
+            List<WaySegment> wss = mv.getNearestWaySegments(mousePos);
             for(WaySegment ws : wss) {
                 mouseOnExistingWays.add(ws.way);
@@ -670,5 +671,5 @@
         } else {
             // no node found in clicked area
-            currentMouseEastNorth = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
+            currentMouseEastNorth = mv.getEastNorth(mousePos.x, mousePos.y);
         }
 
@@ -708,5 +709,5 @@
 
         // find out the distance, in metres, between the base point and the mouse cursor
-        LatLon mouseLatLon = Main.proj.eastNorth2latlon(currentMouseEastNorth);
+        LatLon mouseLatLon = mv.getProjection().eastNorth2latlon(currentMouseEastNorth);
         distance = currentBaseNode.getCoor().greatCircleDistance(mouseLatLon);
         double hdg = Math.toDegrees(currentBaseNode.getCoor().heading(mouseLatLon));
Index: /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 1823)
@@ -36,10 +36,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Lambert.java	(revision 1823)
@@ -277,10 +277,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java	(revision 1823)
@@ -107,10 +107,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 1823)
@@ -47,10 +47,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/Projection.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/Projection.java	(revision 1823)
@@ -63,5 +63,4 @@
      * Get the bounds of the world
      */
-    ProjectionBounds getWorldBounds();
     Bounds getWorldBoundsLatLon();
 }
Index: /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java	(revision 1823)
@@ -101,10 +101,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/data/projection/UTM.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/data/projection/UTM.java	(revision 1823)
@@ -354,10 +354,4 @@
     }
 
-    public ProjectionBounds getWorldBounds()
-    {
-        Bounds b = getWorldBoundsLatLon();
-        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
-    }
-
     public Bounds getWorldBoundsLatLon()
     {
Index: /trunk/src/org/openstreetmap/josm/gui/MapSlider.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapSlider.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/gui/MapSlider.java	(revision 1823)
@@ -30,5 +30,5 @@
         if (getModel().getValueIsAdjusting()) return;
 
-        ProjectionBounds world = Main.proj.getWorldBounds();
+        ProjectionBounds world = this.mv.getMaxProjectionBounds();
         ProjectionBounds current = this.mv.getProjectionBounds();
 
@@ -54,5 +54,5 @@
         if (preventChange) return;
 
-        ProjectionBounds world = Main.proj.getWorldBounds();
+        ProjectionBounds world = this.mv.getMaxProjectionBounds();
         double fact = Math.pow(1.1, getValue());
         double es = world.max.east()-world.min.east();
Index: /trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 1823)
@@ -13,4 +13,5 @@
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseMotionListener;
+import java.awt.geom.GeneralPath;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
@@ -29,4 +30,5 @@
 import org.openstreetmap.josm.actions.MoveAction;
 import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.SelectionChangedListener;
@@ -35,4 +37,5 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
@@ -295,13 +298,35 @@
         // draw world borders
         tempG.setColor(Color.WHITE);
-        ProjectionBounds b = getProjection().getWorldBounds();
-        Point min = getPoint(b.min);
-        Point max = getPoint(b.max);
-        int x1 = Math.min(min.x, max.x);
-        int y1 = Math.min(min.y, max.y);
-        int x2 = Math.max(min.x, max.x);
-        int y2 = Math.max(min.y, max.y);
-        if (x1 > 0 || y1 > 0 || x2 < getWidth() || y2 < getHeight()) {
-            tempG.drawRect(x1, y1, x2-x1+1, y2-y1+1);
+        GeneralPath path = new GeneralPath();
+        Bounds b = getProjection().getWorldBoundsLatLon();
+        double lat = b.min.lat();
+        double lon = b.min.lon();
+
+        Point p = getPoint(b.min);
+        path.moveTo(p.x, p.y);
+
+        double max = b.max.lat();
+        for(; lat <= max; lat += 1.0)
+        {
+            p = getPoint(new LatLon(lat >= max ? max : lat, lon));
+            path.lineTo(p.x, p.y);
+        }
+        lat = max; max = b.max.lon();
+        for(; lon <= max; lon += 1.0)
+        {
+            p = getPoint(new LatLon(lat, lon >= max ? max : lon));
+            path.lineTo(p.x, p.y);
+        }
+        lon = max; max = b.min.lat();
+        for(; lat >= max; lat -= 1.0)
+        {
+            p = getPoint(new LatLon(lat <= max ? max : lat, lon));
+            path.lineTo(p.x, p.y);
+        }
+        lat = max; max = b.min.lon();
+        for(; lon >= max; lon -= 1.0)
+        {
+            p = getPoint(new LatLon(lat, lon <= max ? max : lon));
+            path.lineTo(p.x, p.y);
         }
 
@@ -309,4 +334,5 @@
             playHeadMarker.paint(tempG, this);
         }
+        tempG.draw(path);
 
         g.drawImage(offscreenBuffer, 0, 0, null);
@@ -322,5 +348,5 @@
         }
         if (box.getBounds() == null) {
-            box.visit(getProjection().getWorldBounds());
+            box.visit(getProjection().getWorldBoundsLatLon());
         }
         if (!box.hasExtend()) {
Index: /trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 1823)
@@ -72,6 +72,8 @@
     public double getDist100Pixel()
     {
-        LatLon ll1 = getLatLon(0,0);
-        LatLon ll2 = getLatLon(100,0);
+        int w = getWidth()/2;
+        int h = getHeight()/2;
+        LatLon ll1 = getLatLon(w-50,h);
+        LatLon ll2 = getLatLon(w+50,h);
         return ll1.greatCircleDistance(ll2);
     }
@@ -103,9 +105,17 @@
                         center.east() - getWidth()/2.0*scale,
                         center.north() - getHeight()/2.0*scale),
-                        new EastNorth(
-                                center.east() + getWidth()/2.0*scale,
-                                center.north() + getHeight()/2.0*scale));
+                new EastNorth(
+                        center.east() + getWidth()/2.0*scale,
+                        center.north() + getHeight()/2.0*scale));
     };
 
+    /* FIXME: replace with better method - used by MapSlider */
+    public ProjectionBounds getMaxProjectionBounds() {
+        Bounds b = getProjection().getWorldBoundsLatLon();
+        return new ProjectionBounds(getProjection().latlon2eastNorth(b.min),
+            getProjection().latlon2eastNorth(b.max));
+    };
+
+    /* FIXME: replace with better method - used by Main to reset Bounds when projection changes, don't use otherwise */
     public Bounds getRealBounds() {
         return new Bounds(
@@ -113,7 +123,7 @@
                         center.east() - getWidth()/2.0*scale,
                         center.north() - getHeight()/2.0*scale)),
-                        getProjection().eastNorth2latlon(new EastNorth(
-                                center.east() + getWidth()/2.0*scale,
-                                center.north() + getHeight()/2.0*scale)));
+                getProjection().eastNorth2latlon(new EastNorth(
+                        center.east() + getWidth()/2.0*scale,
+                        center.north() + getHeight()/2.0*scale)));
     };
 
@@ -161,6 +171,17 @@
      */
     private void zoomTo(EastNorth newCenter, double newScale) {
-        /* TODO: check that newCenter is really inside visible world and that scale is correct, don't allow zooming out to much */
         boolean rep = false;
+
+        Bounds b = getProjection().getWorldBoundsLatLon();
+        CachedLatLon cl = new CachedLatLon(newCenter);
+        boolean changed = false;;
+        double lat = cl.lat();
+        double lon = cl.lon();
+        if(lat < b.min.lat()) {changed = true; lat = b.min.lat(); }
+        else if(lat > b.max.lat()) {changed = true; lat = b.max.lat(); }
+        if(lon < b.min.lon()) {changed = true; lon = b.min.lon(); }
+        else if(lon > b.max.lon()) {changed = true; lon = b.max.lon(); }
+        if(changed)
+          newCenter = new CachedLatLon(lat, lon).getEastNorth();
         if (!newCenter.equals(center)) {
             EastNorth oldCenter = center;
@@ -169,4 +190,27 @@
             firePropertyChange("center", oldCenter, newCenter);
         }
+
+        int width = getWidth()/2;
+        int height = getHeight()/2;
+        LatLon l1 = new LatLon(b.min.lat(), lon);
+        LatLon l2 = new LatLon(b.max.lat(), lon);
+        EastNorth e1 = getProjection().latlon2eastNorth(l1);
+        EastNorth e2 = getProjection().latlon2eastNorth(l2);
+        double d = e2.north() - e1.north();
+        if(d < height*newScale)
+        {
+            double newScaleH = d/height;
+            e1 = getProjection().latlon2eastNorth(new LatLon(lat, b.min.lon()));
+            e2 = getProjection().latlon2eastNorth(new LatLon(lat, b.max.lon()));
+            d = e2.east() - e1.east();
+            if(d < width*newScale)
+                newScale = Math.max(newScaleH, d/width);
+        }
+        else
+        {
+            d = d/(l1.greatCircleDistance(l2)*height*10);
+            if(newScale < d)
+                newScale = d;
+        }
         if (scale != newScale) {
             double oldScale = scale;
@@ -175,4 +219,5 @@
             firePropertyChange("scale", oldScale, newScale);
         }
+
         if(rep) {
             repaint();
@@ -461,5 +506,5 @@
      * @return The projection to be used in calculating stuff.
      */
-    protected Projection getProjection() {
+    public Projection getProjection() {
         return Main.proj;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1822)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1823)
@@ -196,7 +196,7 @@
      */
     @Override public void paint(final Graphics g, final MapView mv) {
-        boolean active = Main.map.mapView.getActiveLayer() == this;
+        boolean active = mv.getActiveLayer() == this;
         boolean inactive = !active && Main.pref.getBoolean("draw.data.inactive_color", true);
-        boolean virtual = !inactive && Main.map.mapView.isVirtualNodesEnabled();
+        boolean virtual = !inactive && mv.isVirtualNodesEnabled();
 
         // draw the hatched area for non-downloaded region. only draw if we're the active
@@ -204,5 +204,5 @@
         if (active && Main.pref.getBoolean("draw.data.downloaded_area", true) && !data.dataSources.isEmpty()) {
             // initialize area with current viewport
-            Rectangle b = Main.map.mapView.getBounds();
+            Rectangle b = mv.getBounds();
             // on some platforms viewport bounds seem to be offset from the left,
             // over-grow it just to be sure
@@ -213,6 +213,6 @@
             for (DataSource src : data.dataSources) {
                 if (src.bounds != null && !src.bounds.min.equals(src.bounds.max)) {
-                    EastNorth en1 = Main.proj.latlon2eastNorth(src.bounds.min);
-                    EastNorth en2 = Main.proj.latlon2eastNorth(src.bounds.max);
+                    EastNorth en1 = mv.getProjection().latlon2eastNorth(src.bounds.min);
+                    EastNorth en2 = mv.getProjection().latlon2eastNorth(src.bounds.max);
                     Point p1 = mv.getPoint(en1);
                     Point p2 = mv.getPoint(en2);
@@ -536,5 +536,5 @@
     /**
      * replies the set of conflicts currently managed in this layer
-     * 
+     *
      * @return the set of conflicts currently managed in this layer
      */
