Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Cache.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Cache.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Cache.java	(revision 15091)
@@ -8,8 +8,8 @@
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Random;
 import java.util.Set;
 import java.util.TreeMap;
 import javax.imageio.*;
-
 
 import org.openstreetmap.josm.Main;
@@ -24,4 +24,6 @@
     // If the cache is full, we don't want to delete just one file
     private final int cleanUpThreshold = 20;
+    // After how many file-writes do we want to check if the cache needs emptying?
+    private final int cleanUpInterval = 5;
 
     Cache() {
@@ -73,5 +75,5 @@
         }
 
-        // Clean up must be called manually
+        checkCleanUp();
     }
 
@@ -79,4 +81,11 @@
         saveImg(ident, image);
         return image;
+    }
+
+    public void checkCleanUp() {
+        // The Cache class isn't persistent in its current implementation,
+        // therefore clean up on random intervals, but not every write
+        if(new Random().nextInt(cleanUpInterval) == 0)
+            cleanUp();
     }
 
@@ -112,5 +121,14 @@
     }
 
+    public void deleteSmallFiles(int size) {
+        if(disabled) return;
+        for(File f : getFiles()) {
+            if(f.length() < size)
+                f.delete();
+        }
+    }
+
     private long getDirSize() {
+        if(disabled) return -1;
         long dirsize = 0;
 
@@ -121,4 +139,5 @@
 
     private File[] getFiles() {
+        if(disabled) return null;
         return dir.listFiles(
             new FileFilter() {
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 15091)
@@ -1,4 +1,5 @@
 package wmsplugin;
 
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Graphics;
@@ -80,4 +81,6 @@
         // Zooming is still slow because the images need to be resized
         if(diffx >= 0 && diffx <= 2 && diffy >= 0 && diffy <= 2 && reImg != null) {
+            /*g.setColor(Color.RED);
+              g.drawRect(minPt.x, minPt.y-height, width, height);*/
             g.drawImage(reImg, minPt.x, maxPt.y, null);
             return true;
@@ -120,4 +123,6 @@
 
                 reImgHash.setSize(width, height);
+                /*g.setColor(Color.RED);
+                  g.drawRect(minPt.x, minPt.y-height, width, height);*/
                 g.drawImage(reImg, minPt.x, maxPt.y, null);
             }
@@ -153,15 +158,15 @@
 
     private Image clearAlpha(Image img) {
-		ImageProducer ip = img.getSource();
-		RGBImageFilter filter = new RGBImageFilter() {
-			public int filterRGB(int x, int y, int rgb) {
-				return rgb | 0xff000000;
-			}
-		};
-		ImageProducer filt_ip = new FilteredImageSource(ip, filter);
-		Image out_img = Toolkit.getDefaultToolkit().createImage(filt_ip);
+        ImageProducer ip = img.getSource();
+        RGBImageFilter filter = new RGBImageFilter() {
+            public int filterRGB(int x, int y, int rgb) {
+                return rgb | 0xff000000;
+            }
+        };
+        ImageProducer filt_ip = new FilteredImageSource(ip, filter);
+        Image out_img = Toolkit.getDefaultToolkit().createImage(filt_ip);
 
-		return out_img;
-	}
+        return out_img;
+    }
 
     public void flushedResizedCachedInstance() {
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 15091)
@@ -12,4 +12,5 @@
 import java.awt.Font;
 import javax.swing.JOptionPane;
+import org.openstreetmap.josm.data.coor.LatLon;
 
 abstract public class Grabber implements Runnable {
@@ -21,7 +22,26 @@
     protected GeorefImage image;
 
-    Grabber(Bounds b, Projection proj,
-            double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) {
-        this.b = b;
+    Grabber(Bounds b, Projection proj, double pixelPerDegree, GeorefImage image,
+    MapView mv, WMSLayer layer)
+    {
+        if (b.min != null && b.max != null && WMSPlugin.doOverlap)
+        {
+            double latCent = (b.min.lat() + b.max.lat()) / 2;
+            double lonCent = (b.min.lon() + b.max.lon()) / 2;
+
+            double latSize =  b.max.lat() - b.min.lat();
+            double lonSize =  b.max.lon() - b.min.lon();
+
+            double latCoef = (100.0 + WMSPlugin.overlapLat) / 100.0 / 2.0;
+            double lonCoef = (100.0 + WMSPlugin.overlapLon) / 100.0 / 2.0;
+
+            this.b = new Bounds( new LatLon(latCent - latCoef * latSize,
+                                            lonCent - lonCoef * lonSize),
+                                 new LatLon(latCent + latCoef * latSize,
+                                            lonCent + lonCoef * lonSize));
+        }
+        else
+            this.b = b;
+
         this.proj = proj;
         this.pixelPerDegree = pixelPerDegree;
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 15091)
@@ -42,5 +42,4 @@
  */
 public class WMSLayer extends Layer {
-
     protected static final Icon icon =
         new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
@@ -80,11 +79,12 @@
         mv = Main.map.mapView;
         getPPD();
-        
+
         executor = Executors.newFixedThreadPool(3);
     }
-    
+
+    @Override
     public void destroy() {
-        try { 
-            executor.shutdown();  
+        try {
+            executor.shutdown();
         // Might not be initalized, so catch NullPointer as well
         } catch(Exception x) {}
@@ -172,8 +172,9 @@
             return;
         }
-        
+
         for(int x = bminx; x<bmaxx; ++x)
             for(int y = bminy; y<bmaxy; ++y){
                 GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
+                g.drawRect(x, y, dax, bminy);
                 if(!img.paint(g, mv, dx, dy) && !img.downloadingStarted){
                     img.downloadingStarted = true;
@@ -184,6 +185,4 @@
             }
         }
-
-        new wmsplugin.Cache().cleanUp();
     }
 
@@ -248,5 +247,5 @@
         }
     }
-    
+
     public class reloadErrorTilesAction extends AbstractAction {
         public reloadErrorTilesAction() {
@@ -254,4 +253,8 @@
         }
         public void actionPerformed(ActionEvent ev) {
+            // Delete small files, because they're probably blank tiles.
+            // See https://josm.openstreetmap.de/ticket/2307
+            new wmsplugin.Cache().deleteSmallFiles(2048);
+
             for (int x = 0; x < dax; ++x) {
                 for (int y = 0; y < day; ++y) {
@@ -266,5 +269,5 @@
         }
     }
-    
+
     public class ToggleAlphaAction extends AbstractAction {
         public ToggleAlphaAction() {
@@ -275,5 +278,5 @@
             boolean alphaChannel = checkbox.isSelected();
             Main.pref.put("wmsplugin.alpha_channel", alphaChannel);
-            
+
             // clear all resized cached instances and repaint the layer
             for (int x = 0; x < dax; ++x) {
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java	(revision 15091)
@@ -37,4 +37,8 @@
     static ArrayList<WMSInfo> wmsList = new ArrayList<WMSInfo>();
     static TreeMap<String,String> wmsListDefault = new TreeMap<String,String>();
+
+    static boolean doOverlap = false;
+    static int overlapLat = 4;
+    static int overlapLon = 14;
 
     // remember state of menu item to restore on changed preferences
@@ -77,4 +81,20 @@
 
         TreeSet<String> keys = new TreeSet<String>(prefs.keySet());
+
+        // Here we load the settings for "overlap" checkbox and spinboxes.
+
+        try {
+            doOverlap = Boolean.valueOf(prefs.get("wmsplugin.url.overlap"));
+        } catch (Exception e) {} // If sth fails, we drop to default settings.
+
+        try {
+            overlapLat = Integer.valueOf(prefs.get("wmsplugin.url.overlapLat"));
+        } catch (Exception e) {} // If sth fails, we drop to default settings.
+
+        try {
+            overlapLon = Integer.valueOf(prefs.get("wmsplugin.url.overlapLon"));
+        } catch (Exception e) {} // If sth fails, we drop to default settings.
+
+        // And then the names+urls of WMS servers
         int prefid = 0;
         String name = null;
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPreferenceEditor.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPreferenceEditor.java	(revision 15053)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPreferenceEditor.java	(revision 15091)
@@ -1,4 +1,10 @@
 package wmsplugin;
 
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import org.openstreetmap.josm.Main;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -9,5 +15,4 @@
 import java.util.HashMap;
 import java.util.Map;
-
 
 import javax.swing.Box;
@@ -21,5 +26,4 @@
 import javax.swing.table.DefaultTableModel;
 
-
 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
@@ -27,8 +31,11 @@
 
 public class WMSPreferenceEditor implements PreferenceSetting {
-
     private Map<String,String> orig;
     private DefaultTableModel model;
     private HashMap<Integer, WMSInfo> oldValues = new HashMap<Integer, WMSInfo>();
+
+    JCheckBox overlapCheckBox;
+    JSpinner spinLat;
+    JSpinner spinLon;
 
     public void addGui(final PreferenceDialog gui) {
@@ -59,7 +66,8 @@
         }
 
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+
         JButton add = new JButton(tr("Add"));
-        p.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
-        p.add(add, GBC.std().insets(0,5,0,0));
+        buttonPanel.add(add, GBC.std().insets(0,5,0,0));
         add.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e) {
@@ -79,5 +87,5 @@
 
         JButton delete = new JButton(tr("Delete"));
-        p.add(delete, GBC.std().insets(0,5,0,0));
+        buttonPanel.add(delete, GBC.std().insets(0,5,0,0));
         delete.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e) {
@@ -94,5 +102,5 @@
 
         JButton copy = new JButton(tr("Copy Default"));
-        p.add(copy, GBC.std().insets(0,5,0,0));
+        buttonPanel.add(copy, GBC.std().insets(0,5,0,0));
         copy.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e) {
@@ -107,4 +115,22 @@
             }
         });
+
+        p.add(buttonPanel);
+        p.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
+
+        overlapCheckBox = new JCheckBox(tr("Overlap tiles"), WMSPlugin.doOverlap );
+        JLabel labelLat = new JLabel(tr("% of lat:"));
+        JLabel labelLon = new JLabel(tr("% of lon:"));
+        spinLat = new JSpinner(new SpinnerNumberModel(WMSPlugin.overlapLat, 1, 50, 1));
+        spinLon = new JSpinner(new SpinnerNumberModel(WMSPlugin.overlapLon, 1, 50, 1));
+
+        JPanel overlapPanel = new JPanel(new FlowLayout());
+        overlapPanel.add(overlapCheckBox);
+        overlapPanel.add(labelLat);
+        overlapPanel.add(spinLat);
+        overlapPanel.add(labelLon);
+        overlapPanel.add(spinLon);
+
+        p.add(overlapPanel);
     }
 
@@ -145,4 +171,13 @@
 
         if (change) WMSPlugin.refreshMenu();
+
+        WMSPlugin.doOverlap = overlapCheckBox.getModel().isSelected();
+        WMSPlugin.overlapLat = (Integer) spinLat.getModel().getValue();
+        WMSPlugin.overlapLon = (Integer) spinLon.getModel().getValue();
+
+        Main.pref.put("wmsplugin.url.overlap",    String.valueOf(WMSPlugin.doOverlap));
+        Main.pref.put("wmsplugin.url.overlapLat", String.valueOf(WMSPlugin.overlapLat));
+        Main.pref.put("wmsplugin.url.overlapLon", String.valueOf(WMSPlugin.overlapLon));
+
         return false;
     }
