Index: /applications/editors/josm/plugins/openlayers/build.xml
===================================================================
--- /applications/editors/josm/plugins/openlayers/build.xml	(revision 22549)
+++ /applications/editors/josm/plugins/openlayers/build.xml	(revision 22550)
@@ -33,5 +33,5 @@
 	<property name="commit.message" value="Changed the constructor signature of the plugin main class" />
 	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-	<property name="plugin.main.version" value="2830" />
+	<property name="plugin.main.version" value="3408" />
 
 	<property name="josm"                   location="../../core/dist/josm-custom.jar"/>
@@ -103,8 +103,8 @@
 
 	<!--
-	************************** Publishing the plugin *********************************** 
+	************************** Publishing the plugin ***********************************
 	-->
 	<!--
-		** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+		** extracts the JOSM release for the JOSM version in ../core and saves it in the
 		** property ${coreversion.info.entry.revision}
 		**
@@ -155,15 +155,15 @@
 
 	<!--
-		** commits the plugin.jar 
+		** commits the plugin.jar
 		-->
 	<target name="commit-dist">
 		<echo>
 	***** Properties of published ${plugin.jar} *****
-	Commit message    : '${commit.message}'					
+	Commit message    : '${commit.message}'
 	Plugin-Mainversion: ${plugin.main.version}
 	JOSM build version: ${coreversion.info.entry.revision}
 	Plugin-Version    : ${version.entry.commit.revision}
-	***** / Properties of published ${plugin.jar} *****					
-						
+	***** / Properties of published ${plugin.jar} *****
+
 	Now commiting ${plugin.jar} ...
 	</echo>
@@ -197,5 +197,5 @@
 		</fail>
 	</target>
- 
+
 	<target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
 	</target>
Index: /applications/editors/josm/plugins/openlayers/src/org/openstreetmap/josm/plugins/openLayers/OpenLayersLayer.java
===================================================================
--- /applications/editors/josm/plugins/openlayers/src/org/openstreetmap/josm/plugins/openLayers/OpenLayersLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/openlayers/src/org/openstreetmap/josm/plugins/openLayers/OpenLayersLayer.java	(revision 22550)
@@ -1,5 +1,4 @@
 package org.openstreetmap.josm.plugins.openLayers;
 
-import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics2D;
@@ -7,7 +6,6 @@
 import java.beans.PropertyChangeListener;
 
+import javax.swing.Action;
 import javax.swing.Icon;
-import javax.swing.JMenuItem;
-import javax.swing.JSeparator;
 
 import org.mozilla.javascript.NativeArray;
@@ -77,13 +75,13 @@
 
     @Override
