Index: trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 8616)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 8618)
@@ -16,4 +16,5 @@
 
 import org.openstreetmap.gui.jmapviewer.Coordinate;
+import org.openstreetmap.gui.jmapviewer.OsmMercator;
 import org.openstreetmap.gui.jmapviewer.Tile;
 import org.openstreetmap.gui.jmapviewer.TileXY;
@@ -39,4 +40,5 @@
     private final List<String> serverProjections;
     private EastNorth topLeftCorner;
+    private Bounds worldBounds;
 
     private static final String PATTERN_HEADER  = "\\{header\\(([^,]+),([^}]+)\\)\\}";
@@ -79,7 +81,7 @@
      */
     public void initProjection(Projection proj) {
-        Bounds bounds = proj.getWorldBoundsLatLon();
-        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
-        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
+        this.worldBounds = getWorldBounds();
+        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
+        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
         this.topLeftCorner = new EastNorth(min.east(), max.north());
     }
@@ -230,10 +232,6 @@
     @Override
     public int getTileXMax(int zoom) {
-        Projection proj = Main.getProjection();
-        double scale = getDegreesPerTile(zoom);
-        Bounds bounds = Main.getProjection().getWorldBoundsLatLon();
-        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
-        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
-        return (int) Math.ceil(Math.abs(max.getX() - min.getX()) / scale);
+        LatLon bottomRight = new LatLon(worldBounds.getMinLat(), worldBounds.getMaxLon());
+        return latLonToTileXY(bottomRight.toCoordinate(), zoom).getXIndex();
     }
 
@@ -245,10 +243,6 @@
     @Override
     public int getTileYMax(int zoom) {
-        Projection proj = Main.getProjection();
-        double scale = getDegreesPerTile(zoom);
-        Bounds bounds = Main.getProjection().getWorldBoundsLatLon();
-        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
-        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
-        return (int) Math.ceil(Math.abs(max.getY() - min.getY()) / scale);
+        LatLon bottomRight = new LatLon(worldBounds.getMinLat(), worldBounds.getMaxLon());
+        return latLonToTileXY(bottomRight.toCoordinate(), zoom).getYIndex();
     }
 
@@ -354,11 +348,8 @@
 
     private double getDegreesPerTile(int zoom) {
-        return getDegreesPerTile(zoom, Main.getProjection());
-    }
-
-    private double getDegreesPerTile(int zoom, Projection proj) {
-        Bounds bounds = proj.getWorldBoundsLatLon();
-        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
-        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
+        Projection proj = Main.getProjection();
+        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
+        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
+
         int tilesPerZoom = (int) Math.pow(2, zoom - 1);
         return Math.max(
@@ -368,4 +359,24 @@
     }
 
+    /**
+     * returns world bounds, but detect situation, when default bounds are provided (-90, -180, 90, 180), and projection
+     * returns very close values for both min and max X. To work around this problem, cap this projection on north and south
+     * pole, the same way they are capped in Mercator projection, so conversions should work properly
+     */
+    private final static Bounds getWorldBounds() {
+        Projection proj = Main.getProjection();
+        Bounds bounds = proj.getWorldBoundsLatLon();
+        EastNorth min = proj.latlon2eastNorth(bounds.getMin());
+        EastNorth max = proj.latlon2eastNorth(bounds.getMax());
+
+        if (Math.abs(min.getX() - max.getX()) < 1 && bounds.equals(new Bounds(new LatLon(-90, -180), new LatLon(90, 180)))) {
+            return new Bounds(
+                    new LatLon(OsmMercator.MIN_LAT, bounds.getMinLon()),
+                    new LatLon(OsmMercator.MAX_LAT, bounds.getMaxLon())
+                    );
+        }
+        return bounds;
+    }
+
     @Override
     public String getTileId(int zoom, int tilex, int tiley) {
