Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/DownloadWMSTask.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/DownloadWMSTask.java	(revision 6776)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/DownloadWMSTask.java	(revision 6777)
@@ -8,4 +8,5 @@
 import org.openstreetmap.josm.actions.DownloadAction;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -16,17 +17,17 @@
 	private WMSLayer wmsLayer;
 	private Bounds bounds;
+	private double pixelPerDegree;
 	
-	public DownloadWMSTask(WMSLayer wmsLayer, Bounds bounds) {
+	public DownloadWMSTask(WMSLayer wmsLayer, Bounds bounds, double pixelPerDegree) {
 		super(tr("Downloading " + wmsLayer.name));
 
 		this.wmsLayer = wmsLayer;
 		this.bounds = bounds;
+		this.pixelPerDegree = pixelPerDegree;
 	}
 	
 	@Override public void realRun() throws IOException {
 		Main.pleaseWaitDlg.currentAction.setText(tr("Contacting WMS Server..."));
-		wmsLayer.grab(
-			bounds.min.lat(), bounds.min.lon(),
-			bounds.max.lat(), bounds.max.lon());
+		wmsLayer.grab(bounds, pixelPerDegree);
 	}
 
@@ -35,5 +36,5 @@
 
 	public static void download(String name, String wmsurl,
-			double minlat, double minlon, double maxlat, double maxlon) {
+			Bounds b, double pixelPerDegree) {
 		WMSLayer wmsLayer = null;
 
@@ -45,16 +46,25 @@
 		}
 
+		// FIXME: move this to WMSPlugin/WMSInfo/preferences.
 		if (wmsLayer == null) {
 			if (wmsurl.matches("(?i).*layers=npeoocmap.*") || wmsurl.matches("(?i).*layers=npe.*") ){
-				//then we use the OSGBLayer
-				wmsLayer= new OSGBLayer(name, wmsurl);
+				wmsLayer = new WMSLayer(name, new OSGBGrabber(wmsurl));
 			} else {
-				wmsLayer = new WMSLayer(name, wmsurl); 
+				wmsLayer = new WMSLayer(name, new WMSGrabber(wmsurl));
 			}
 			Main.main.addLayer(wmsLayer);
 		} 
 
-		Main.worker.execute(new DownloadWMSTask(wmsLayer,
-			new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon))));
+		Main.worker.execute(new DownloadWMSTask(wmsLayer, b, pixelPerDegree));
+	}
+
+	public static void download(String name, String wmsurl) {
+		MapView mv = Main.map.mapView;
+
+		Bounds b = new Bounds(
+			mv.getLatLon(0, mv.getHeight()),
+			mv.getLatLon(mv.getWidth(), 0));
+
+		download(name, wmsurl, b, mv.getWidth() / (b.max.lon() - b.min.lon()));
 	}
 }
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 6777)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 6777)
@@ -0,0 +1,60 @@
+package wmsplugin;
+
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import javax.imageio.ImageIO;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.gui.NavigatableComponent;
+
+public class GeorefImage implements Serializable {
+	public BufferedImage image;
+	public EastNorth min, max;
+
+	public GeorefImage(BufferedImage img, EastNorth min, EastNorth max) {
+		image = img;
+		this.min = min;
+		this.max = max;
+	}
+
+	public void displace(double dx, double dy) {
+		min = new EastNorth(min.east() + dx, min.north() + dy);
+		max = new EastNorth(max.east() + dx, max.north() + dy);
+	}
+
+	public boolean contains(EastNorth en) {
+		return min.east() <= en.east() && en.east() <= max.east()
+			&& min.north() <= en.north() && en.north() <= max.north();
+	}
+
+	public void paint(Graphics g, NavigatableComponent nc) {
+		Point minPt = nc.getPoint(min), maxPt = nc.getPoint(max);
+
+		if (!g.hitClip(minPt.x, maxPt.y,
+				maxPt.x - minPt.x, minPt.y - maxPt.y))
+			return;
+
+		g.drawImage(image,
+			minPt.x, maxPt.y, maxPt.x, minPt.y, // dest
+			0, 0, image.getWidth(), image.getHeight(), // src
+			null);
+	}
+
+	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+		max = (EastNorth) in.readObject();
+		min = (EastNorth) in.readObject();
+		image = (BufferedImage) ImageIO.read(ImageIO.createImageInputStream(in));
+	}
+	
+	private void writeObject(ObjectOutputStream out) throws IOException {
+		out.writeObject(max);
+		out.writeObject(min);
+		ImageIO.write(image, "png", ImageIO.createImageOutputStream(out));
+	}
+}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 6777)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 6777)
@@ -0,0 +1,10 @@
+package wmsplugin;
+import java.io.IOException;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.projection.Projection;
+
+public interface Grabber {
+	public GeorefImage grab(Bounds bounds,
+		Projection proj, double pixelPerDegree)
+		throws IOException;
+}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Map_Rectifier_WMSmenuAction.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Map_Rectifier_WMSmenuAction.java	(revision 6776)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Map_Rectifier_WMSmenuAction.java	(revision 6777)
@@ -7,5 +7,4 @@
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.MapView;
-
 
 public class Map_Rectifier_WMSmenuAction extends JosmAction {
@@ -18,44 +17,15 @@
 	public Map_Rectifier_WMSmenuAction() {
 		super("Rectified Image ...", "OLmarker", "Download Rectified Image from Metacarta's Map Rectifer WMS", 0, 0, false);
-
-
 	}
 
 	public void actionPerformed(ActionEvent e) {
+		String newid = JOptionPane.showInputDialog(Main.parent, "Metacarta Map Rectifier image id");
 
-		//String newid;
-		String newURL = "";
-		String newid = "";
+		if (newid != null && !newid.equals("")) {
+			String newURL = "http://labs.metacarta.com/rectifier/wms.cgi?id="+newid+
+			"&srs=EPSG:4326&Service=WMS&Version=1.1.0&Request=GetMap&format=image/png";
 
-		newid = JOptionPane.showInputDialog(Main.parent, "Metacarta Map Rectifier image id ");
-	//	System.out.println("newid= " +newid);
-		if (newid != null){
-
-
-			if (newid.compareTo("") != 0) 
-			{
-				newURL = "http://labs.metacarta.com/rectifier/wms.cgi?id="+newid+
-				"&srs=EPSG:4326&Service=WMS&Version=1.1.0&Request=GetMap&format=image/png";
-
-
-				//System.out.println(newURL);
-
-				MapView mv = Main.map.mapView;
-
-				DownloadWMSTask.download("rectifier id="+newid, newURL,
-						mv.getLatLon(0, mv.getHeight()).lat(),
-						mv.getLatLon(0, mv.getHeight()).lon(),
-						mv.getLatLon(mv.getWidth(), 0).lat(),
-						mv.getLatLon(mv.getWidth(), 0).lon());			
-
-
-			}
+			DownloadWMSTask.download("rectifier id="+newid, newURL);
 		}
-		//else do nuffink
-
 	}
-
-
-
 }
-
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java	(revision 6777)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java	(revision 6777)
@@ -0,0 +1,62 @@
+package wmsplugin;
+
+import uk.me.jstott.jcoord.OSRef;
+import uk.me.jstott.jcoord.LatLng;
+
+import java.io.IOException;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Epsg4326;
+
+// FIXME: Remove this hack when we have proper projection support.
+public class OSGBGrabber extends WMSGrabber {
+	public OSGBGrabber(String baseURL) {
+		super(baseURL);
+	}
+
+	private Epsg4326 latlonProj = new Epsg4326();
+
+	@Override public GeorefImage grab(Bounds b, Projection proj,
+			double pixelPerDegree) throws IOException {
+		Bounds bnew = toOSGB(b);
+		double pixelPerDegreeNew =
+			pixelPerDegree / (bnew.max.lon() - bnew.min.lon())
+				* (b.max.lon() - b.min.lon());
+
+		GeorefImage img = super.grab(bnew, latlonProj, pixelPerDegreeNew);
+
+		img.min = proj.latlon2eastNorth(fromOSGB(img.min));
+		img.max = proj.latlon2eastNorth(fromOSGB(img.max));
+
+		return img;
+	}
+
+	protected static Bounds toOSGB(Bounds b) {
+		LatLng[] lls = new LatLng[] {
+			new LatLng(b.min.lat(), b.min.lon()),
+			new LatLng(b.min.lat(), b.max.lon()),
+			new LatLng(b.max.lat(), b.min.lon()),
+			new LatLng(b.max.lat(), b.max.lon()) };
+
+		for (LatLng ll : lls) ll.toOSGB36();
+
+		OSRef[] grs = new OSRef[lls.length];
+		for (int i = 0; i < lls.length; i++) grs[i] = lls[i].toOSRef();
+
+		LatLon latlon = new LatLon(grs[0].getNorthing(), grs[0].getEasting());
+		Bounds bnew = new Bounds(latlon, latlon);
+		for (int i = 1; i < grs.length; i++)
+			bnew.extend(new LatLon(grs[i].getNorthing(), grs[i].getEasting()));
+
+		return bnew;
+	}
+
+	protected static LatLon fromOSGB(EastNorth en) {
+		LatLng ll = new OSRef(en.east(), en.north()).toLatLng();
+		ll.toWGS84();
+		return new LatLon(ll.getLat(), ll.getLng());
+	}
+}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBImage.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBImage.java	(revision 6776)
+++ 	(revision )
@@ -1,153 +1,0 @@
-package wmsplugin;
-
-import uk.me.jstott.jcoord.OSRef;
-import uk.me.jstott.jcoord.LatLng;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.gui.NavigatableComponent;
-
-import java.awt.Graphics2D;
-import java.awt.BasicStroke;
-import java.awt.Point;
-import java.awt.Graphics;
-import java.awt.Color;
-
-public class OSGBImage extends WMSImage
-{
-	public OSGBImage(String constURL)
-	{
-		super(constURL);
-	}
-
-	public void grab(NavigatableComponent nc,double minlat,double minlon,
-			double maxlat,double maxlon) throws IOException
-	{
-		// To deal with the fact that grid refs and lat/lon don't align
-		LatLng ll1 = new LatLng(minlat,minlon),
-				ll2 = new LatLng(maxlat,maxlon),
-				ll3 = new LatLng(maxlat,minlon),
-				ll4 = new LatLng(minlat,maxlon);
-
-		ll1.toOSGB36();
-		ll2.toOSGB36();
-		ll3.toOSGB36();
-		ll4.toOSGB36();
-
-		OSRef bottomLeftGR = ll1.toOSRef(),
-			  topRightGR = ll2.toOSRef(),
-		 	topLeftGR =  ll3.toOSRef(),
-			  bottomRightGR =  ll4.toOSRef();
-
-		double w = Math.min(bottomLeftGR.getEasting(),
-								topLeftGR.getEasting()),
-			   s = Math.min(bottomLeftGR.getNorthing(),
-							   bottomRightGR.getNorthing()),
-			   e = Math.max(bottomRightGR.getEasting(),
-							   topRightGR.getEasting()),
-			   n = Math.max(topLeftGR.getNorthing(),
-							   topRightGR.getNorthing());
-
-		// Adjust topLeft and bottomRight due to messing around with
-		// projections
-		LatLng tl2 = new OSRef(w,n).toLatLng();
-		LatLng br2 = new OSRef(e,s).toLatLng();
-		tl2.toWGS84();
-		br2.toWGS84();
-
-		topLeft = Main.proj.latlon2eastNorth
-					(new LatLon(tl2.getLat(),tl2.getLng() ));
-		bottomRight = Main.proj.latlon2eastNorth
-					(new LatLon(br2.getLat(),br2.getLng() ));
-
-		grabbedScale = nc.getScale(); // enPerPixel
-
-		int widthPx = (int)((bottomRight.east()-topLeft.east())/grabbedScale),
-			heightPx = (int)
-				((topLeft.north()-bottomRight.north()) / grabbedScale);
-
-		try
-		{
-			URL url =  doGetURL(w,s,e,n,widthPx,heightPx);
-			doGrab(url);
-		}
-		catch(MalformedURLException ex)
-		{
-			System.out.println("Illegal url. Error="+ex);
-		}
-	}
-
-	public void paint(Graphics g,NavigatableComponent nc) 
-	{
-		if(theImage!=null)
-		{
-			super.paint(g,nc);
-			Graphics2D g2d = (Graphics2D)g;
-			g2d.setStroke(new BasicStroke(2));
-
-			// Display markers at the OSGB intersections.
-			// The code is very convoluted - projections really are fun
-			// things to deal with :-)
-			// Oh well, at least I can let someone else do the maths :-)
-
-			double zoomInFactor = grabbedScale / nc.getScale();
-
-			EastNorth topLeftDisplaced  = 
-				new EastNorth(topLeft.east()+dEast, topLeft.north()+dNorth);
-			EastNorth bottomRightDisplaced  = 
-				new EastNorth(bottomRight.east()+dEast,
-								bottomRight.north()+dNorth);
-
-			LatLon ll5 = Main.proj.eastNorth2latlon(topLeftDisplaced),
-				ll6 = Main.proj.eastNorth2latlon(bottomRightDisplaced);
-
-			LatLng ll7 = new LatLng(ll5.lat(),ll5.lon());
-			LatLng ll8 = new LatLng(ll6.lat(),ll6.lon());
-			ll7.toOSGB36();
-			ll8.toOSGB36();
-
-			LatLng curLatLng; 
-			EastNorth curEN;
-
-			
-			OSRef osgb1 = ll7.toOSRef(),
-				 osgb2 = ll8.toOSRef();
-
-			for(int easting=(int)(osgb1.getEasting()/1000) + 1; 
-					easting<=(int)(osgb2.getEasting()/1000);
-					easting++)
-			{
-				for (int northing=(int)(osgb1.getNorthing()/1000) ;
-					 northing>(int)(osgb2.getNorthing()/1000);
-					 northing--)
-				{
-					// Now we have to convert the OSGB eastings and northings
-					// *back* to EastNorth units so we can draw the 
-					// intersections....
-					// Not to mention converting between JOSM LatLon and
-					// JCoord LatLng....
-				
-
-					curLatLng = new OSRef(easting*1000,northing*1000).
-											toLatLng();
-					curLatLng.toWGS84();
-					curEN = Main.proj.latlon2eastNorth
-								(new LatLon(curLatLng.getLat(),
-											curLatLng.getLng() ) );
-
-					// draw a cross at the intersection 
-					Point p = Main.map.mapView.getPoint(curEN);
-					g.setColor(Color.BLUE);
-					g.drawLine(p.x-5,p.y,p.x+5,p.y);
-					g.drawLine(p.x,p.y-5,p.x,p.y+5);
-				}
-			}
-			g2d.setStroke(new BasicStroke(1));
-		}
-	}
-}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBLayer.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBLayer.java	(revision 6776)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package wmsplugin;
-
-import java.io.IOException;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.MapView;
-
-public class OSGBLayer extends WMSLayer {
-
-	public OSGBLayer(String name, String constURL) {
-		super(name, constURL);
-	}
-
-	public void grab(double minlat,double minlon,double maxlat,double maxlon)
-	throws IOException {
-		MapView mv = Main.map.mapView;
-		OSGBImage npeImage = new OSGBImage(url);
-		npeImage.grab(mv,minlat,minlon,maxlat,maxlon);
-		wmsImages.add(npeImage);
-	}
-}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSAdjustAction.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSAdjustAction.java	(revision 6776)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSAdjustAction.java	(revision 6777)
@@ -19,5 +19,5 @@
 		MouseListener, MouseMotionListener{
 
-	WMSImage selectedImage; 
+	GeorefImage selectedImage;
 	boolean mouseDown;
 	EastNorth prevEastNorth;
@@ -46,5 +46,5 @@
 
 		 for(Layer layer:Main.map.mapView.getAllLayers()) {
-			if (layer instanceof WMSLayer) {
+			if (layer.visible && layer instanceof WMSLayer) {
 				prevEastNorth=Main.map.mapView.getEastNorth(e.getX(),e.getY());
 				selectedImage = ((WMSLayer)layer).findImage(prevEastNorth);
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java	(revision 6776)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java	(revision 6777)
@@ -21,9 +21,5 @@
 		MapView mv = Main.map.mapView;
 		
-		DownloadWMSTask.download(info.name, info.url,
-				mv.getLatLon(0, mv.getHeight()).lat(),
-				mv.getLatLon(0, mv.getHeight()).lon(),
-				mv.getLatLon(mv.getWidth(), 0).lat(),
-				mv.getLatLon(mv.getWidth(), 0).lon());			
+		DownloadWMSTask.download(info.name, info.url);
 	}
 };
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 6777)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 6777)
@@ -0,0 +1,68 @@
+package wmsplugin;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+import javax.imageio.ImageIO;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.io.ProgressInputStream;
+
+public class WMSGrabber implements Grabber {
+	public String baseURL;
+
+	public WMSGrabber(String baseURL) {
+		this.baseURL = baseURL;
+	}
+
+	public GeorefImage grab(Bounds b, Projection proj,
+			double pixelPerDegree) throws IOException {
+		int w = (int) ((b.max.lon() - b.min.lon()) * pixelPerDegree);
+		int h = (int) ((b.max.lat() - b.min.lat()) * pixelPerDegree);
+
+		try {
+			URL url = getURL(
+				b.min.lon(), b.min.lat(),
+				b.max.lon(), b.max.lat(),
+				w, h);
+
+			BufferedImage img = grab(url);
+
+			return new GeorefImage(img,
+				proj.latlon2eastNorth(b.min),
+				proj.latlon2eastNorth(b.max));
+		} catch (MalformedURLException e) {
+			throw (IOException) new IOException(
+				"WMSGrabber: Illegal url.").initCause(e);
+		}
+	}
+
+	public static final NumberFormat
+		latLonFormat = new DecimalFormat("###0.0000000");
+
+	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"));
+	}
+
+	protected BufferedImage grab(URL url) throws IOException {
+		InputStream is = new ProgressInputStream(
+			url.openConnection(), Main.pleaseWaitDlg);
+		BufferedImage img = ImageIO.read(is);
+		is.close();
+		return img;
+	}
+}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSImage.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSImage.java	(revision 6776)
+++ 	(revision )
@@ -1,185 +1,0 @@
-package wmsplugin;
-
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-import javax.imageio.ImageIO;
-import javax.swing.ImageIcon;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.gui.NavigatableComponent;
-import org.openstreetmap.josm.io.ProgressInputStream;
-
-public class WMSImage implements Serializable
-{
-	String constURL;
-	protected BufferedImage theImage;
-	protected double grabbedScale;
-	protected EastNorth topLeft, bottomRight;
-	double dEast, dNorth;	
-
-	public WMSImage(String constURL)
-	{
-		this.constURL = constURL;
-	}
-	
-	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-		constURL = (String) in.readObject();
-		topLeft = (EastNorth) in.readObject();
-		bottomRight = (EastNorth) in.readObject();
-		dEast = in.readDouble();
-		dNorth = in.readDouble();
-		grabbedScale = in.readDouble();
-		theImage = (BufferedImage) ImageIO.read(ImageIO.createImageInputStream(in));
-	}
-	
-	private void writeObject(ObjectOutputStream out) throws IOException {
-		System.out.println("writ" + theImage.getWidth(null));
-		out.writeObject(constURL);
-		out.writeObject(topLeft);
-		out.writeObject(bottomRight);
-		out.writeDouble(dEast);
-		out.writeDouble(dNorth);
-		out.writeDouble(grabbedScale);
-		ImageIO.write(theImage, "png", ImageIO.createImageOutputStream(out));
-	}
-
-	public void grab(NavigatableComponent nc) throws IOException
-	{
-		EastNorth topLeft = nc.getEastNorth(0,0);
-		grabbedScale = nc.getScale();  // scale is enPerPixel
-
-		this.topLeft = topLeft;
-
-		try
-		{
-			URL url = getURL(nc);
-			doGrab(url);
-		}
-		catch(MalformedURLException e)
-		{
-			System.out.println("Illegal url. Error="+e);
-		}
-	}
-
-	public void grab(NavigatableComponent nc,double minlat,double minlon,
-			double maxlat,double maxlon) throws IOException
-	{
-		LatLon p = new LatLon(minlat,minlon),
-				p2 = new LatLon(maxlat,maxlon);
-
-		grabbedScale = nc.getScale(); // enPerPixel
-
-		topLeft = Main.proj.latlon2eastNorth(new LatLon(maxlat,minlon));
-		bottomRight = Main.proj.latlon2eastNorth(new LatLon(minlat,maxlon));
-
-		int widthPx = (int)((bottomRight.east()-topLeft.east())/grabbedScale),
-		heightPx = (int)
-		((topLeft.north()-bottomRight.north()) / grabbedScale);
-
-		try
-		{
-			URL url =  doGetURL(p.lon(),p.lat(),
-									p2.lon(),p2.lat(),widthPx,heightPx);
-			doGrab(url);
-		}
-		catch(MalformedURLException e)
-		{
-			System.out.println("Illegal url. Error="+e);
-		}
-	}
-
-	private URL getURL(NavigatableComponent nc) throws MalformedURLException
-	{
-		double widthEN = nc.getWidth()*grabbedScale,
-		heightEN = nc.getHeight()*grabbedScale;
-		LatLon p = Main.proj.eastNorth2latlon(new EastNorth
-				(topLeft.east(), topLeft.north()-heightEN));
-		LatLon p2 = Main.proj.eastNorth2latlon(new EastNorth
-				(topLeft.east()+widthEN, topLeft.north()));
-		return doGetURL(p.lon(),p.lat(),p2.lon(),p2.lat(),
-						(int)(widthEN/grabbedScale),
-						(int)(heightEN/grabbedScale) );
-	}
-
-	public static NumberFormat latLonFormat = new DecimalFormat("###0.0000000");
-
-	protected URL doGetURL(double w,double s,double e,double n, int wi, 
-					int ht) throws MalformedURLException
-	{
-		String str = constURL + "&bbox="
-			+ latLonFormat.format(w) + ","
-			+ latLonFormat.format(s) + ","
-			+ latLonFormat.format(e) + ","
-			+ latLonFormat.format(n)
-			+ "&width=" + wi + "&height=" + ht;
-		return new URL(str.replace(" ", "%20"));
-	}
-
-	protected void doGrab (URL url) throws IOException
-	{
-		InputStream is = new ProgressInputStream(
-			url.openConnection(), Main.pleaseWaitDlg);
-		theImage = ImageIO.read(is);
-		is.close();
-		Main.map.repaint();
-	}
-
-	public void displace (double dEast, double dNorth)
-	{
-	 	this.dEast += dEast;	
-	 	this.dNorth += dNorth;	
-	}
-
-	public boolean contains(EastNorth eastNorth)
-	{
-		double e1 = topLeft.east()+dEast, 
-			   e2 = bottomRight.east()+dEast,
-			   n1 = bottomRight.north()+dNorth,
-			   n2 = topLeft.north()+dNorth;
-
-		boolean b =  eastNorth.east()>=e1 && eastNorth.east()<=e2 &&
-				eastNorth.north()>=n1 && eastNorth.north()<=n2;
-		return b;
-	}
-
-	public void paint(Graphics g,NavigatableComponent nc) 
-	{
-		if (theImage != null)
-		{
-			double zoomInFactor = grabbedScale / nc.getScale();
-
-			// Find the image x and y of the supplied bottom left
-			// This will be the difference in EastNorth units, divided by the
-			// grabbed scale in EastNorth/pixel.
-
-			int w = theImage.getWidth(null), h=theImage.getHeight(null);
-			EastNorth topLeftDisplaced  = 
-				new EastNorth(topLeft.east()+dEast, topLeft.north()+dNorth);
-			Point displacement = Main.map.mapView.getPoint(topLeftDisplaced);
-			g.drawImage(theImage,displacement.x,displacement.y,
-					(int)(displacement.x+w*zoomInFactor),
-					(int)(displacement.y+h*zoomInFactor),
-					0,0,w,h,null);
-		}
-	}
-
-}
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 6776)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 6777)
@@ -29,4 +29,5 @@
 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.gui.MapView;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
