Index: applications/editors/josm/plugins/wmsplugin/README
===================================================================
--- applications/editors/josm/plugins/wmsplugin/README	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/README	(revision 10382)
@@ -15,4 +15,5 @@
 some code from Jonathan Stott <jonathan@jstott.me.uk>, Gabriel Ebner
 <ge@gabrielebner.at> and Ulf Lamping <ulf.lamping@web.de>.
+The automatic tiles downloading and Yahoo downloader made by Petr Dlouhý <petr.dlouhy@email.cz>
 
 This plugin is licensed under the GNU GPL v2 or later.
Index: applications/editors/josm/plugins/wmsplugin/build.xml
===================================================================
--- applications/editors/josm/plugins/wmsplugin/build.xml	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/build.xml	(revision 10382)
@@ -33,4 +33,7 @@
 
   <target name="dist" depends="compile">
+    <copy todir="${plugin.build.dir}/resources">
+      <fileset dir="resources"/>
+    </copy>
     <copy todir="build/images" >
       <fileset dir="images" />
Index: applications/editors/josm/plugins/wmsplugin/resources/ymap.html
===================================================================
--- applications/editors/josm/plugins/wmsplugin/resources/ymap.html	(revision 10382)
+++ applications/editors/josm/plugins/wmsplugin/resources/ymap.html	(revision 10382)
@@ -0,0 +1,101 @@
+<html>
+  <head>
+    <script type="text/javascript">
+		var bbox = "";
+        var width  = 800;
+        var height = 800;
+
+		// Parse query string and set variables
+		var url = location.href;
+        var queryStringPos = url.indexOf("?");
+		if( queryStringPos != -1 )
+        {
+            url = url.substring(queryStringPos + 1);
+	    	var variables = url.split ("&");
+            for (i = 0; i < variables.length; i++) 
+            {
+            	if( !variables[i] )
+            		continue;
+                var keyValue = variables[i].split("=");
+                eval ('var '+keyValue[0].toLowerCase()+'="'+keyValue[1]+'"');
+            }
+        }
+        else
+        {
+            dump("YWMS ERROR: no queryString\n");
+        }
+        
+        // Limit size to current window's, to avoid memory problems
+        width = Math.min(width, screen.width);
+        height = Math.min(height, screen.height);
+        
+    </script>
+    <script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.4&appid=z7qRk3_V34HAbY_SkC7u7GAgG5nDTblw.cuL1OS5LWGwkIIUeGjg4qsnJDPpmhoF"></script>
+  </head>
+  
+  <body style="margin: 0px">
+    <div id="map"></div>
+    <script type="text/javascript">
+      if( !bbox || !width || !height)
+      {
+          alert("YWMS ERROR: invalid parameters\n");
+      }
+      else
+      {
+          // Resize map container to parameter dimension
+          var mapDiv = document.getElementById("map");
+          mapDiv.style.width  = Math.ceil(width/258)*258;
+          mapDiv.style.height = Math.ceil(height/258)*258;
+
+          // Get the bounding box
+          var coords = bbox.split(",");
+          var tllon  = coords[0], tllat = coords[1];
+          var brlon  = coords[2], brlat = coords[3];
+
+          var points = new Array();
+          points[0] = new YGeoPoint(tllat, tllon);
+          points[1] = new YGeoPoint(brlat, brlon);
+
+          // other map types work as well but only satellite allowed for use with OSM!
+          var map = new YMap(document.getElementById("map"), YAHOO_MAP_SAT);
+          map.removeZoomScale();
+          var zac = map.getBestZoomAndCenter(points);
+          var level = zac.zoomLevel;
+           
+           // funny Yahoo bug seems to return 0 if your section is too small
+           if( level == 0 ) level = 1;
+           if (level>1) level--;
+           
+           map.drawZoomAndCenter(zac.YGeoPoint,level);
+
+		  // Get the on-screen coordinates of the points
+		  xy0 = map.convertLatLonXY(points[0]);
+		  xy1 = map.convertLatLonXY(points[1]);
+		  
+		  // Create a new size for the map. This makes the need of clipping the image unnecesary.
+		  new_width  = Math.abs( xy0.x - xy1.x);
+		  new_height = Math.abs( xy0.y - xy1.y);
+		  
+		  // Apply the new width-height
+          mapDiv.style.width  = new_width;
+          mapDiv.style.height = new_height;
+          map.resizeTo( new YSize(new_width, new_height));
+          
+		  /// DEBUG: colour the interesting area
+		  var cPT2 = new YGeoPoint(tllat, tllon); 
+		  var cPT3 = new YGeoPoint(tllat, brlon); 
+		  var cPT4 = new YGeoPoint(brlat, brlon); 
+		  var cPT5 = new YGeoPoint(brlat, tllon); 
+		  // args: array of pts, color, width, alpha 
+		  var poly1 = new YPolyline([cPT2,cPT3,cPT4,cPT5, cPT2],'blue',7,0.7); 
+		  //map.addOverlay(poly1);
+		 
+          var bounds = map.getBoundsLatLon();
+
+          //Resizes to the actual bounding box
+			 window.moveTo(0,0);
+			 window.resizeTo(new_width,new_height);
+      }
+    </script>
+  </body>
+</html>
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/GeorefImage.java	(revision 10382)
@@ -15,11 +15,10 @@
 
 public class GeorefImage implements Serializable {
-	public BufferedImage image;
+	public BufferedImage image = null;
 	public EastNorth min, max;
+	public boolean downloadingStarted;
 
-	public GeorefImage(BufferedImage img, EastNorth min, EastNorth max) {
-		image = img;
-		this.min = min;
-		this.max = max;
+	public GeorefImage(boolean downloadingStarted) {
+		this.downloadingStarted = downloadingStarted;
 	}
 
@@ -34,12 +33,19 @@
 	}
 
-	public void paint(Graphics g, NavigatableComponent nc) {
-		if (image == null || min == null || max == null) return;
+	public boolean isVisible(NavigatableComponent nc) {
+		Point minPt = nc.getPoint(min), maxPt = nc.getPoint(max);
+		Graphics g = nc.getGraphics();
+
+		return (g.hitClip(minPt.x, maxPt.y,
+				maxPt.x - minPt.x, minPt.y - maxPt.y));
+	}
+
+	public boolean paint(Graphics g, NavigatableComponent nc) {
+		if (image == null || min == null || max == null) return false;
 
 		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;
+		if(!isVisible(nc))
+			return false;
 
 		g.drawImage(image,
@@ -47,4 +53,6 @@
 			0, 0, image.getWidth(), image.getHeight(), // src
 			null);
+
+		return true;
 	}
 
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/Grabber.java	(revision 10382)
@@ -3,8 +3,8 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.projection.Projection;
+import java.util.ArrayList;
+import org.openstreetmap.josm.gui.MapView;
 
 public interface Grabber {
-	public GeorefImage grab(Bounds bounds,
-		Projection proj, double pixelPerDegree)
-		throws IOException;
+	public void start();
 }
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/OSGBGrabber.java	(revision 10382)
@@ -1,2 +1,3 @@
+/*
 package wmsplugin;
 
@@ -61,2 +62,3 @@
 	}
 }
+*/
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSDownloadAction.java	(revision 10382)
@@ -9,4 +9,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.data.Bounds;
 
 public class WMSDownloadAction extends JosmAction {
@@ -22,5 +23,13 @@
 		System.out.println(info.url);
 		
-		DownloadWMSTask.download(getLayer(info));
+		WMSLayer wmsLayer = getLayer(info);
+		MapView mv = Main.map.mapView;
+
+		Bounds b = new Bounds(
+			mv.getLatLon(0, mv.getHeight()),
+			mv.getLatLon(mv.getWidth(), 0));
+		double pixelPerDegree = mv.getWidth() / (b.max.lon() - b.min.lon());
+
+		wmsLayer.grab(b, pixelPerDegree);
 	}
 
@@ -34,5 +43,5 @@
 
 		// FIXME: move this to WMSPlugin/WMSInfo/preferences.
-		WMSLayer wmsLayer = new WMSLayer(info.name, info.grabber);
+		WMSLayer wmsLayer = new WMSLayer(info.name, info.url);
 		Main.main.addLayer(wmsLayer);
 		return wmsLayer;
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSGrabber.java	(revision 10382)
@@ -12,6 +12,8 @@
 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;
@@ -19,32 +21,57 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.io.ProgressInputStream;
+import org.openstreetmap.josm.gui.MapView;
 
-public class WMSGrabber implements Grabber {
-	public String baseURL;
 
-	public WMSGrabber(String baseURL) {
-		this.baseURL = baseURL;
+public class WMSGrabber extends Thread implements 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;
+		this.setDaemon(true);
+		this.setPriority(Thread.MIN_PRIORITY);
 	}
 
-	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);
+	public void run() {
+			
+			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);
+			try {
+				URL url = getURL(
+					b.min.lon(), b.min.lat(),
+					b.max.lon(), b.max.lat(),
+					w, h);
 
-			BufferedImage img = grab(url);
+				image.min = proj.latlon2eastNorth(b.min);
+				image.max = proj.latlon2eastNorth(b.max);
 
-			return new GeorefImage(img,
-				proj.latlon2eastNorth(b.min),
-				proj.latlon2eastNorth(b.max));
-		} catch (MalformedURLException e) {
-			throw (IOException) new IOException(
-				tr("WMSGrabber: Illegal url.")).initCause(e);
-		}
+				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()));
+			}
 	}
 
