Index: /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 10683)
+++ /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 10684)
@@ -1,5 +1,75 @@
 package wmsplugin;
 
-public interface Grabber extends Runnable {
-	
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.Main;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import java.awt.Color;
+import java.awt.Font;
+import javax.swing.JOptionPane;
+
+abstract public class Grabber implements Runnable {
+	protected Bounds b;
+	protected Projection proj;
+	protected double pixelPerDegree;
+	protected MapView mv;
+	protected WMSLayer layer;
+	protected GeorefImage image;
+
+	Grabber(Bounds b, Projection proj,
+			double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) {
+		this.b = b;
+		this.proj = proj;
+		this.pixelPerDegree = pixelPerDegree;
+		this.image = image;
+		this.mv = mv;
+		this.layer = layer;
+	}
+
+	abstract void fetch() throws Exception; // the image fetch code
+
+	int width(){
+		return (int) ((b.max.lon() - b.min.lon()) * pixelPerDegree);
+	}
+	int height(){
+		return (int) ((b.max.lat() - b.min.lat()) * pixelPerDegree);
+	}
+
+	protected void grabError(Exception e){ // report error when grabing image
+		e.printStackTrace();
+		
+		BufferedImage img = new BufferedImage(width(), height(), BufferedImage.TYPE_INT_ARGB);
+		Graphics g = img.getGraphics();
+		g.setColor(Color.RED);
+		g.fillRect(0, 0, width(), height());
+		Font font = g.getFont();
+		Font tempFont = font.deriveFont(Font.PLAIN).deriveFont(36.0f);
+		g.setFont(tempFont);
+		g.setColor(Color.BLACK);
+		g.drawString(e.getClass().getSimpleName() + " occured", 10, height()/2);
+		image.image = img;
+		g.setFont(font);
+	}
+
+	protected void attempt(){ // try to fetch the image
+		int maxTries = 5; // n tries for every image
+		for (int i = 1; i <= maxTries; i++) {
+			try {
+				fetch();
+				break; // break out of the retry loop
+			} catch (Exception e) {
+				try { // sleep some time and then ask the server again
+					Thread.sleep(random(1000, 2000));
+				} catch (InterruptedException e1) {}
+
+				if(i == maxTries) grabError(e);
+			}
+		}
+	}
+
+	public static int random(int min, int max) {
+	    return (int)(Math.random() * ((max+1)-min) ) + min;
+	}
 }
Index: /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 10683)
+++ /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 10684)
@@ -1,19 +1,19 @@
 package wmsplugin;
 
-import static org.openstreetmap.josm.tools.I18n.tr;
-
 import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;
 import java.util.Locale;
-import java.util.ArrayList;
 
 import javax.imageio.ImageIO;