@@ -42,45 +43,24 @@
 public class WMSLayer extends Layer {
 
-	protected static Icon icon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
-	protected final ArrayList<WMSImage> wmsImages;
-	protected final String url;
-	protected final int serializeFormatVersion = 1;
- 
+	protected static final Icon icon =
+		new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
+
+	protected ArrayList<GeorefImage> images = new ArrayList<GeorefImage>();
+	protected Grabber grabber;
+	protected final int serializeFormatVersion = 2;
+
 	public WMSLayer() {
-		super("Blank Layer");
-		wmsImages = new ArrayList<WMSImage>();
-		url = "";
-	}
-	public WMSLayer(String name, String url) {
+		this("Blank Layer", null);
+	}
+
+	public WMSLayer(String name, Grabber grabber) {
 		super(name);
-		// to calculate the world dimension, we assume that the projection does
-		// not have problems with translating longitude to a correct scale.
-		// Next to that, the projection must be linear dependend on the lat/lon
-		// unprojected scale.
-		if (Projection.MAX_LON != 180)
-			throw new IllegalArgumentException(tr
-					("Wrong longitude transformation for tile manager. "+
-							"Can't operate on {0}",Main.proj));
-
-		this.url = url;
-		//wmsImage = new WMSImage(url);
-		wmsImages = new ArrayList<WMSImage>();
-	}
-
-	public void grab() throws IOException
-	{
-		MapView mv = Main.map.mapView;
-		WMSImage wmsImage = new WMSImage(url);
-		wmsImage.grab(mv);
-		wmsImages.add(wmsImage);
-	}
-
-	public void grab(double minlat,double minlon,double maxlat,double maxlon)
-	throws IOException
-	{
-		MapView mv = Main.map.mapView;
-		WMSImage wmsImage = new WMSImage(url);
-		wmsImage.grab(mv,minlat,minlon,maxlat,maxlon);
-		wmsImages.add(wmsImage);
+		this.grabber = grabber;
+	}
+
+	public void grab(Bounds b, double pixelPerDegree) throws IOException {
+		if (grabber == null) return;
+		images.add(grabber.grab(b, Main.main.proj, pixelPerDegree));
+		Main.map.mapView.repaint();
 	}
 
@@ -90,5 +70,5 @@
 
 	@Override public String getToolTipText() {
-		return tr("WMS layer ({0}), {1} tile(s) loaded", name, wmsImages.size());
+		return tr("WMS layer ({0}), {1} tile(s) loaded", name, images.size());
 	}
 
@@ -101,11 +81,12 @@
 
 	@Override public void paint(Graphics g, final MapView mv) {
-		for(WMSImage wmsImage : wmsImages) {
-			wmsImage.paint(g,mv);
-		}
+		for (GeorefImage img : images) img.paint(g, mv);
 	}
 
 	@Override public void visitBoundingBox(BoundingXYVisitor v) {
-		// doesn't have a bounding box
+		for (GeorefImage img : images) {
+			v.visit(img.min);
+			v.visit(img.max);
+		}
 	}
 
@@ -124,9 +105,10 @@
 	}
 