-    public Component[] getMenuEntries() {
-        return new Component[] {
-            new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-            new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-            new JSeparator(),
+    public Action[] getMenuEntries() {
+        return new Action[] {
+            LayerListDialog.getInstance().createShowHideLayerAction(),
+            LayerListDialog.getInstance().createDeleteLayerAction(),
+            SeparatorLayerAction.INSTANCE,
             // color,
-            new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
-            new JSeparator(),
-            new JMenuItem(new LayerListPopup.InfoAction(this)) };
+            new RenameLayerAction(getAssociatedFile(), this),
+            SeparatorLayerAction.INSTANCE,
+            new LayerListPopup.InfoAction(this) };
     }
 
Index: /applications/editors/josm/plugins/slippymap/build.xml
===================================================================
--- /applications/editors/josm/plugins/slippymap/build.xml	(revision 22549)
+++ /applications/editors/josm/plugins/slippymap/build.xml	(revision 22550)
@@ -18,5 +18,5 @@
 **
 ** To build against the core in ../../core, create a correct manifest and deploy to
-** SVN, 
+** SVN,
 **    set the properties commit.message and plugin.main.version
 ** and run
@@ -28,5 +28,5 @@
 
 	<property name="commit.message" value="Added haiti imagery tile source" />
-	<property name="plugin.main.version" value="2830" />
+	<property name="plugin.main.version" value="3408" />
 
 	<property name="josm"                   location="../../core/dist/josm-custom.jar"/>
@@ -87,8 +87,8 @@
 
 	<!--
-			 ************************** Publishing the plugin *********************************** 
+			 ************************** Publishing the plugin ***********************************
 			-->
 	<!--
-			** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+			** extracts the JOSM release for the JOSM version in ../core and saves it in the
 			** property ${coreversion.info.entry.revision}
 			**
@@ -139,15 +139,15 @@
 
 	<!--
-			** commits the plugin.jar 
+			** commits the plugin.jar
 			-->
 	<target name="commit-dist">
 		<echo>
 		***** Properties of published ${plugin.jar} *****
-		Commit message    : '${commit.message}'					
+		Commit message    : '${commit.message}'
 		Plugin-Mainversion: ${plugin.main.version}
 		JOSM build version: ${coreversion.info.entry.revision}
 		Plugin-Version    : ${version.entry.commit.revision}
-		***** / Properties of published ${plugin.jar} *****					
-							
+		***** / Properties of published ${plugin.jar} *****
+
 		Now commiting ${plugin.jar} ...
 		</echo>
@@ -184,5 +184,5 @@
 	<target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
 	</target>
-	
+
 	<target name="dev-install">
 		<copy file="${plugin.jar}" todir="c:/data/projekte/osm/josm-dev/plugins" />
Index: /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java
===================================================================
--- /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java	(revision 22550)
@@ -4,5 +4,4 @@
 
 import java.awt.Color;
-import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
@@ -21,9 +20,9 @@
 
 import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.Icon;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
-import javax.swing.JSeparator;
 import javax.swing.SwingUtilities;
 
@@ -44,9 +43,9 @@
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 
 /**
@@ -993,13 +992,13 @@
 
     @Override
-    public Component[] getMenuEntries() {
-        return new Component[] {
-                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-                new JSeparator(),
+    public Action[] getMenuEntries() {
+        return new Action[] {
+                LayerListDialog.getInstance().createShowHideLayerAction(),
+                LayerListDialog.getInstance().createDeleteLayerAction(),
+                SeparatorLayerAction.INSTANCE,
                 // color,
-                new JMenuItem(new RenameLayerAction(this.getAssociatedFile(), this)),
-                new JSeparator(),
-                new JMenuItem(new LayerListPopup.InfoAction(this)) };
+                new RenameLayerAction(this.getAssociatedFile(), this),
+                SeparatorLayerAction.INSTANCE,
+                new LayerListPopup.InfoAction(this) };
     }
 
Index: /applications/editors/josm/plugins/validator/build.xml
===================================================================
--- /applications/editors/josm/plugins/validator/build.xml	(revision 22549)
+++ /applications/editors/josm/plugins/validator/build.xml	(revision 22550)
@@ -27,5 +27,5 @@
 	-->
 	<property name="commit.message" value="i18n fix" />
-	<property name="plugin.main.version" value="3388" />
+	<property name="plugin.main.version" value="3408" />
 
 
Index: /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ErrorLayer.java
===================================================================
--- /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ErrorLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/ErrorLayer.java	(revision 22550)
@@ -4,12 +4,10 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Component;
 import java.awt.Graphics2D;
 import java.util.Enumeration;
 import java.util.List;
 
+import javax.swing.Action;
 import javax.swing.Icon;
-import javax.swing.JMenuItem;
-import javax.swing.JSeparator;
 import javax.swing.tree.DefaultMutableTreeNode;
 
@@ -124,10 +122,12 @@
 
     @Override
-    public Component[] getMenuEntries() {
-        return new Component[] { new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-                new JSeparator(),
-                new JMenuItem(new RenameLayerAction(null, this)), new JSeparator(),
-                new JMenuItem(new LayerListPopup.InfoAction(this)) };
+    public Action[] getMenuEntries() {
+        return new Action[] {
+                LayerListDialog.getInstance().createShowHideLayerAction(),
+                LayerListDialog.getInstance().createDeleteLayerAction(),
+                SeparatorLayerAction.INSTANCE,
+                new RenameLayerAction(null, this),
+                SeparatorLayerAction.INSTANCE,
+                new LayerListPopup.InfoAction(this) };
     }
 
Index: /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java
===================================================================
--- /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java	(revision 22550)
@@ -3,5 +3,4 @@
 
 import java.awt.Color;
-import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
@@ -9,7 +8,6 @@
 import java.awt.geom.Point2D;
 
+import javax.swing.Action;
 import javax.swing.Icon;
-import javax.swing.JMenuItem;
-import javax.swing.JSeparator;
 
 import org.openstreetmap.josm.Main;
@@ -123,13 +121,13 @@
 
     @Override
-    public Component[] getMenuEntries()
-    {
-        return new Component[]{
-                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-                new JSeparator(),
-                new JMenuItem(new RenameLayerAction(null, this)),
-                new JSeparator(),
-                new JMenuItem(new LayerListPopup.InfoAction(this))};
+    public Action[] getMenuEntries()
+    {
+        return new Action[] {
+                LayerListDialog.getInstance().createShowHideLayerAction(),
+                LayerListDialog.getInstance().createDeleteLayerAction(),
+                SeparatorLayerAction.INSTANCE,
+                new RenameLayerAction(null, this),
+                SeparatorLayerAction.INSTANCE,
+                new LayerListPopup.InfoAction(this)};
     }
 
Index: /applications/editors/josm/plugins/videomapping/.classpath
===================================================================
--- /applications/editors/josm/plugins/videomapping/.classpath	(revision 22549)
+++ /applications/editors/josm/plugins/videomapping/.classpath	(revision 22550)
@@ -5,11 +5,7 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
-	<classpathentry kind="lib" path="D:/Projekte/Studium/GeoProjekt/working/VideoMapping/lib/jna.jar"/>
-	<classpathentry kind="lib" path="D:/Projekte/Studium/GeoProjekt/working/VideoMapping/lib/vlcj-1.1h.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/D:/Projekte/Studium/GeoProjekt/working/vlcj/vlcj-1.1h-javadoc.jar!/"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="lib" path="D:/Projekte/Studium/GeoProjekt/working/VideoMapping/lib/log4j.jar"/>
+	<classpathentry kind="lib" path="lib/jna.jar"/>
+	<classpathentry kind="lib" path="lib/log4j.jar"/>
+	<classpathentry kind="lib" path="lib/vlcj-1.1h.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: /applications/editors/josm/plugins/videomapping/build.xml
===================================================================
--- /applications/editors/josm/plugins/videomapping/build.xml	(revision 22549)
+++ /applications/editors/josm/plugins/videomapping/build.xml	(revision 22550)
@@ -33,5 +33,5 @@
 	<property name="commit.message" value="videomapping" />
 	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-	<property name="plugin.main.version" value="1234" />
+	<property name="plugin.main.version" value="3408" />
 
 
@@ -110,5 +110,5 @@
 				<attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/VideoMapping"/>
 				<attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
-				<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>				
+				<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
 			</manifest>
 			<zipfileset src="lib/vlcj-1.1h.jar" />
@@ -165,8 +165,8 @@
 
 	<!--
-	************************** Publishing the plugin *********************************** 
+	************************** Publishing the plugin ***********************************
 	-->
 	<!--
-		** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+		** extracts the JOSM release for the JOSM version in ../core and saves it in the
 		** property ${coreversion.info.entry.revision}
 		**
@@ -217,15 +217,15 @@
 
 	<!--
-		** commits the plugin.jar 
+		** commits the plugin.jar
 		-->
 	<target name="commit-dist">
 		<echo>
 	***** Properties of published ${plugin.jar} *****
-	Commit message    : '${commit.message}'					
+	Commit message    : '${commit.message}'
 	Plugin-Mainversion: ${plugin.main.version}
 	JOSM build version: ${coreversion.info.entry.revision}
 	Plugin-Version    : ${version.entry.commit.revision}
-	***** / Properties of published ${plugin.jar} *****					
-						
+	***** / Properties of published ${plugin.jar} *****
+
 	Now commiting ${plugin.jar} ...
 	</echo>
Index: /applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/PositionLayer.java
===================================================================
--- /applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/PositionLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/PositionLayer.java	(revision 22550)
@@ -2,44 +2,27 @@
 
 
-import java.sql.Time;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Color;
-import java.awt.Component;
 import java.awt.Cursor;
-import java.awt.Dimension;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-
-import javax.swing.*;
-
-import static org.openstreetmap.josm.tools.I18n.*;
+import java.text.SimpleDateFormat;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.InfoAction;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.WayPoint;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.MapView;
@@ -48,8 +31,4 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.plugins.videomapping.video.GPSVideoPlayer;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.Shortcut;
-
-import com.sun.jna.StringArray;
 
 //Basic rendering and GPS layer interaction
@@ -65,5 +44,5 @@
 	private SimpleDateFormat ms;
 	private GPSVideoPlayer gps;
-		
+
 	public PositionLayer(String name, final List<WayPoint> ls) {
 		super(name);
@@ -74,6 +53,6 @@
 		ms= new SimpleDateFormat("mm:ss");
 		Main.map.mapView.addMouseListener(this);
-		Main.map.mapView.addMouseMotionListener(this);							
-		
+		Main.map.mapView.addMouseMotionListener(this);
+
 	}
 
@@ -94,14 +73,13 @@
 
 	@Override
-	public Component[] getMenuEntries() {
-        return new Component[]{
-                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-                new JSeparator(),
+	public Action[] getMenuEntries() {
+        return new Action[]{
+                LayerListDialog.getInstance().createShowHideLayerAction(),
+                LayerListDialog.getInstance().createDeleteLayerAction(),
+                SeparatorLayerAction.INSTANCE,
                 //TODO here my stuff
-                new JSeparator(),
-                new JMenuItem(new LayerListPopup.InfoAction(this))};//TODO here infos about the linked videos
-	}
-	  
+                new LayerListPopup.InfoAction(this)};//TODO here infos about the linked videos
+	}
+
 
 
@@ -119,9 +97,9 @@
 	@Override
 	public void mergeFrom(Layer arg0) {
-		
-	}
-
-	
-	
+
+	}
+
+
+
 	@Override
 	//Draw the current position, infos, waypoints
@@ -177,5 +155,5 @@
 			{
 				p=Main.map.mapView.getPoint(iconPosition.getEastNorth());
-				icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);				
+				icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);
 				g.drawString(mins.format(iconPosition.getTime()),p.x-10,p.y-10);
 			}
@@ -185,10 +163,10 @@
 			if (player.getCurr()!=null){
 			p=Main.map.mapView.getPoint(player.getCurr().getEastNorth());
-			icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);			
+			icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);
 			g.drawString(ms.format(player.getRelativeTime()),p.x-10,p.y-10);
 			}
 		}
 	}
-	
+
 	//finds the first waypoint that is nearby the given point
 	private WayPoint getNearestWayPoint(Point mouse)
@@ -202,13 +180,13 @@
 			p = Main.map.mapView.getPoint(n.getEastNorth());
 			if (rect.contains(p))
-			{				
+			{
 				return n;
 			}
-			
+
 		}
 		return null;
-		
-	}
-	
+
+	}
+
 	//upper left corner like rectangle
 	private Rectangle getIconRect()
@@ -225,8 +203,8 @@
 	}
 
-	public void mouseClicked(MouseEvent e) {		
-	}
-
-	public void mouseEntered(MouseEvent arg0) {	
+	public void mouseClicked(MouseEvent e) {
+	}
+
+	public void mouseEntered(MouseEvent arg0) {
 	}
 
@@ -247,9 +225,9 @@
 			}
 		}
-		
-	}
-	
+
+	}
+
 	//
-	public void mouseReleased(MouseEvent e) {		
+	public void mouseReleased(MouseEvent e) {
 		//only leftclicks on our layer
 		if(e.getButton() == MouseEvent.BUTTON1) {
@@ -270,11 +248,11 @@
 			Main.map.mapView.repaint();
 		}
-		
-	}
-	
+
+	}
+
 	//slide and restrict during movement
-	public void mouseDragged(MouseEvent e) {		
+	public void mouseDragged(MouseEvent e) {
 		if(dragIcon)
-		{			
+		{
 			mouse=e.getPoint();
 			//restrict to GPS track
@@ -286,7 +264,7 @@
 
 	//visualize drag&drop
-	public void mouseMoved(MouseEvent e) {		
+	public void mouseMoved(MouseEvent e) {
 		if (player.getCurr()!=null)
-		{						
+		{
 			if (getIconRect().contains(e.getPoint()))
 			{
@@ -298,12 +276,12 @@
 			}
 		}
-		
+
 	}
 
 	public void setGPSPlayer(GPSVideoPlayer player) {
 		this.gps = player;
-		
-	}
-	
+
+	}
+
 	public static void addObserver(PlayerObserver observer) {
 
@@ -312,5 +290,5 @@
     }
 
- 
+
 
     public static void removeObserver(PlayerObserver observer) {
Index: /applications/editors/josm/plugins/wmsplugin/.classpath
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/.classpath	(revision 22549)
+++ /applications/editors/josm/plugins/wmsplugin/.classpath	(revision 22550)
@@ -2,4 +2,5 @@
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry including="images/" kind="src" path=""/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
Index: /applications/editors/josm/plugins/wmsplugin/build.xml
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/build.xml	(revision 22549)
+++ /applications/editors/josm/plugins/wmsplugin/build.xml	(revision 22550)
@@ -29,5 +29,5 @@
 
 	<property name="commit.message" value="add commit message" />
-	<property name="plugin.main.version" value="2830" />
+	<property name="plugin.main.version" value="3408" />
 
 
@@ -93,8 +93,8 @@
 
 	<!--
-	************************** Publishing the plugin *********************************** 
+	************************** Publishing the plugin ***********************************
 	-->
 	<!--
-	** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+	** extracts the JOSM release for the JOSM version in ../core and saves it in the
 	** property ${coreversion.info.entry.revision}
 	**
@@ -145,15 +145,15 @@
 
 	<!--
-	** commits the plugin.jar 
+	** commits the plugin.jar
 	-->
 	<target name="commit-dist">
 		<echo>
 	***** Properties of published ${plugin.jar} *****
-	Commit message    : '${commit.message}'					
+	Commit message    : '${commit.message}'
 	Plugin-Mainversion: ${plugin.main.version}
 	JOSM build version: ${coreversion.info.entry.revision}
 	Plugin-Version    : ${version.entry.commit.revision}
-	***** / Properties of published ${plugin.jar} *****					
-						
+	***** / Properties of published ${plugin.jar} *****
+
 	Now commiting ${plugin.jar} ...
 	</echo>
Index: /applications/editors/josm/plugins/wmsplugin/josm-wmsplugin.launch
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/josm-wmsplugin.launch	(revision 22549)
+++ /applications/editors/josm/plugins/wmsplugin/josm-wmsplugin.launch	(revision 22550)
@@ -7,5 +7,5 @@
 <listEntry value="1"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JDK 5"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JDK 6"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.openstreetmap.josm.gui.MainApplication"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="wmsplugin"/>
Index: /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java
===================================================================
--- /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 22549)
+++ /applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java	(revision 22550)
@@ -13,15 +13,15 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JFileChooser;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
-import javax.swing.JSeparator;
 
 import org.openstreetmap.josm.Main;
@@ -30,6 +30,9 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.ProjectionBounds;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
+import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
@@ -38,6 +41,4 @@
 import org.openstreetmap.josm.io.CacheFiles;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
-import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 
 /**
@@ -46,450 +47,480 @@
  */
 public class WMSLayer extends Layer implements PreferenceChangedListener {
-    protected static final Icon icon =
-        new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
-
-    public int messageNum = 5; //limit for messages per layer
-    protected MapView mv;
-    protected String resolution;
-    protected boolean stopAfterPaint = false;
-    protected int imageSize = 500;
-    protected int dax = 10;
-    protected int day = 10;
-    protected int minZoom = 3;
-    protected double dx = 0.0;
-    protected double dy = 0.0;
-    protected double pixelPerDegree;
-    protected GeorefImage[][] images = new GeorefImage[dax][day];
-    JCheckBoxMenuItem startstop = new JCheckBoxMenuItem(tr("Automatic downloading"), true);
-    protected JCheckBoxMenuItem alphaChannel = new JCheckBoxMenuItem(new ToggleAlphaAction());
-    protected String baseURL;
-    protected String cookies;
-    protected final int serializeFormatVersion = 5;
-
-    private ExecutorService executor = null;
-
-    /** set to true if this layer uses an invalid base url */
-    private boolean usesInvalidUrl = false;
-    /** set to true if the user confirmed to use an potentially invalid WMS base url */
-    private boolean isInvalidUrlConfirmed = false;
-
-    public WMSLayer() {
-        this(tr("Blank Layer"), null, null);
-        initializeImages();
-        mv = Main.map.mapView;
-    }
-
-    public WMSLayer(String name, String baseURL, String cookies) {
-        super(name);
-        alphaChannel.setSelected(Main.pref.getBoolean("wmsplugin.alpha_channel"));
-        setBackgroundLayer(true); /* set global background variable */
-        initializeImages();
-        this.baseURL = baseURL;
-        this.cookies = cookies;
-        WMSGrabber.getProjection(baseURL, true);
-        mv = Main.map.mapView;
-
-        // quick hack to predefine the PixelDensity to reuse the cache
-        int codeIndex = getName().indexOf("#PPD=");
-        if (codeIndex != -1) {
-            pixelPerDegree = Double.valueOf(getName().substring(codeIndex+5));
-        } else {
-            pixelPerDegree = getPPD();
-        }
-        resolution = mv.getDist100PixelText();
-
-        executor = Executors.newFixedThreadPool(
-            Main.pref.getInteger("wmsplugin.numThreads",
-            WMSPlugin.simultaneousConnections));
-        if (baseURL != null && !baseURL.startsWith("html:") && !WMSGrabber.isUrlWithPatterns(baseURL)) {
-            if (!(baseURL.endsWith("&") || baseURL.endsWith("?"))) {
-                if (!confirmMalformedUrl(baseURL)) {
-                    System.out.println(tr("Warning: WMS layer deactivated because of malformed base url ''{0}''", baseURL));
-                    usesInvalidUrl = true;
-                    setName(getName() + tr("(deactivated)"));
-                    return;
-                } else {
-                    isInvalidUrlConfirmed = true;
-                }
-            }
-        }
-
-        Main.pref.addPreferenceChangeListener(this);
-    }
-
-    public boolean hasAutoDownload(){
-        return startstop.isSelected();
-    }
-
-    public double getDx(){
-        return dx;
-    }
-
-    public double getDy(){
-        return dy;
-    }
-
-    @Override
-    public void destroy() {
-        try {
-            executor.shutdownNow();
-            // Might not be initialized, so catch NullPointer as well
-        } catch(Exception x) {
-            x.printStackTrace();
-        }
-    }
-
-    public double getPPD(){
-        ProjectionBounds bounds = mv.getProjectionBounds();
-        return mv.getWidth() / (bounds.max.east() - bounds.min.east());
-    }
-
-    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);
-            }
-        }
-    }
-
-    @Override public Icon getIcon() {
-        return icon;
-    }
-
-    @Override public String getToolTipText() {
-        if(startstop.isSelected())
-            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
-        else
-            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
-    }
-
-    @Override public boolean isMergable(Layer other) {
-        return false;
-    }
-
-    @Override public void mergeFrom(Layer from) {
-    }
-
-    private ProjectionBounds XYtoBounds (int x, int y) {
-        return new ProjectionBounds(
-            new EastNorth(      x * imageSize / pixelPerDegree,       y * imageSize / pixelPerDegree),
-            new EastNorth((x + 1) * imageSize / pixelPerDegree, (y + 1) * imageSize / pixelPerDegree));
-    }
-
-    private int modulo (int a, int b) {
-        return a % b >= 0 ? a%b : a%b+b;
-    }
-
-    private boolean zoomIsTooBig() {
-        //don't download when it's too outzoomed
-        return pixelPerDegree / getPPD() > minZoom;
-    }
-
-    @Override public void paint(Graphics2D g, final MapView mv, Bounds bounds) {
-        if(baseURL == null) return;
-        if (usesInvalidUrl && !isInvalidUrlConfirmed) return;
-
-        if (zoomIsTooBig()) {
-            for(int x = 0; x<dax; ++x) {
-                for(int y = 0; y<day; ++y) {
-                    images[modulo(x,dax)][modulo(y,day)].paint(g, mv, dx, dy);
-                }
-            }
-        } else {
-            downloadAndPaintVisible(g, mv, false);
-        }
-    }
-
-    public void displace(double dx, double dy) {
-        this.dx += dx;
-        this.dy += dy;
-    }
-
-    protected boolean confirmMalformedUrl(String url) {
-        if (isInvalidUrlConfirmed)
-            return true;
-        String msg  = tr("<html>The base URL<br>"
-            + "''{0}''<br>"
-            + "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
-            + "This is likely to lead to invalid WMS request. You should check your<br>"
-            + "preference settings.<br>"
-            + "Do you want to fetch WMS tiles anyway?",
-            url);
-        String [] options = new String[] {
-            tr("Yes, fetch images"),
-            tr("No, abort")
-        };
-        int ret = JOptionPane.showOptionDialog(
-            Main.parent,
-            msg,
-            tr("Invalid URL?"),
-            JOptionPane.YES_NO_OPTION,
-            JOptionPane.WARNING_MESSAGE,
-            null,
-            options, options[1]
-        );
-        switch(ret) {
-        case JOptionPane.YES_OPTION: return true;
-        default: return false;
-        }
-    }
-
-    protected void downloadAndPaintVisible(Graphics g, final MapView mv,
-    boolean real){
-        if (usesInvalidUrl)
-            return;
-
-        ProjectionBounds bounds = mv.getProjectionBounds();
-        int bminx= (int)Math.floor (((bounds.min.east() - dx) * pixelPerDegree) / imageSize );
-        int bminy= (int)Math.floor (((bounds.min.north() - dy) * pixelPerDegree) / imageSize );
-        int bmaxx= (int)Math.ceil  (((bounds.max.east() - dx) * pixelPerDegree) / imageSize );
-        int bmaxy= (int)Math.ceil  (((bounds.max.north() - dy) * pixelPerDegree) / imageSize );
-
-        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, dx, dy) || img.infotext) && !img.downloadingStarted){
-                    img.downloadingStarted = true;
-                    img.image = null;
-                    img.flushedResizedCachedInstance();
-                    Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
-                    if(!gr.loadFromCache(real)){
-                        gr.setPriority(1);
-                        executor.submit(gr);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override public void visitBoundingBox(BoundingXYVisitor v) {
-        for(int x = 0; x<dax; ++x) {
-            for(int y = 0; y<day; ++y)
-                if(images[x][y].image!=null){
-                    v.visit(images[x][y].min);
-                    v.visit(images[x][y].max);
-                }
-        }
-    }
-
-    @Override public Object getInfoComponent() {
-        return getToolTipText();
-    }
-
-    @Override public Component[] getMenuEntries() {
-        return new Component[]{
-            new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
-            new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
-            new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
-            new JSeparator(),
-            new JMenuItem(new LoadWmsAction()),
-            new JMenuItem(new SaveWmsAction()),
-            new JMenuItem(new BookmarkWmsAction()),
-            new JSeparator(),
-            startstop,
-            alphaChannel,
-            new JMenuItem(new ChangeResolutionAction()),
-            new JMenuItem(new ReloadErrorTilesAction()),
-            new JMenuItem(new DownloadAction()),
-            new JSeparator(),
-            new JMenuItem(new LayerListPopup.InfoAction(this))
-        };
-    }
-
-    public GeorefImage findImage(EastNorth eastNorth) {
-        for(int x = 0; x<dax; ++x) {
-            for(int y = 0; y<day; ++y)
-                if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
-                    if(images[x][y].contains(eastNorth, dx, dy))
-                        return images[x][y];
-        }
-        return null;
-    }
-
-    public class DownloadAction extends AbstractAction {
-        public DownloadAction() {
-            super(tr("Download visible tiles"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            if (zoomIsTooBig()) {
-                JOptionPane.showMessageDialog(
-                    Main.parent,
-                    tr("The requested area is too big. Please zoom in a little, or change resolution"),
-                    tr("Error"),
-                    JOptionPane.ERROR_MESSAGE
-                );
-            } else {
-                downloadAndPaintVisible(mv.getGraphics(), mv, true);
-            }
-        }
-    }
-
-    public class ChangeResolutionAction extends AbstractAction {
-        public ChangeResolutionAction() {
-            super(tr("Change resolution"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            initializeImages();
-            resolution = mv.getDist100PixelText();
-            pixelPerDegree = getPPD();
-            mv.repaint();
-        }
-    }
-
-    public class ReloadErrorTilesAction extends AbstractAction {
-        public ReloadErrorTilesAction() {
-            super(tr("Reload erroneous tiles"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            // Delete small files, because they're probably blank tiles.
-            // See https://josm.openstreetmap.de/ticket/2307
-            WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
-
-            for (int x = 0; x < dax; ++x) {
-                for (int y = 0; y < day; ++y) {
-                    GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
-                    if(img.failed){
-                        img.image = null;
-                        img.flushedResizedCachedInstance();
-                        img.downloadingStarted = false;
-                        img.failed = false;
-                        mv.repaint();
-                    }
-                }
-            }
-        }
-    }
-
-    public class ToggleAlphaAction extends AbstractAction {
-        public ToggleAlphaAction() {
-            super(tr("Alpha channel"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
-            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) {
-                for (int y = 0; y < day; ++y) {
-                    GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
-                    img.flushedResizedCachedInstance();
-                }
-            }
-            mv.repaint();
-        }
-    }
-
-    public class SaveWmsAction extends AbstractAction {
-        public SaveWmsAction() {
-            super(tr("Save WMS layer to file"), ImageProvider.get("save"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            File f = SaveActionBase.createAndOpenSaveFileChooser(
-                tr("Save WMS layer"), ".wms");
-            try {
-                if (f != null) {
-                    ObjectOutputStream oos = new ObjectOutputStream(
-                        new FileOutputStream(f)
-                    );
-                    oos.writeInt(serializeFormatVersion);
-                    oos.writeInt(dax);
-                    oos.writeInt(day);
-                    oos.writeInt(imageSize);
-                    oos.writeDouble(pixelPerDegree);
-                    oos.writeObject(getName());
-                    oos.writeObject(baseURL);
-                    oos.writeObject(images);
-                    oos.close();
-                }
-            } catch (Exception ex) {
-                ex.printStackTrace(System.out);
-            }
-        }
-    }
-
-    public class LoadWmsAction extends AbstractAction {
-        public LoadWmsAction() {
-            super(tr("Load WMS layer from file"), ImageProvider.get("load"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
-                false, tr("Load WMS layer"), "wms");
-            if(fc == null) return;
-            File f = fc.getSelectedFile();
-            if (f == null) return;
-            try
-            {
-                FileInputStream fis = new FileInputStream(f);
-                ObjectInputStream ois = new ObjectInputStream(fis);
-                int sfv = ois.readInt();
-                if (sfv != serializeFormatVersion) {
-                    JOptionPane.showMessageDialog(Main.parent,
-                        tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
-                        tr("File Format Error"),
-                        JOptionPane.ERROR_MESSAGE);
-                    return;
-                }
-                startstop.setSelected(false);
-                dax = ois.readInt();
-                day = ois.readInt();
-                imageSize = ois.readInt();
-                pixelPerDegree = ois.readDouble();
-                setName((String)ois.readObject());
-                baseURL = (String) ois.readObject();
-                images = (GeorefImage[][])ois.readObject();
-                ois.close();
-                fis.close();
-                mv.repaint();
-            }
-            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;
-            }
-        }
-    }
-    /**
-     * This action will add a WMS layer menu entry with the current WMS layer
-     * URL and name extended by the current resolution.
-     * When using the menu entry again, the WMS cache will be used properly.
-     */
-    public class BookmarkWmsAction extends AbstractAction {
-        public BookmarkWmsAction() {
-            super(tr("Set WMS Bookmark"));
-        }
-        public void actionPerformed(ActionEvent ev) {
-            int i = 0;
-            while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
-                i++;
-            }
-            String baseName;
-            // cut old parameter
-            int parameterIndex = getName().indexOf("#PPD=");
-            if (parameterIndex != -1) {
-                baseName = getName().substring(0,parameterIndex);
-            }
-            else {
-                baseName = getName();
-            }
-            Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
-            Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name",
-                baseName + "#PPD=" + pixelPerDegree );
-            WMSPlugin.refreshMenu();
-        }
-    }
-
-    public void preferenceChanged(PreferenceChangeEvent event) {
-        if (event.getKey().equals("wmsplugin.simultaneousConnections")) {
-            executor.shutdownNow();
-            executor = Executors.newFixedThreadPool(
-                Main.pref.getInteger("wmsplugin.numThreads",
-                WMSPlugin.simultaneousConnections));
-        }
-    }
+	protected static final Icon icon =
+		new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
+
+	private static final BooleanProperty PROP_ALPHA_CHANNEL = new BooleanProperty("wmsplugin.alpha_channel", true);
+
+	public int messageNum = 5; //limit for messages per layer
+	protected MapView mv;
+	protected String resolution;
+	protected boolean stopAfterPaint = false;
+	protected int imageSize = 500;
+	protected int dax = 10;
+	protected int day = 10;
+	protected int minZoom = 3;
+	protected double dx = 0.0;
+	protected double dy = 0.0;
+	protected double pixelPerDegree;
+	protected GeorefImage[][] images = new GeorefImage[dax][day];
+	protected String baseURL;
+	protected String cookies;
+	protected final int serializeFormatVersion = 5;
+	protected boolean autoDownloadEnabled = true;
+
+	private ExecutorService executor = null;
+
+	/** set to true if this layer uses an invalid base url */
+	private boolean usesInvalidUrl = false;
+	/** set to true if the user confirmed to use an potentially invalid WMS base url */
+	private boolean isInvalidUrlConfirmed = false;
+
+	public WMSLayer() {
+		this(tr("Blank Layer"), null, null);
+		initializeImages();
+		mv = Main.map.mapView;
+	}
+
+	public WMSLayer(String name, String baseURL, String cookies) {
+		super(name);
+		setBackgroundLayer(true); /* set global background variable */
+		initializeImages();
+		this.baseURL = baseURL;
+		this.cookies = cookies;
+		WMSGrabber.getProjection(baseURL, true);
+		mv = Main.map.mapView;
+
+		// quick hack to predefine the PixelDensity to reuse the cache
+		int codeIndex = getName().indexOf("#PPD=");
+		if (codeIndex != -1) {
+			pixelPerDegree = Double.valueOf(getName().substring(codeIndex+5));
+		} else {
+			pixelPerDegree = getPPD();
+		}
+		resolution = mv.getDist100PixelText();
+
+		executor = Executors.newFixedThreadPool(
+				Main.pref.getInteger("wmsplugin.numThreads",
+						WMSPlugin.simultaneousConnections));
+		if (baseURL != null && !baseURL.startsWith("html:") && !WMSGrabber.isUrlWithPatterns(baseURL)) {
+			if (!(baseURL.endsWith("&") || baseURL.endsWith("?"))) {
+				if (!confirmMalformedUrl(baseURL)) {
+					System.out.println(tr("Warning: WMS layer deactivated because of malformed base url ''{0}''", baseURL));
+					usesInvalidUrl = true;
+					setName(getName() + tr("(deactivated)"));
+					return;
+				} else {
+					isInvalidUrlConfirmed = true;
+				}
+			}
+		}
+
+		Main.pref.addPreferenceChangeListener(this);
+	}
+
+	public boolean hasAutoDownload(){
+		return autoDownloadEnabled;
+	}
+
+	public double getDx(){
+		return dx;
+	}
+
+	public double getDy(){
+		return dy;
+	}
+
+	@Override
+	public void destroy() {
+		try {
+			executor.shutdownNow();
+			// Might not be initialized, so catch NullPointer as well
+		} catch(Exception x) {
+			x.printStackTrace();
+		}
+	}
+
+	public double getPPD(){
+		ProjectionBounds bounds = mv.getProjectionBounds();
+		return mv.getWidth() / (bounds.max.east() - bounds.min.east());
+	}
+
+	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);
+			}
+		}
+	}
+
+	@Override public Icon getIcon() {
+		return icon;
+	}
+
+	@Override public String getToolTipText() {
+		if(autoDownloadEnabled)
+			return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
+		else
+			return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
+	}
+
+	@Override public boolean isMergable(Layer other) {
+		return false;
+	}
+
+	@Override public void mergeFrom(Layer from) {
+	}
+
+	private ProjectionBounds XYtoBounds (int x, int y) {
+		return new ProjectionBounds(
+				new EastNorth(      x * imageSize / pixelPerDegree,       y * imageSize / pixelPerDegree),
+				new EastNorth((x + 1) * imageSize / pixelPerDegree, (y + 1) * imageSize / pixelPerDegree));
+	}
+
+	private int modulo (int a, int b) {
+		return a % b >= 0 ? a%b : a%b+b;
+	}
+
+	private boolean zoomIsTooBig() {
+		//don't download when it's too outzoomed
+		return pixelPerDegree / getPPD() > minZoom;
+	}
+
+	@Override public void paint(Graphics2D g, final MapView mv, Bounds bounds) {
+		if(baseURL == null) return;
+		if (usesInvalidUrl && !isInvalidUrlConfirmed) return;
+
+		if (zoomIsTooBig()) {
+			for(int x = 0; x<dax; ++x) {
+				for(int y = 0; y<day; ++y) {
+					images[modulo(x,dax)][modulo(y,day)].paint(g, mv, dx, dy);
+				}
+			}
+		} else {
+			downloadAndPaintVisible(g, mv, false);
+		}
+	}
+
+	public void displace(double dx, double dy) {
+		this.dx += dx;
+		this.dy += dy;
+	}
+
+	protected boolean confirmMalformedUrl(String url) {
+		if (isInvalidUrlConfirmed)
+			return true;
+		String msg  = tr("<html>The base URL<br>"
+				+ "''{0}''<br>"
+				+ "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
+				+ "This is likely to lead to invalid WMS request. You should check your<br>"
+				+ "preference settings.<br>"
+				+ "Do you want to fetch WMS tiles anyway?",
+				url);
+		String [] options = new String[] {
+				tr("Yes, fetch images"),
+				tr("No, abort")
+		};
+		int ret = JOptionPane.showOptionDialog(
+				Main.parent,
+				msg,
+				tr("Invalid URL?"),
+				JOptionPane.YES_NO_OPTION,
+				JOptionPane.WARNING_MESSAGE,
+				null,
+				options, options[1]
+		);
+		switch(ret) {
+		case JOptionPane.YES_OPTION: return true;
+		default: return false;
+		}
+	}
+
+	protected void downloadAndPaintVisible(Graphics g, final MapView mv,
+			boolean real){
+		if (usesInvalidUrl)
+			return;
+
+		ProjectionBounds bounds = mv.getProjectionBounds();
+		int bminx= (int)Math.floor (((bounds.min.east() - dx) * pixelPerDegree) / imageSize );
+		int bminy= (int)Math.floor (((bounds.min.north() - dy) * pixelPerDegree) / imageSize );
+		int bmaxx= (int)Math.ceil  (((bounds.max.east() - dx) * pixelPerDegree) / imageSize );
+		int bmaxy= (int)Math.ceil  (((bounds.max.north() - dy) * pixelPerDegree) / imageSize );
+
+		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, dx, dy) || img.infotext) && !img.downloadingStarted){
+					img.downloadingStarted = true;
+					img.image = null;
+					img.flushedResizedCachedInstance();
+					Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
+					if(!gr.loadFromCache(real)){
+						gr.setPriority(1);
+						executor.submit(gr);
+					}
+				}
+			}
+		}
+	}
+
+	@Override public void visitBoundingBox(BoundingXYVisitor v) {
+		for(int x = 0; x<dax; ++x) {
+			for(int y = 0; y<day; ++y)
+				if(images[x][y].image!=null){
+					v.visit(images[x][y].min);
+					v.visit(images[x][y].max);
+				}
+		}
+	}
+
+	@Override public Object getInfoComponent() {
+		return getToolTipText();
+	}
+
+	@Override public Action[] getMenuEntries() {
+		return new Action[]{
+				LayerListDialog.getInstance().createActivateLayerAction(this),
+				LayerListDialog.getInstance().createShowHideLayerAction(),
+				LayerListDialog.getInstance().createDeleteLayerAction(),
+				SeparatorLayerAction.INSTANCE,
+				new LoadWmsAction(),
+				new SaveWmsAction(),
+				new BookmarkWmsAction(),
+				SeparatorLayerAction.INSTANCE,
+				new StartStopAction(),
+				new ToggleAlphaAction(),
+				new ChangeResolutionAction(),
+				new ReloadErrorTilesAction(),
+				new DownloadAction(),
+				SeparatorLayerAction.INSTANCE,
+				new LayerListPopup.InfoAction(this)
+		};
+	}
+
+	public GeorefImage findImage(EastNorth eastNorth) {
+		for(int x = 0; x<dax; ++x) {
+			for(int y = 0; y<day; ++y)
+				if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
+					if(images[x][y].contains(eastNorth, dx, dy))
+						return images[x][y];
+		}
+		return null;
+	}
+
+	public class DownloadAction extends AbstractAction {
+		public DownloadAction() {
+			super(tr("Download visible tiles"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			if (zoomIsTooBig()) {
+				JOptionPane.showMessageDialog(
+						Main.parent,
+						tr("The requested area is too big. Please zoom in a little, or change resolution"),
+						tr("Error"),
+						JOptionPane.ERROR_MESSAGE
+				);
+			} else {
+				downloadAndPaintVisible(mv.getGraphics(), mv, true);
+			}
+		}
+	}
+
+	public class ChangeResolutionAction extends AbstractAction {
+		public ChangeResolutionAction() {
+			super(tr("Change resolution"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			initializeImages();
+			resolution = mv.getDist100PixelText();
+			pixelPerDegree = getPPD();
+			mv.repaint();
+		}
+	}
+
+	public class ReloadErrorTilesAction extends AbstractAction {
+		public ReloadErrorTilesAction() {
+			super(tr("Reload erroneous tiles"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			// Delete small files, because they're probably blank tiles.
+			// See https://josm.openstreetmap.de/ticket/2307
+			WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
+
+			for (int x = 0; x < dax; ++x) {
+				for (int y = 0; y < day; ++y) {
+					GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
+					if(img.failed){
+						img.image = null;
+						img.flushedResizedCachedInstance();
+						img.downloadingStarted = false;
+						img.failed = false;
+						mv.repaint();
+					}
+				}
+			}
+		}
+	}
+
+	public class ToggleAlphaAction extends AbstractAction implements LayerAction {
+		public ToggleAlphaAction() {
+			super(tr("Alpha channel"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
+			boolean alphaChannel = checkbox.isSelected();
+			PROP_ALPHA_CHANNEL.put(alphaChannel);
+
+			// clear all resized cached instances and repaint the layer
+			for (int x = 0; x < dax; ++x) {
+				for (int y = 0; y < day; ++y) {
+					GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
+					img.flushedResizedCachedInstance();
+				}
+			}
+			mv.repaint();
+		}
+		public Component createMenuComponent() {
+			JCheckBoxMenuItem item = new JCheckBoxMenuItem(this);
+			item.setSelected(PROP_ALPHA_CHANNEL.get());
+			return item;
+		}
+		public boolean supportLayers(List<Layer> layers) {
+			return layers.size() == 1 && layers.get(0) instanceof WMSLayer;
+		}
+	}
+
+	public class SaveWmsAction extends AbstractAction {
+		public SaveWmsAction() {
+			super(tr("Save WMS layer to file"), ImageProvider.get("save"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			File f = SaveActionBase.createAndOpenSaveFileChooser(
+					tr("Save WMS layer"), ".wms");
+			try {
+				if (f != null) {
+					ObjectOutputStream oos = new ObjectOutputStream(
+							new FileOutputStream(f)
+					);
+					oos.writeInt(serializeFormatVersion);
+					oos.writeInt(dax);
+					oos.writeInt(day);
+					oos.writeInt(imageSize);
+					oos.writeDouble(pixelPerDegree);
+					oos.writeObject(getName());
+					oos.writeObject(baseURL);
+					oos.writeObject(images);
+					oos.close();
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace(System.out);
+			}
+		}
+	}
+
+	public class LoadWmsAction extends AbstractAction {
+		public LoadWmsAction() {
+			super(tr("Load WMS layer from file"), ImageProvider.get("load"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
+					false, tr("Load WMS layer"), "wms");
+			if(fc == null) return;
+			File f = fc.getSelectedFile();
+			if (f == null) return;
+			try
+			{
+				FileInputStream fis = new FileInputStream(f);
+				ObjectInputStream ois = new ObjectInputStream(fis);
+				int sfv = ois.readInt();
+				if (sfv != serializeFormatVersion) {
+					JOptionPane.showMessageDialog(Main.parent,
+							tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
+							tr("File Format Error"),
+							JOptionPane.ERROR_MESSAGE);
+					return;
+				}
+				autoDownloadEnabled = false;
+				dax = ois.readInt();
+				day = ois.readInt();
+				imageSize = ois.readInt();
+				pixelPerDegree = ois.readDouble();
+				setName((String)ois.readObject());
+				baseURL = (String) ois.readObject();
+				images = (GeorefImage[][])ois.readObject();
+				ois.close();
+				fis.close();
+				mv.repaint();
+			}
+			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;
+			}
+		}
+	}
+	/**
+	 * This action will add a WMS layer menu entry with the current WMS layer
+	 * URL and name extended by the current resolution.
+	 * When using the menu entry again, the WMS cache will be used properly.
+	 */
+	public class BookmarkWmsAction extends AbstractAction {
+		public BookmarkWmsAction() {
+			super(tr("Set WMS Bookmark"));
+		}
+		public void actionPerformed(ActionEvent ev) {
+			int i = 0;
+			while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
+				i++;
+			}
+			String baseName;
+			// cut old parameter
+			int parameterIndex = getName().indexOf("#PPD=");
+			if (parameterIndex != -1) {
+				baseName = getName().substring(0,parameterIndex);
+			}
+			else {
+				baseName = getName();
+			}
+			Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
+			Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name",
+					baseName + "#PPD=" + pixelPerDegree );
+			WMSPlugin.refreshMenu();
+		}
+	}
+
+	private class StartStopAction extends AbstractAction implements LayerAction {
+
+		public StartStopAction() {
+			super(tr("Automatic downloading"));
+		}
+
+		public Component createMenuComponent() {
+			JCheckBoxMenuItem item = new JCheckBoxMenuItem(this);
+			item.setSelected(autoDownloadEnabled);
+			return item;
+		}
+
+		public boolean supportLayers(List<Layer> layers) {
+			return layers.size() == 1 && layers.get(0) instanceof WMSLayer;
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			autoDownloadEnabled = !autoDownloadEnabled;
+		}
+
+	}
+
+	public void preferenceChanged(PreferenceChangeEvent event) {
+		if (event.getKey().equals("wmsplugin.simultaneousConnections")) {
+			executor.shutdownNow();
+			executor = Executors.newFixedThreadPool(
+					Main.pref.getInteger("wmsplugin.numThreads",
+							WMSPlugin.simultaneousConnections));
+		}
+	}
 }