-import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
@@ -24,52 +24,35 @@
 
 
-public class WMSGrabber implements Grabber {
+public class WMSGrabber extends Grabber {
 	protected String baseURL;
 
-	protected Bounds b;
-	protected Projection proj;
-	protected double pixelPerDegree;
-	protected GeorefImage image;
-	protected MapView mv;
-	protected WMSLayer layer;
-
-	WMSGrabber(String _baseURL, Bounds _b, Projection _proj,
-			double _pixelPerDegree, GeorefImage _image, MapView _mv, WMSLayer _layer) {
-		this.baseURL = _baseURL;
-		b = _b;
-		proj = _proj;
-		pixelPerDegree = _pixelPerDegree;
-		image = _image;
-		mv = _mv;
-		layer = _layer;
+	WMSGrabber(String baseURL, Bounds b, Projection proj,
+			double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) {
+		super(b, proj, pixelPerDegree, image, mv, layer);
+		this.baseURL = baseURL;
 	}
 
 	public void run() {
+		attempt();
+		mv.repaint();
+	}
+
+	void fetch() throws Exception{
+		URL url = null;
+		try {
+			url = getURL(
+				b.min.lon(), b.min.lat(),
+				b.max.lon(), b.max.lat(),
+				width(), height());
 			
-			int w = (int) ((b.max.lon() - b.min.lon()) * pixelPerDegree);
-			int h = (int) ((b.max.lat() - b.min.lat()) * pixelPerDegree);
+			image.min = proj.latlon2eastNorth(b.min);
+			image.max = proj.latlon2eastNorth(b.max);
 
-			try {
-				URL url = getURL(
-					b.min.lon(), b.min.lat(),
-					b.max.lon(), b.max.lat(),
-					w, h);
-
-				image.min = proj.latlon2eastNorth(b.min);
-				image.max = proj.latlon2eastNorth(b.max);
-
+			if(image.isVisible(mv)) //don't download, if the image isn't visible already
 				image.image = grab(url);
-				image.downloadingStarted = false;
-
-				mv.repaint();
-			}
-			catch (MalformedURLException e) {
-				if(layer.messageNum-- > 0)
-					JOptionPane.showMessageDialog(Main.parent,tr("WMSPlugin: Illegal url.\n{0}",e.getMessage()));
-			}
-			catch (IOException e) {
-				if(layer.messageNum-- > 0)
-					JOptionPane.showMessageDialog(Main.parent,tr("WMSPlugin: IO exception.\n{0}",e.getMessage()));
-			}
+			image.downloadingStarted = false;
+		} catch(Exception e) {
+			throw new Exception(e.getMessage() + "\nImage couldn't be fetched: " + (url != null ? url.toString() : ""));
+		}
 	}
 
@@ -90,11 +73,29 @@
 
 	protected BufferedImage grab(URL url) throws IOException {
-		InputStream is = new ProgressInputStream(
-			url.openConnection(), null);
-		if(!image.isVisible(mv))
-			return null;
+		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+		
+		String contentType = conn.getHeaderField("Content-Type");
+		if( conn.getResponseCode() != 200 
+				|| contentType != null && !contentType.startsWith("image") ) {
+			throw new IOException(readException(conn));
+		}
+		
+		InputStream is = new ProgressInputStream(conn, null);
 		BufferedImage img = ImageIO.read(is);
 		is.close();
 		return img;
 	}
+
+	protected String readException(URLConnection conn) throws IOException {
+		StringBuilder exception = new StringBuilder();
+		InputStream in = conn.getInputStream();
+		BufferedReader br = new BufferedReader(new InputStreamReader(in));
+		
+		String line = null;
+		while( (line = br.readLine()) != null) {
+			exception.append(line);
+			exception.append('\n');
+		}
+		return exception.toString();
+	}
 }
Index: /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 10683)
+++ /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 10684)
@@ -6,5 +6,4 @@
 import java.awt.Component;
 import java.awt.Graphics;
-import java.awt.Point;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
@@ -12,8 +11,6 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.ArrayList;
 
 import javax.swing.AbstractAction;
@@ -29,11 +26,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
-import org.openstreetmap.josm.actions.SaveActionBase;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
-import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.MapView;
-import java.util.ArrayList;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
Index: /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java	(revision 10683)
+++ /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java	(revision 10684)
@@ -4,104 +4,32 @@
 
 import java.awt.image.BufferedImage;
+import java.awt.Image;
+import java.net.URL;
+import java.util.ArrayList;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.BufferedReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.Locale;
-import java.util.ArrayList;
 
-import java.awt.*;
-import java.awt.image.*;
-import java.io.*;
-import java.net.*;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.StringTokenizer;
 
 import javax.imageio.ImageIO;
-import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.io.ProgressInputStream;
 import org.openstreetmap.josm.gui.MapView;
 
 