@@ -65,9 +92,15 @@
 
 	protected BufferedImage grab(URL url) throws IOException {
-		InputStream is = new ProgressInputStream(
-			url.openConnection(), Main.pleaseWaitDlg);
-		BufferedImage img = ImageIO.read(is);
-		is.close();
-		return img;
+			InputStream is = new ProgressInputStream(
+				url.openConnection(), null);
+			BufferedImage img;
+		synchronized (layer){ //download only one tile in one moment
+			if(!image.isVisible(mv)){
+				return null;
+			}
+			img = ImageIO.read(is);
+		}
+			is.close();
+			return img;
 	}
 }
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSInfo.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSInfo.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSInfo.java	(revision 10382)
@@ -12,15 +12,10 @@
 	String name;
 	String url;
-	Grabber grabber;
 	int prefid;
 	
-	public WMSInfo(String name, String url, Grabber grabber, int prefid) {
+	public WMSInfo(String name, String url, int prefid) {
 		this.name=name; this.url=url; this.prefid=prefid;
-		this.grabber = grabber;
 	}
 
-	public WMSInfo(String name, String url, int prefid) {
-		this(name, url, WMSPlugin.getGrabber(url), prefid);
-	}
 	
 	public void save() {
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 10382)
@@ -3,6 +3,8 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.lang.Math;
 import java.awt.Component;
 import java.awt.Graphics;
+import java.awt.Point;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
@@ -30,5 +32,7 @@
 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 org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
@@ -46,21 +50,43 @@
 		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 int messageNum = 5; //limit for messages per layer
+	protected boolean started = true;
+	protected boolean stopAfterPaint = false;
+	protected int ImageSize = 500;
+	protected int dax = 10;
+	protected int day = 10;
+	protected int minZoom = 3;
+	protected double pixelPerDegree;
+	protected GeorefImage[][] images = new GeorefImage[dax][day];
+
+	protected String baseURL;
+	protected final int serializeFormatVersion = 3;
 
 	public WMSLayer() {
 		this(tr("Blank Layer"), null);
-	}
-
-	public WMSLayer(String name, Grabber grabber) {
+		initializeImages();
+	}
+
+	public WMSLayer(String name, String baseURL) {
 		super(name);
-		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();
+		initializeImages();
+		this.baseURL = baseURL;
+	}
+
+	public void initializeImages() {
+		images = new GeorefImage[dax][day];
+		for(int x = 0; x<dax; ++x)
+			for(int y = 0; y<day; ++y)
+				images[x][y]= new GeorefImage(false);
+	}
+
+	public void grab(Bounds b, double _pixelPerDegree) {
+		if (baseURL == null) return;
+		//set resolution
+		if(started || Math.round(pixelPerDegree/10000) != Math.round(_pixelPerDegree/10000))
+			initializeImages();
+		pixelPerDegree = _pixelPerDegree;
+		if(!started)stopAfterPaint = true;
+		started = true;
 	}
 
@@ -70,5 +96,8 @@
 
 	@Override public String getToolTipText() {
-		return tr("WMS layer ({0}), {1} tile(s) loaded", name, images.size());
+		if(started)
+			return tr("WMS layer ({0}), automaticaly downloading in zoom {1}", name, Math.round(pixelPerDegree/10000));
+		else
+			return tr("WMS layer ({0}), downloading in zoom {1}", name, Math.round(pixelPerDegree/10000));
 	}
 
@@ -80,13 +109,58 @@
 	}
 
