Index: src/org/openstreetmap/josm/gui/layer/WMSLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 5967)
+++ src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(working copy)
@@ -20,6 +20,7 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -106,7 +107,8 @@
     public static final IntegerProperty PROP_IMAGE_SIZE = new IntegerProperty("imagery.wms.imageSize", 500);
 
     public int messageNum = 5; //limit for messages per layer
-    protected String resolution;
+    protected double resolution;
+    protected String resolutionText;
     protected int imageSize;
     protected int dax = 10;
     protected int day = 10;
@@ -116,6 +118,7 @@
     protected GeorefImage[][] images;
     protected final int serializeFormatVersion = 5;
     protected boolean autoDownloadEnabled = true;
+    protected boolean autoResolutionEnabled = true;
     protected boolean settingsChanged;
     public WmsCache cache;
     private AttributionSupport attribution = new AttributionSupport();
@@ -179,11 +182,12 @@
                 cache.loadIndex();
             }
         }
-        if(this.info.getPixelPerDegree() == 0.0) {
-            this.info.setPixelPerDegree(getPPD());
-        }
-        resolution = Main.map.mapView.getDist100PixelText();
 
+        // if automatic resolution is enabled, ensure that the first zoom level
+        // is already snapped. Otherwise it may load tiles that will never get
+        // used again when zooming.
+        updateResolutionSetting(this, autoResolutionEnabled);
+
         final MouseAdapter adapter = new MouseAdapter() {
             @Override
             public void mouseClicked(MouseEvent e) {
@@ -286,9 +290,9 @@
 
     @Override public String getToolTipText() {
         if(autoDownloadEnabled)
-            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
+            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolutionText);
         else
-            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
+            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolutionText);
     }
 
     private int modulo (int a, int b) {
@@ -300,9 +304,28 @@
         return info.getPixelPerDegree() / getPPD() > minZoom;
     }
 
+
+    private ArrayList<Double> usedResos = new ArrayList<Double>();// FIXME: debug
+
+
     @Override public void paint(Graphics2D g, final MapView mv, Bounds b) {
         if(info.getUrl() == null || (usesInvalidUrl && !isInvalidUrlConfirmed)) return;
 
+        if (autoResolutionEnabled) {
+            double pixelScaling = mv.getDist100Pixel() / resolution;
+            System.out.println("pixelSacling: " + pixelScaling + "     reso is: " + resolution); // FIXME: debug
+            if (pixelScaling > 2 || pixelScaling < 0.7) {
+                System.out.println("CHANING RESO ---------- "); // FIXME: debug
+                Collections.sort(usedResos);
+                System.out.println(Arrays.toString(usedResos.toArray()));
+                changeResolution(this, true);
+            }
+        }
+        // FIXME: debug
+        if(!usedResos.contains(this.resolution)) {
+            usedResos.add(this.resolution);
+        }
+
         settingsChanged = false;
 
         ProjectionBounds bounds = mv.getProjectionBounds();
@@ -477,10 +500,11 @@
                 new LayerSaveAsAction(this),
                 new BookmarkWmsAction(),
                 SeparatorLayerAction.INSTANCE,
-                new ZoomToNativeResolution(),
                 new StartStopAction(),
                 new ToggleAlphaAction(),
+                new ToggleAutoResolutionAction(),
                 new ChangeResolutionAction(),
+                new ZoomToNativeResolution(),
                 new ReloadErrorTilesAction(),
                 new DownloadAction(),
                 SeparatorLayerAction.INSTANCE,
@@ -666,22 +690,57 @@
         }
     }
 
-    public static class ChangeResolutionAction extends AbstractAction implements LayerAction {
-        public ChangeResolutionAction() {
-            super(tr("Change resolution"));
+    /**
+     * Updates the given layer’s resolution settings to the current zoom level. Does
+     * not update existing tiles, only new ones will be subject to the new settings.
+     *
+     * @param layer
+     * @param round  Set to true if the resolution should snap to certain values instead of
+     *               matching the current zoom level perfectly
+     */
+    private static void updateResolutionSetting(WMSLayer layer, boolean round) {
+        if(round) {
+            layer.resolution = Math.round(Main.map.mapView.getDist100Pixel());
+            layer.resolutionText = MapView.getDistText(layer.resolution);
+        } else {
+            layer.resolution = Main.map.mapView.getDist100Pixel();
+            layer.resolutionText = Main.map.mapView.getDist100PixelText();
         }
+        layer.info.setPixelPerDegree(layer.getPPD());
+    }
 
-        private void changeResolution(WMSLayer layer) {
-            layer.resolution = Main.map.mapView.getDist100PixelText();
-            layer.info.setPixelPerDegree(layer.getPPD());
-            layer.settingsChanged = true;
+    /**
+     * Updates the given layer’s resolution settings to the current zoom level and
+     * updates existing tiles. If round is true, tiles will be updated gradually, if
+     * false they will be removed instantly (and redrawn only after the new resolution
+     * image has been loaded).
+     * @param layer
+     * @param round  Set to true if the resolution should snap to certain values instead of
+     *               matching the current zoom level perfectly
+     */
+    private static void changeResolution(WMSLayer layer, boolean round) {
+        updateResolutionSetting(layer, round);
+
+        layer.settingsChanged = true;
+
+        // Don’t move tiles off screen when the resolution is rounded. This
+        // prevents some flickering when zooming with auto-resolution enabled
+        // and instead gradually updates each tile.
+        if(!round) {
             for(int x = 0; x<layer.dax; ++x) {
                 for(int y = 0; y<layer.day; ++y) {
                     layer.images[x][y].changePosition(-1, -1);
                 }
             }
         }
+    }
 
+
+    public static class ChangeResolutionAction extends AbstractAction implements LayerAction {
+        public ChangeResolutionAction() {
+            super(tr("Change resolution"));
+        }
+
         @Override
         public void actionPerformed(ActionEvent ev) {
 
@@ -690,7 +749,7 @@
 
             List<Layer> layers = LayerListDialog.getInstance().getModel().getSelectedLayers();
             for (Layer l: layers) {
-                changeResolution((WMSLayer) l);
+                changeResolution((WMSLayer) l, false);
             }
             Main.map.mapView.repaint();
         }
@@ -767,6 +826,31 @@
         }
     }
 
+
+    public class ToggleAutoResolutionAction extends AbstractAction implements LayerAction {
+        public ToggleAutoResolutionAction() {
+            super(tr("Automatically change resolution"));
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent ev) {
+            JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
+            autoResolutionEnabled = checkbox.isSelected();
+        }
+
+        @Override
+        public Component createMenuComponent() {
+            JCheckBoxMenuItem item = new JCheckBoxMenuItem(this);
+            item.setSelected(autoResolutionEnabled);
+            return item;
+        }
+
+        @Override
+        public boolean supportLayers(List<Layer> layers) {
+            return layers.size() == 1 && layers.get(0) instanceof WMSLayer;
+        }
+    }
+
     /**
      * This action will add a WMS layer menu entry with the current WMS layer
      * URL and name extended by the current resolution.