-public class YAHOOGrabber implements Grabber{
-	protected String baseURL;
+public class YAHOOGrabber extends WMSGrabber{
 	protected String browserCmd;
 
-	protected Bounds b;
-	protected Projection proj;
-	protected double pixelPerDegree;
-	protected GeorefImage image;
-	protected MapView mv;
-	protected WMSLayer layer;
-	protected int width, height;
-
-	YAHOOGrabber(String _baseURL, Bounds _b, Projection _proj,
-			double _pixelPerDegree, GeorefImage _image, MapView _mv, WMSLayer _layer) {
-		this.baseURL = "file://" + Main.pref.getPreferencesDir() + "plugins/wmsplugin/ymap.html?request=getmap&format=image/jpeg";
-		this.browserCmd = _baseURL.replaceFirst("yahoo://", "");
-		this.b = _b;
-		this.proj = _proj;
-		this.pixelPerDegree = _pixelPerDegree;
-		this.image = _image;
-		this.mv = _mv;
-		this.layer = _layer;
+	YAHOOGrabber(String baseURL, Bounds b, Projection proj,
+			double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) {
+		super("file://" + Main.pref.getPreferencesDir() + "plugins/wmsplugin/ymap.html?request=getmap&format=image/jpeg", b, proj, pixelPerDegree, image, mv, layer);
+		this.browserCmd = baseURL.replaceFirst("yahoo://", "");
 	}
 
-	public void run() {
-			Image img;
-			
-			width = (int) ((b.max.lon() - b.min.lon()) * pixelPerDegree);
-			height = (int) ((b.max.lat() - b.min.lat()) * pixelPerDegree);
-
-			try {
-				URL url = getURL(
-					b.min.lon(), b.min.lat(),
-					b.max.lon(), b.max.lat(),
-					width, height);
-
-				image.min = proj.latlon2eastNorth(b.min);
-				image.max = proj.latlon2eastNorth(b.max);
-				if(!image.isVisible(mv)){ //don't download, if the image isn't visible already
-					image.downloadingStarted = false;
-					return;
-				}
-				Process browser = browse(url.toString());;
-				image.image =  new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-				img = ImageIO.read(browser.getInputStream()).getScaledInstance(width, height, Image.SCALE_FAST);
-				image.image.getGraphics().drawImage(img, 0 , 0, null);
-
-				image.downloadingStarted = false;
-
-				mv.repaint();
-			}
-			catch (MalformedURLException e) {
-				if(layer.messageNum-- > 0)
-					JOptionPane.showMessageDialog(Main.parent,tr("WMSPlugin (YAHOOGrabber): Illegal url.\n{0}",e.getMessage()));
-			}
-			catch (IOException e) {
-				if(layer.messageNum-- > 0)
-					JOptionPane.showMessageDialog(Main.parent,tr("WMSPlugin (YAHOOGrabber): IO exception.\n{0}",e.getMessage()));
-			}
-			catch (NullPointerException e) {
-				if(layer.messageNum-- > 0)
-					JOptionPane.showMessageDialog(Main.parent,tr("WMSPlugin (YAHOOGrabber): Null pointer exception.\n{0}",e.getMessage()));
-			}
-	}
-
-
-	protected Process browse(String url) throws IOException {
+	protected BufferedImage grab(URL url) throws IOException {
 		ArrayList<String> cmdParams = new ArrayList<String>();
 		
-		StringTokenizer st = new StringTokenizer(tr(browserCmd, url));
+		StringTokenizer st = new StringTokenizer(tr(browserCmd, url.toString()));
 		while( st.hasMoreTokens() ) 
 			cmdParams.add(st.nextToken());
@@ -110,26 +38,17 @@
 		ProcessBuilder builder = new ProcessBuilder( cmdParams);
 
+
+		Process browser;
 		try {
-			return builder.start();
+			browser = builder.start();
 		}
 		catch(IOException ioe) {
-			throw new IOException( tr("Could not start browser. Please check that the executable path is correct."));
+			throw new IOException( "Could not start browser. Please check that the executable path is correct.\n" + ioe.getMessage() );
 		}
+
+		BufferedImage i =  new BufferedImage(width(), height(), BufferedImage.TYPE_INT_RGB);
+		Image img = ImageIO.read(browser.getInputStream()).getScaledInstance(width(), height(), Image.SCALE_FAST);
+		i.getGraphics().drawImage(img, 0 , 0, null);
+		return i;
 	}
-
-	protected static final NumberFormat
-		latLonFormat = new DecimalFormat("###0.0000000",
-			new DecimalFormatSymbols(Locale.US));
-
-	protected URL getURL(double w, double s,double e,double n,
-			int wi, int ht) throws MalformedURLException {
-		String str = baseURL + "&bbox="
-			+ latLonFormat.format(w) + ","
-			+ latLonFormat.format(s) + ","
-			+ latLonFormat.format(e) + ","
-			+ latLonFormat.format(n)
-			+ "&width=" + wi + "&height=" + ht;
-		return new URL(str.replace(" ", "%20"));
-	}
-
 }