+	private Bounds XYtoBounds (int x, int y) {
+		return new Bounds( 
+			new LatLon( x * ImageSize / pixelPerDegree,
+				         y * ImageSize / pixelPerDegree),
+			new LatLon((x + 1) *  ImageSize / pixelPerDegree,
+			           (y + 1) * ImageSize / pixelPerDegree));
+	}
+
+	private int modulo (int a, int b) {
+	  if(a%b>=0)return a%b;
+	  else return a%b+b;
+	}	  
+
 	@Override public void paint(Graphics g, final MapView mv) {
-		for (GeorefImage img : images) img.paint(g, mv);
+		Bounds b = new Bounds(
+			mv.getLatLon(0, mv.getHeight()),
+			mv.getLatLon(mv.getWidth(), 0));
+		int bminx= (int)Math.floor ((b.min.lat() * pixelPerDegree ) / ImageSize );
+		int bminy= (int)Math.floor ((b.min.lon() * pixelPerDegree ) / ImageSize );
+		int bmaxx= (int)Math.ceil  ((b.max.lat() * pixelPerDegree ) / ImageSize );
+		int bmaxy= (int)Math.ceil  ((b.max.lon() * pixelPerDegree ) / ImageSize );
+
+
+		if( !started || (pixelPerDegree / (mv.getWidth() / (b.max.lon() - b.min.lon())) > minZoom) ){ //don't download when it's too outzoomed
+			for(int x = 0; x<dax; ++x)
+				for(int y = 0; y<day; ++y){
+						images[modulo(x,dax)][modulo(y,day)].paint(g, mv);
+				}
+		} else {
+			for(int x = bminx; x<bmaxx; ++x)
+				for(int y = bminy; y<bmaxy; ++y){
+					GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
+					if(!img.paint(g, mv) && !img.downloadingStarted){
+						//System.out.println(tr("------{0}|{1}|{2}|{3}", modulo(x,dax), modulo(y,day), img.downloadingStarted, img.isVisible(mv)));
+						img.downloadingStarted = true;
+						img.image = null;
+						Grabber gr = WMSPlugin.getGrabber(baseURL, XYtoBounds(x,y), Main.main.proj, pixelPerDegree, img, mv, this);
+						gr.start();
+				}
+			}
+		}
+		if(stopAfterPaint){
+			started = false;
+			stopAfterPaint = false;
+		}
 	}
 
 	@Override public void visitBoundingBox(BoundingXYVisitor v) {
-		for (GeorefImage img : images) {
-			v.visit(img.min);
-			v.visit(img.max);
-		}
+		for(int x = 0; x<dax; ++x)
+			for(int y = 0; y<day; ++y)
+					if(images[x][y]!=null){
+						v.visit(images[x][y].min);
+						v.visit(images[x][y].max);
+					}
 	}
 