-	public WMSImage findImage(EastNorth eastNorth)
-	{
-		for(WMSImage wmsImage : wmsImages) {
-			if (wmsImage.contains(eastNorth))  {
-				return wmsImage;
+	public GeorefImage findImage(EastNorth eastNorth) {
+		// Iterate in reverse, so we return the image which is painted last.
+		// (i.e. the topmost one)
+		for (int i = images.size() - 1; i >= 0; i--) {
+			if (images.get(i).contains(eastNorth)) {
+				return images.get(i);
 			}
 		}
@@ -134,9 +116,4 @@
 	}
 
-	//to enable the removal of the images when the layer is removed.
-	public void destroy() {
-		wmsImages.clear();
-	}
-	
 	public class SaveWmsAction extends AbstractAction {
 		public SaveWmsAction() {
@@ -149,7 +126,7 @@
 				ObjectOutputStream oos = new ObjectOutputStream(fos);
 				oos.writeInt(serializeFormatVersion);
-				oos.writeInt(wmsImages.size());
-				for (WMSImage w : wmsImages) {
-					oos.writeObject(w);
+				oos.writeInt(images.size());
+				for (GeorefImage img : images) {
+					oos.writeObject(img);
 				}
 				oos.close();
@@ -181,6 +158,6 @@
 				int numImg = ois.readInt();
 				for (int i=0; i< numImg; i++) {
-					WMSImage img = (WMSImage) ois.readObject();
-					wmsImages.add(img);
+					GeorefImage img = (GeorefImage) ois.readObject();
+					images.add(img);
 				}
 				ois.close();