@@ -99,20 +173,26 @@
 				new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
 				new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),				
+				new JSeparator(),
 				new JMenuItem(new LoadWmsAction()),
 				new JMenuItem(new SaveWmsAction()),
 				new JSeparator(),
+				new JMenuItem(new StartWmsAction()),
+				new JMenuItem(new StopWmsAction()),
+				new JSeparator(),
 				new JMenuItem(new LayerListPopup.InfoAction(this))};
+
 	}
 
 	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);
-			}
-		}
+		for(int x = 0; x<dax; ++x)
+			for(int y = 0; y<day; ++y)
+					if(images[x][y]!=null && images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null){
+						if (images[x][y].contains(eastNorth)) {
+							return images[x][y];
+						}
+					}
 		return null;
 	}
+
 
 	public class SaveWmsAction extends AbstractAction {
@@ -122,20 +202,24 @@
 		public void actionPerformed(ActionEvent ev) {
 			File f = openFileDialog(false);
-			try {
+			try
+			{
 				FileOutputStream fos = new FileOutputStream(f);
 				ObjectOutputStream oos = new ObjectOutputStream(fos);
 				oos.writeInt(serializeFormatVersion);
-				oos.writeInt(images.size());
-				for (GeorefImage img : images) {
-					oos.writeObject(img);
-				}
+				oos.writeInt(dax);
+				oos.writeInt(day);
+				oos.writeInt(ImageSize);
+				oos.writeDouble(pixelPerDegree);
+				oos.writeObject(baseURL);
+				oos.writeObject(images);
 				oos.close();
 				fos.close();
-			} catch (Exception ex) {
+			}
+			catch (Exception ex) {
 				ex.printStackTrace(System.out);
 			}
 		}
 	}
-	
+
 	public class LoadWmsAction extends AbstractAction {
 		public LoadWmsAction() {
@@ -145,34 +229,57 @@
 			File f = openFileDialog(true);
 			if (f == null) return;
-			try {
+			try
+			{
 				FileInputStream fis = new FileInputStream(f);
 				ObjectInputStream ois = new ObjectInputStream(fis);
 				int sfv = ois.readInt();
 				if (sfv != serializeFormatVersion) {
-					JOptionPane.showMessageDialog(Main.parent, 
+					JOptionPane.showMessageDialog(Main.parent,
 						tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
-						tr("File Format Error"), 
+						tr("File Format Error"),
 						JOptionPane.ERROR_MESSAGE);
 					return;
 				}
-				int numImg = ois.readInt();
-				for (int i=0; i< numImg; i++) {
-					GeorefImage img = (GeorefImage) ois.readObject();
-					images.add(img);
-				}
+				dax = ois.readInt();
+				day = ois.readInt();
+				ImageSize = ois.readInt();
+				pixelPerDegree = ois.readDouble();
+				baseURL = (String) ois.readObject();
+				images = (GeorefImage[][])ois.readObject();
+
 				ois.close();
 				fis.close();
-			} catch (Exception ex) {
+				started = false;
+			}
+			catch (Exception ex) {
 				// FIXME be more specific
 				ex.printStackTrace(System.out);
-				JOptionPane.showMessageDialog(Main.parent, 
-						tr("Error loading file"),
-						tr("Error"), 
-						JOptionPane.ERROR_MESSAGE);
-					return;
-			}
-		}
-	}
-	
+				JOptionPane.showMessageDialog(Main.parent,
+					tr("Error loading file"),
+					tr("Error"),
+					JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+		}
+	}
+
+	public class StartWmsAction extends AbstractAction {
+		public StartWmsAction() {
+			super(tr("Start automatic downloading"), null);
+		}
+		public void actionPerformed(ActionEvent ev) {
+			started = true;
+		}
+	}
+
+	public class StopWmsAction extends AbstractAction {
+		public StopWmsAction() {
+			super(tr("Stop automatic downloading"), null);
+		}
+		public void actionPerformed(ActionEvent ev) {
+			started = false;
+		}
+	}
+
 	protected static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple) {
 		String curDir = Main.pref.get("lastDirectory");
@@ -184,9 +291,9 @@
 			fc.addChoosableFileFilter(ExtensionFileFilter.filters[i]);
 		fc.setAcceptAllFileFilterUsed(true);
-	
+
 		int answer = open ? fc.showOpenDialog(Main.parent) : fc.showSaveDialog(Main.parent);
 		if (answer != JFileChooser.APPROVE_OPTION)
 			return null;
-		
+
 		if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
 			Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
@@ -194,12 +301,12 @@
 		if (!open) {
 			File file = fc.getSelectedFile();
-			if (file == null || (file.exists() && JOptionPane.YES_OPTION != 
-					JOptionPane.showConfirmDialog(Main.parent, tr("File exists. Overwrite?"), tr("Overwrite"), JOptionPane.YES_NO_OPTION)))
+			if (file == null || (file.exists() && JOptionPane.YES_OPTION !=
+				JOptionPane.showConfirmDialog(Main.parent, tr("File exists. Overwrite?"), tr("Overwrite"), JOptionPane.YES_NO_OPTION)))
 				return null;
 		}
-		
+
 		return fc;
 	}
-	
+
 	public static File openFileDialog(boolean open) {
 		JFileChooser fc = createAndOpenFileChooser(open, false);
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java	(revision 10379)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java	(revision 10382)
@@ -9,4 +9,5 @@
 import java.util.Map;
 import java.util.TreeSet;
+import java.io.*;
 
 import javax.swing.AbstractAction;
@@ -21,4 +22,7 @@
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.MapView;
 
 
@@ -26,4 +30,6 @@
 // data.
 
+
+
 public class WMSPlugin extends Plugin {
 
@@ -37,4 +43,11 @@
 	
 	public WMSPlugin() {
+		try
+		{
+			copy("/resources/ymap.html", "ymap.html");
+		}
+		catch(IOException e) {
+			e.printStackTrace();
+		}
 		refreshMenu();
 	}
@@ -44,4 +57,19 @@
 	// wmsplugin.1.name=Landsat
 	// wmsplugin.1.url=http://and.so.on/
+	
+	public void copy(String from, String to) throws FileNotFoundException, IOException
+	{
+		File pluginDir = new File(Main.pref.getPreferencesDir() + "plugins/wmsplugin/");
+		if (!pluginDir.exists())
+			pluginDir.mkdirs();
+		FileOutputStream out = new FileOutputStream(Main.pref.getPreferencesDir() + "plugins/wmsplugin/" + to);
+		InputStream in = WMSPlugin.class.getResourceAsStream(from);
+		byte[] buffer = new byte[8192];
+		for(int len = in.read(buffer); len > 0; len = in.read(buffer))
+			out.write(buffer, 0, len);
+		in.close();
+		out.close();
+	}
+
 	
 	public static void refreshMenu() {
@@ -54,4 +82,5 @@
 		String url = null;
 		int lastid = -1;
+		boolean isYahoo = false;
 		for (String key : keys) {
 			String[] elements = key.split("\\.");
@@ -65,4 +94,5 @@
 				if ((name != null) && (url != null)) {
 					wmsList.add(new WMSInfo(name, url, prefid));
+					if(name.equals("YAHOO"))isYahoo = true;
 				}
 				name = null; url = null; lastid = prefid; 
@@ -76,6 +106,7 @@
 		if ((name != null) && (url != null)) {
 			wmsList.add(new WMSInfo(name, url, prefid));
-		}
-		
+			if(name.equals("YAHOO"))isYahoo = true;
+		}
+
 		// if no (valid) prefs are set, initialize to a sensible default.
 		if (wmsList.isEmpty()) {
@@ -92,4 +123,13 @@
 			wmsList.add(npeInfo);
 		}
+		if(!isYahoo){ //add Yahoo to the list, if there isn't
+			int maxKey = 0;
+			for(WMSInfo in : wmsList)
+				if(maxKey < in.prefid)maxKey = in.prefid;
+			WMSInfo yahooInfo = new WMSInfo(tr("YAHOO"),
+					"yahoo://gnome-web-photo --mode=photo --format=png {0} /dev/stdout", maxKey+1);
+			yahooInfo.save();
+			wmsList.add(yahooInfo);
+		}
 		
 		JMenuBar menu = Main.main.menu;
@@ -122,10 +162,16 @@
 	}
 
-	public static Grabber getGrabber(String wmsurl) {
-		if (wmsurl.matches("(?i).*layers=npeoocmap.*") || wmsurl.matches("(?i).*layers=npe.*") ){
-			return new OSGBGrabber(wmsurl);
-		} else {
-			return new WMSGrabber(wmsurl);
-		}
+	public static Grabber getGrabber(String _baseURL, Bounds _b, Projection _proj,
+			         double _pixelPerDegree, GeorefImage _image, MapView _mv, WMSLayer _layer){
+		if(_baseURL.startsWith("yahoo://"))
+			return new YAHOOGrabber(_baseURL, _b, _proj, _pixelPerDegree, _image, _mv, _layer);
+		else 
+			return new WMSGrabber(_baseURL, _b, _proj, _pixelPerDegree, _image, _mv, _layer);
+		// OSBGrabber should be rewrite for thread support first
+		//if (wmsurl.matches("(?i).*layers=npeoocmap.*") || wmsurl.matches("(?i).*layers=npe.*") ){
+		//	return new OSGBGrabber(_b, _proj, _pixelPerDegree,  _images, _mv, _layer);
+		//} else {
+		//	return new WMSGrabber(_b, _proj, _pixelPerDegree,  _images, _mv, _layer);
+		//}
 	}
 	
Index: applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java
===================================================================
--- applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java	(revision 10382)
+++ applications/editors/josm/plugins/wmsplugin/src/wmsplugin/YAHOOGrabber.java	(revision 10382)
@@ -0,0 +1,139 @@
+package wmsplugin;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.image.BufferedImage;
+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 extends Thread implements Grabber{
+	protected String baseURL;
+	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;
+		this.setDaemon(true);
+		this.setPriority(Thread.MIN_PRIORITY);
+	}
+
+	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);
+				synchronized (layer) {
+					if(!image.isVisible(mv)){
+						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 {
+		ArrayList<String> cmdParams = new ArrayList<String>();
+		
+		StringTokenizer st = new StringTokenizer(tr(browserCmd, url));
+		while( st.hasMoreTokens() ) 
+			cmdParams.add(st.nextToken());
+
+		System.out.println("WMS::Browsing YAHOO: " + cmdParams);
+		ProcessBuilder builder = new ProcessBuilder( cmdParams);
+
+		try {
+			return builder.start();
+		}
+		catch(IOException ioe) {
+			throw new IOException( tr("Could not start browser. Please check that the executable path is correct."));
+		}
+	}
+
+	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"));
+	}
+
+}
