Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 152)
+++ src/org/openstreetmap/josm/Main.java	(revision 153)
@@ -44,4 +44,5 @@
 import org.openstreetmap.josm.actions.UndoAction;
 import org.openstreetmap.josm.actions.UploadAction;
+import org.openstreetmap.josm.actions.DownloadAction.DownloadTask;
 import org.openstreetmap.josm.actions.mapmode.MapMode;
 import org.openstreetmap.josm.data.Bounds;
@@ -51,4 +52,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.PleaseWaitDialog;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 import org.openstreetmap.josm.gui.annotation.AnnotationTester;
@@ -58,5 +60,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;
 import org.openstreetmap.josm.plugins.PluginException;
-import org.openstreetmap.josm.plugins.PluginLoader;
+import org.openstreetmap.josm.plugins.PluginInformation;
 import org.openstreetmap.josm.plugins.PluginProxy;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -97,4 +99,9 @@
 	 */
 	public final static Collection<PluginProxy> plugins = new LinkedList<PluginProxy>();
+	/**
+	 * The dialog that gets displayed during background task execution.
+	 */
+	public static PleaseWaitDialog pleaseWaitDlg;
+
 
 	/**
@@ -130,5 +137,5 @@
 
 		for (PluginProxy plugin : plugins)
-            plugin.mapFrameInitialized(old, map);
+			plugin.mapFrameInitialized(old, map);
 	}
 
@@ -249,14 +256,12 @@
 
 		contentPane.updateUI();
-		
 
 		// Plugins
 		if (Main.pref.hasKey("plugins")) {
-			PluginLoader loader = new PluginLoader();
 			for (String pluginName : Main.pref.get("plugins").split(",")) {
 				try {
 					File pluginFile = new File(pref.getPreferencesDir()+"plugins/"+pluginName+".jar");
 					if (pluginFile.exists())
-						plugins.add(loader.loadPlugin(loader.loadClassName(pluginFile), pluginFile));
+						plugins.add(new PluginInformation(pluginFile).load());
 					else
 						JOptionPane.showMessageDialog(Main.parent, tr("Plugin not found: {0}.", pluginName));
@@ -268,4 +273,5 @@
 		}
 	}
+
 	/**
 	 * Add a new layer to the map. If no map exist, create one.
@@ -304,13 +310,13 @@
 
 
-	private static JPanel panel = new JPanel(new BorderLayout());
+	public static JPanel panel = new JPanel(new BorderLayout());
 
 	protected final JMenuBar mainMenu = new JMenuBar();
 	protected static Rectangle bounds;
 
-	private final UndoAction undoAction = new UndoAction();
-	private final RedoAction redoAction = new RedoAction();
-	private final OpenAction openAction = new OpenAction();
-	private final DownloadAction downloadAction = new DownloadAction();
+	public final UndoAction undoAction = new UndoAction();
+	public final RedoAction redoAction = new RedoAction();
+	public final OpenAction openAction = new OpenAction();
+	public final DownloadAction downloadAction = new DownloadAction();
 
 	private final CommandQueueListener redoUndoListener = new CommandQueueListener(){
@@ -374,4 +380,6 @@
 		if (bounds == null)
 			bounds = !args.containsKey("no-fullscreen") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
+
+		pleaseWaitDlg = new PleaseWaitDialog();
 	}
 
@@ -393,6 +401,8 @@
 			if (b == null)
 				JOptionPane.showMessageDialog(Main.parent, tr("Ignoring malformed url: \"{0}\"", s));
-			else
-				main.downloadAction.download(false, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
+			else {
+				DownloadTask osmTask = main.downloadAction.downloadTasks.get(0);
+				osmTask.download(main.downloadAction, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
+			}
 			return;
 		}
@@ -410,5 +420,6 @@
 		if (st.countTokens() == 4) {
 			try {
-				main.downloadAction.download(rawGps, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
+				DownloadTask task = main.downloadAction.downloadTasks.get(rawGps ? 1 : 0);
+				task.download(main.downloadAction, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
 				return;
 			} catch (final NumberFormatException e) {
Index: src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 152)
+++ src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 153)
@@ -14,7 +14,7 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.io.IOException;
-import java.util.Collection;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 
 import javax.swing.DefaultListModel;
@@ -32,96 +32,55 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.BookmarkList;
 import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.WorldChooser;
 import org.openstreetmap.josm.gui.BookmarkList.Bookmark;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.layer.RawGpsLayer;
-import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
-import org.openstreetmap.josm.io.BoundingBoxDownloader;
 import org.openstreetmap.josm.tools.GBC;
-import org.xml.sax.SAXException;
 
 /**
  * Action that opens a connection to the osm server and download map data.
- * 
+ *
  * An dialog is displayed asking the user to specify a rectangle to grab.
  * The url and account settings from the preferences are used.
- *  
+ *
  * @author imi
  */
 public class DownloadAction extends JosmAction {
-	/**
-	 * Open the download dialog and download the data.
-	 * Run in the worker thread.
-	 */
-	private final class DownloadOsmTask extends PleaseWaitRunnable {
-		private final BoundingBoxDownloader reader;
-		private DataSet dataSet;
-
-		private DownloadOsmTask(BoundingBoxDownloader reader) {
-			super(tr("Downloading data"));
-			this.reader = reader;
-			reader.setProgressInformation(currentAction, progress);
-		}
-
-		@Override public void realRun() throws IOException, SAXException {
-			dataSet = reader.parseOsm();
-		}
-
-		@Override protected void finish() {
-			if (dataSet == null)
-				return; // user cancelled download or error occoured
-			if (dataSet.allPrimitives().isEmpty())
-				errorMessage = tr("No data imported.");
-			Main.main.addLayer(new OsmDataLayer(dataSet, tr("Data Layer"), null));
-		}
-
-		@Override protected void cancel() {
-			reader.cancel();
-		}
-	}
-
-
-	private final class DownloadGpsTask extends PleaseWaitRunnable {
-		private final BoundingBoxDownloader reader;
-		private Collection<Collection<GpsPoint>> rawData;
-
-		private DownloadGpsTask(BoundingBoxDownloader reader) {
-			super(tr("Downloading GPS data"));
-			this.reader = reader;
-			reader.setProgressInformation(currentAction, progress);
-		}
-
-		@Override public void realRun() throws IOException, SAXException {
-			rawData = reader.parseRawGps();
-		}
-
-		@Override protected void finish() {
-			if (rawData == null)
-				return;
-			String name = latlon[0].getText() + " " + latlon[1].getText() + " x " + latlon[2].getText() + " " + latlon[3].getText();
-			Main.main.addLayer(new RawGpsLayer(rawData, name, null));
-		}
-
-		@Override protected void cancel() {
-			reader.cancel();
-		}
-	}
-
+
+	public interface DownloadTask {
+		/**
+		 * Execute the download.
+		 */
+		void download(DownloadAction action, double minlat, double minlon, double maxlat, double maxlon);
+		/**
+		 * @return The checkbox presented to the user
+		 */
+		JCheckBox getCheckBox();
+		/**
+		 * @return The name of the preferences suffix to use for storing the
+		 * selection state.
+		 */
+		String getPreferencesSuffix();
+	}
+
+	/**
+	 * The list of download tasks. First entry should be the osm data entry
+	 * and the second the gps entry. After that, plugins can register additional
+	 * download possibilities.
+	 */
+	public final List<DownloadTask> downloadTasks = new ArrayList<DownloadTask>(5);
 
 	/**
 	 * minlat, minlon, maxlat, maxlon
 	 */
-	JTextField[] latlon = new JTextField[]{
+	public JTextField[] latlon = new JTextField[]{
 			new JTextField(9),
 			new JTextField(9),
 			new JTextField(9),
 			new JTextField(9)};
-	JCheckBox rawGps = new JCheckBox(tr("Open as raw gps data"), false);
 
 	public DownloadAction() {
@@ -130,4 +89,7 @@
 		for (JTextField f : latlon)
 			f.setMinimumSize(new Dimension(100,new JTextField().getMinimumSize().height));
+
+		downloadTasks.add(new DownloadOsmTask());
+		downloadTasks.add(new DownloadGpsTask());
 	}
 
@@ -155,10 +117,15 @@
 					mv.getLatLon(0, mv.getHeight()),
 					mv.getLatLon(mv.getWidth(), 0)));
-			rawGps.setSelected(mv.getActiveLayer() instanceof RawGpsLayer);
-		}
-		dlg.add(rawGps, GBC.eop());
+		}
+
+		// adding the download tasks
+		dlg.add(new JLabel(tr("Download the following data:")), GBC.eol().insets(0,5,0,0));
+		for (DownloadTask task : downloadTasks) {
+			dlg.add(task.getCheckBox(), GBC.eol().insets(20,0,0,0));
+			task.getCheckBox().setSelected(Main.pref.getBoolean("download."+task.getPreferencesSuffix()));
+		}
 
 		// OSM url edit
-		dlg.add(new JLabel(tr("URL from www.openstreetmap.org")), GBC.eol());
+		dlg.add(new JLabel(tr("URL from www.openstreetmap.org")), GBC.eol().insets(0,5,0,0));
 		final JTextField osmUrl = new JTextField();
 		dlg.add(osmUrl, GBC.eop().fill(GBC.HORIZONTAL));
@@ -204,5 +171,5 @@
 						if (b != null)
 							setEditBounds(b);
-						else 
+						else
 							for (JTextField f : latlon)
 								f.setText("");
@@ -222,5 +189,4 @@
 					latlon[i].setCaretPosition(0);
 				}
-				rawGps.setSelected(b == null ? false : b.rawgps);
 				osmUrlRefresher.keyTyped(null);
 			}
@@ -267,4 +233,5 @@
 		// Finally: the dialog
 		Bookmark b;
+		boolean anySelected = false;
 		do {
 			final JOptionPane pane = new JOptionPane(dlg, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
@@ -283,7 +250,17 @@
 				return;
 			b = readBookmark();
+
+			for (DownloadTask task : downloadTasks) {
+				if (task.getCheckBox().isSelected()) {
+					anySelected = true;
+					break;
+				}
+			}
+
 			if (b == null)
 				JOptionPane.showMessageDialog(Main.parent,tr("Please enter the desired coordinates or click on a bookmark."));
-		} while (b == null);
+			else if (!anySelected)
+				JOptionPane.showMessageDialog(Main.parent,tr("Please select at least one download data type."));
+		} while (b == null && anySelected);
 
 		double minlon = b.latlon[0];
@@ -291,5 +268,5 @@
 		double maxlon = b.latlon[2];
 		double maxlat = b.latlon[3];
-		download(rawGps.isSelected(), minlon, minlat, maxlon, maxlat);
+		download(minlon, minlat, maxlon, maxlat);
 	}
 
@@ -309,5 +286,4 @@
 				b.latlon[i] = Double.parseDouble(latlon[i].getText());
 			}
-			b.rawgps = rawGps.isSelected();
 			return b;
 		} catch (NumberFormatException x) {
@@ -315,5 +291,4 @@
 		}
 	}
-
 
 	public static Bounds osmurl2bounds(String url) {
@@ -329,5 +304,5 @@
 					map.put(arg.substring(0, eq), Double.parseDouble(arg.substring(eq + 1)));
 				} catch (NumberFormatException e) {
-				}				
+				}
 			}
 		}
@@ -363,9 +338,11 @@
 	 * Do the download for the given area.
 	 */
-	public void download(boolean rawGps, double minlat, double minlon, double maxlat, double maxlon) {
-		BoundingBoxDownloader reader = new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon);
-		PleaseWaitRunnable task = rawGps ? new DownloadGpsTask(reader) : new DownloadOsmTask(reader);
-		Main.worker.execute(task);
-		task.pleaseWaitDlg.setVisible(true);
+	public void download(double minlat, double minlon, double maxlat, double maxlon) {
+		for (DownloadTask task : downloadTasks) {
+			Main.pref.put("download."+task.getPreferencesSuffix(), task.getCheckBox().isSelected());
+			if (task.getCheckBox().isSelected()) {
+				task.download(this, minlat, minlon, maxlat, maxlon);
+			}
+		}
 	}
 }
Index: src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 152)
+++ src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 153)
@@ -26,8 +26,8 @@
 /**
  * Action that opens a connection to the osm server and download map data.
- * 
+ *
  * An dialog is displayed asking the user to specify a rectangle to grab.
  * The url and account settings from the preferences are used.
- *  
+ *
  * @author imi
  */
@@ -46,5 +46,4 @@
 			super(trn("Downloading {0} segment", "Downloading {0} segments", toDownload.size(), toDownload.size()));
 			reader = new ObjectListDownloader(toDownload);
-			reader.setProgressInformation(currentAction, progress);
 		}
 
@@ -71,8 +70,6 @@
 			}
 			reader = new ObjectListDownloader(nodes);
-			reader.setProgressInformation(currentAction, progress);
 			nodesLoaded = true;
 			Main.worker.execute(this);
-			pleaseWaitDlg.setVisible(true);
 		}
 
@@ -105,5 +102,4 @@
 		PleaseWaitRunnable task = new DownloadTask(toDownload);
 		Main.worker.execute(task);
-		task.pleaseWaitDlg.setVisible(true);
 	}
 }
Index: src/org/openstreetmap/josm/actions/ExternalToolsAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 152)
+++ src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 153)
@@ -66,8 +66,8 @@
 			super(msg);
 			this.p = p;
-			currentAction.setText(tr("Executing {0}",getValue(NAME)));
 		}
 
 		@Override protected void realRun() throws SAXException, IOException {
+			Main.pleaseWaitDlg.currentAction.setText(tr("Executing {0}",getValue(NAME)));
 			if (!input.isEmpty()) {
 				fromDataSet = new DataSet();
@@ -201,5 +201,5 @@
 			}
 			if (output != null)
-				dataSet = OsmReader.parseDataSet(p.getInputStream(), currentAction, progress);
+				dataSet = OsmReader.parseDataSet(p.getInputStream(), Main.pleaseWaitDlg.currentAction, Main.pleaseWaitDlg.progress);
 		}
 
@@ -302,5 +302,4 @@
 			PleaseWaitRunnable runner = new ExecuteToolRunner(tr("Executing {0}",getValue(NAME)), p);
 			Main.worker.execute(runner);
-			runner.pleaseWaitDlg.setVisible(true);
 		} catch (IOException e1) {
 			e1.printStackTrace();
Index: src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/UploadAction.java	(revision 152)
+++ src/org/openstreetmap/josm/actions/UploadAction.java	(revision 153)
@@ -26,8 +26,8 @@
 /**
  * Action that opens a connection to the osm server and upload all changes.
- * 
+ *
  * An dialog is displayed asking the user to specify a rectangle to grab.
  * The url and account settings from the preferences are used.
- *  
+ *
  * @author imi
  */
@@ -75,5 +75,4 @@
 		PleaseWaitRunnable uploadTask = new PleaseWaitRunnable(tr("Uploading data")){
 			@Override protected void realRun() throws SAXException {
-				server.setProgressInformation(currentAction, progress);
 				server.uploadOsm(all);
 			}
@@ -86,5 +85,4 @@
 		};
 		Main.worker.execute(uploadTask);
-		uploadTask.pleaseWaitDlg.setVisible(true);
 	}
 
@@ -129,5 +127,5 @@
 		}
 
-		return JOptionPane.showConfirmDialog(Main.parent, p, tr("Upload this changes?"), 
+		return JOptionPane.showConfirmDialog(Main.parent, p, tr("Upload this changes?"),
 				JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
 	}
Index: src/org/openstreetmap/josm/actions/WmsServerAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/WmsServerAction.java	(revision 152)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package org.openstreetmap.josm.actions;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.Main;
-
-public class WmsServerAction extends JosmAction {
-
-    public WmsServerAction() {
-        super(tr("Show background"), "wmsserver", tr("Download and show landsat background images."), KeyEvent.VK_B);
-    }
-
-    public void actionPerformed(ActionEvent e) {
-    	JOptionPane.showMessageDialog(Main.parent, tr("Not implemented yet."));
-    }
-}
Index: src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 153)
+++ src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 153)
@@ -0,0 +1,59 @@
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.swing.JCheckBox;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.DownloadAction;
+import org.openstreetmap.josm.actions.DownloadAction.DownloadTask;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.layer.RawGpsLayer;
+import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
+import org.openstreetmap.josm.io.BoundingBoxDownloader;
+import org.xml.sax.SAXException;
+
+public class DownloadGpsTask extends PleaseWaitRunnable implements DownloadTask {
+	private DownloadAction action;
+	private BoundingBoxDownloader reader;
+	private Collection<Collection<GpsPoint>> rawData;
+	private JCheckBox checkBox = new JCheckBox(tr("Raw GPS data"));
+
+	public DownloadGpsTask() {
+		super(tr("Downloading GPS data"));
+	}
+
+	@Override public void realRun() throws IOException, SAXException {
+		rawData = reader.parseRawGps();
+	}
+
+	@Override protected void finish() {
+		if (rawData == null)
+			return;
+		String name = action.latlon[0].getText() + " " + action.latlon[1].getText() + " x " + this.action.latlon[2].getText() + " " + this.action.latlon[3].getText();
+		Main.main.addLayer(new RawGpsLayer(rawData, name, null));
+	}
+
+	@Override protected void cancel() {
+		if (reader != null)
+			reader.cancel();
+	}
+
+
+	public void download(DownloadAction action, double minlat, double minlon, double maxlat, double maxlon) {
+		this.action = action;
+		reader = new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon);
+		Main.worker.execute(this);
+	}
+
+	public JCheckBox getCheckBox() {
+	    return checkBox;
+    }
+
+	public String getPreferencesSuffix() {
+	    return "gps";
+    }
+}
Index: src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 153)
+++ src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 153)
@@ -0,0 +1,60 @@
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+
+import javax.swing.JCheckBox;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.DownloadAction;
+import org.openstreetmap.josm.actions.DownloadAction.DownloadTask;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.io.BoundingBoxDownloader;
+import org.xml.sax.SAXException;
+
+/**
+ * Open the download dialog and download the data.
+ * Run in the worker thread.
+ */
+public class DownloadOsmTask extends PleaseWaitRunnable implements DownloadTask {
+	private BoundingBoxDownloader reader;
+	private DataSet dataSet;
+	private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"));
+
+	public DownloadOsmTask() {
+		super(tr("Downloading data"));
+	}
+
+	@Override public void realRun() throws IOException, SAXException {
+		dataSet = reader.parseOsm();
+	}
+
+	@Override protected void finish() {
+		if (dataSet == null)
+			return; // user cancelled download or error occoured
+		if (dataSet.allPrimitives().isEmpty())
+			errorMessage = tr("No data imported.");
+		Main.main.addLayer(new OsmDataLayer(dataSet, tr("Data Layer"), null));
+	}
+
+	@Override protected void cancel() {
+		if (reader != null)
+			reader.cancel();
+	}
+
+	public void download(DownloadAction action, double minlat, double minlon, double maxlat, double maxlon) {
+		reader = new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon);
+		Main.worker.execute(this);
+    }
+
+	public JCheckBox getCheckBox() {
+	    return checkBox;
+    }
+
+	public String getPreferencesSuffix() {
+	    return "osm";
+    }
+}
Index: src/org/openstreetmap/josm/gui/BookmarkList.java
===================================================================
--- src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/BookmarkList.java	(revision 153)
@@ -3,5 +3,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Component;
 import java.io.BufferedReader;
 import java.io.File;
@@ -12,12 +11,9 @@
 import java.util.StringTokenizer;
 
-import javax.swing.DefaultListCellRenderer;
 import javax.swing.DefaultListModel;
-import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -34,5 +30,4 @@
 		public String name;
 		public double[] latlon = new double[4]; // minlat, minlon, maxlat, maxlon
-		public boolean rawgps;
 		@Override public String toString() {
 			return name;
@@ -47,14 +42,4 @@
 		load();
 		setVisibleRowCount(7);
-		setCellRenderer(new DefaultListCellRenderer(){
-			@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
-				Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-				if (c instanceof JLabel) {
-					Bookmark b = (Bookmark)value;
-					((JLabel)c).setIcon(ImageProvider.get("layer/"+(b.rawgps?"rawgps_small":"osmdata_small")));
-				}
-				return c;
-			}
-		});
 	}
 
@@ -73,5 +58,5 @@
 			for (String line = in.readLine(); line != null; line = in.readLine()) {
 				StringTokenizer st = new StringTokenizer(line, ",");
-				if (st.countTokens() != 6)
+				if (st.countTokens() != 5)
 					continue;
 				Bookmark b = new Bookmark();
@@ -80,5 +65,4 @@
 					for (int i = 0; i < b.latlon.length; ++i)
 						b.latlon[i] = Double.parseDouble(st.nextToken());
-					b.rawgps = Boolean.parseBoolean(st.nextToken());
 					model.addElement(b);
 				} catch (NumberFormatException x) {
@@ -107,6 +91,6 @@
 				out.print(b.name+",");
 				for (int i = 0; i < b.latlon.length; ++i)
-					out.print(b.latlon[i]+",");
-				out.println(b.rawgps);
+					out.print(b.latlon[i]+(i<b.latlon.length-1?",":""));
+				out.println();
 			}
 			out.close();
Index: src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- src/org/openstreetmap/josm/gui/MainApplication.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/MainApplication.java	(revision 153)
@@ -26,10 +26,10 @@
 /**
  * Main window class application.
- *  
+ *
  * @author imi
  */
 public class MainApplication extends Main {
 	/**
-	 * Construct an main frame, ready sized and operating. Does not 
+	 * Construct an main frame, ready sized and operating. Does not
 	 * display the frame.
 	 */
@@ -67,5 +67,4 @@
 	/**
 	 * Main application Startup
-	 * @param args	No parameters accepted.
 	 */
 	public static void main(final String[] argArray) {
@@ -74,11 +73,11 @@
 		/////////////////////////////////////////////////////////////////////////
 		// Do not translate the early strings below until the locale is set up.
-		// The cannot be translated. That's live. Really. Sorry.
+		// These strings cannot be translated. That's live. Really. Sorry.
 		//
-		// The next sending me a patch translating these strings owe me a beer!
+		// The next one sending me a patch translating these strings owe me a beer!
 		//
 		//                                                                 Imi.
 		/////////////////////////////////////////////////////////////////////////
-		
+
 		Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
 
@@ -139,5 +138,5 @@
 			}
 		}
-		
+
 		// Locale is set. From now on, tr(), trn() and trc() may be called.
 
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 153)
@@ -27,11 +27,10 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.layer.WmsServerLayer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer.ModifiedChangedListener;
 
 /**
  * This is a component used in the MapFrame for browsing the map. It use is to
- * provide the MapMode's enough capabilities to operate. 
- * 
+ * provide the MapMode's enough capabilities to operate.
+ *
  * MapView hold meta-data about the data set currently displayed, as scale level,
  * center point viewed, what scrolling mode or editing mode is selected or with
@@ -99,5 +98,5 @@
 		add(zoomSlider);
 		zoomSlider.setBounds(3, 0, 114, 30);
-		
+
 		MapScaler scaler = new MapScaler(this);
 		add(scaler);
@@ -128,8 +127,8 @@
 
 		// add as a new layer
-		if (layer instanceof WmsServerLayer)
+		if (layer instanceof OsmDataLayer)
+			layers.add(0, layer);
+		else
 			layers.add(layers.size(), layer);
-		else
-			layers.add(0, layer);
 
 		for (LayerChangeListener l : listeners)
@@ -219,5 +218,5 @@
 	}
 	/**
-	 * Set the new dimension to the projection class. Also adjust the components 
+	 * Set the new dimension to the projection class. Also adjust the components
 	 * scale, if in autoScale mode.
 	 */
@@ -239,5 +238,5 @@
 
 			if (v.min == null || v.max == null || v.min.equals(v.max)) {
-				// no bounds means whole world 
+				// no bounds means whole world
 				center = getProjection().latlon2eastNorth(new LatLon(0,0));
 				EastNorth world = getProjection().latlon2eastNorth(new LatLon(Projection.MAX_LAT,Projection.MAX_LON));
Index: src/org/openstreetmap/josm/gui/PleaseWaitDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 153)
+++ src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 153)
@@ -0,0 +1,38 @@
+package org.openstreetmap.josm.gui;
+
+import java.awt.GridBagLayout;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoundedRangeModel;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.I18n;
+
+public class PleaseWaitDialog extends JDialog {
+
+	private final JProgressBar progressBar = new JProgressBar();
+
+	public final JLabel currentAction = new JLabel(I18n.tr("Contacting the OSM server..."));
+	public final BoundedRangeModel progress = progressBar.getModel();
+	public final JButton cancel = new JButton(I18n.tr("Cancel"));
+
+	public PleaseWaitDialog() {
+		super(JOptionPane.getFrameForComponent(Main.parent), true);
+		setLayout(new GridBagLayout());
+		JPanel pane = new JPanel(new GridBagLayout());
+		pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+		pane.add(currentAction, GBC.eol().fill(GBC.HORIZONTAL));
+		pane.add(progressBar, GBC.eop().fill(GBC.HORIZONTAL));
+		pane.add(cancel, GBC.eol().anchor(GBC.CENTER));
+		setContentPane(pane);
+		setSize(350,100);
+		setLocationRelativeTo(Main.parent);
+	}
+}
Index: src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 153)
@@ -4,5 +4,4 @@
 
 import java.awt.EventQueue;
-import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -11,17 +10,9 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 
-import javax.swing.BorderFactory;
-import javax.swing.BoundedRangeModel;
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
 import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.I18n;
 import org.xml.sax.SAXException;
 
@@ -29,43 +20,36 @@
  * Instanced of this thread will display a "Please Wait" message in middle of JOSM
  * to indicate a progress beeing executed.
- *  
+ *
  * @author Imi
  */
 public abstract class PleaseWaitRunnable implements Runnable {
 
-	public final JDialog pleaseWaitDlg;
 	public String errorMessage;
 
-	private final JProgressBar progressBar = new JProgressBar();
 	private boolean closeDialogCalled = false;
+	private boolean cancelled = false;
 
-	protected final JLabel currentAction = new JLabel(I18n.tr("Contacting the OSM server..."));
-	protected final BoundedRangeModel progress = progressBar.getModel();
+	private final String title;
 
 	/**
 	 * Create the runnable object with a given message for the user.
 	 */
-	public PleaseWaitRunnable(String msg) {
-		pleaseWaitDlg = new JDialog(JOptionPane.getFrameForComponent(Main.parent), msg, true);
-		pleaseWaitDlg.setLayout(new GridBagLayout());
-		JPanel pane = new JPanel(new GridBagLayout());
-		pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
-		pane.add(currentAction, GBC.eol().fill(GBC.HORIZONTAL));
-		pane.add(progressBar, GBC.eop().fill(GBC.HORIZONTAL));
-		JButton cancel = new JButton(tr("Cancel"));
-		pane.add(cancel, GBC.eol().anchor(GBC.CENTER));
-		pleaseWaitDlg.setContentPane(pane);
-		pleaseWaitDlg.setSize(350,100);
-		pleaseWaitDlg.setLocationRelativeTo(Main.parent);
-
-		cancel.addActionListener(new ActionListener(){
+	public PleaseWaitRunnable(String title) {
+		this.title = title;
+		Main.pleaseWaitDlg.cancel.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
-				cancel();
+				if (!cancelled) {
+					cancelled = true;
+					cancel();
+				}
 			}
 		});
-		pleaseWaitDlg.addWindowListener(new WindowAdapter(){
+		Main.pleaseWaitDlg.addWindowListener(new WindowAdapter(){
 			@Override public void windowClosing(WindowEvent e) {
 				if (!closeDialogCalled) {
-					cancel();
+					if (!cancelled) {
+						cancelled = true;
+						cancel();
+					}
 					closeDialog();
 				}
@@ -76,4 +60,16 @@
 	public final void run() {
 		try {
+			if (cancelled)
+				return; // since realRun isn't executed, do not call to finish
+			Main.pleaseWaitDlg.setTitle(title);
+
+			// show the dialog
+			closeDialogCalled = false;
+			EventQueue.invokeLater(new Runnable() {
+				public void run() {
+					Main.pleaseWaitDlg.setVisible(true);
+				}
+			});
+
 			realRun();
 		} catch (SAXException x) {
@@ -116,13 +112,27 @@
 			return;
 		closeDialogCalled  = true;
-		EventQueue.invokeLater(new Runnable(){
-			public void run() {
-				finish();
-				pleaseWaitDlg.setVisible(false);
-				pleaseWaitDlg.dispose();
-				if (errorMessage != null)
-					JOptionPane.showMessageDialog(Main.parent, errorMessage);
-			}
-		});
+		try {
+			Runnable runnable = new Runnable(){
+				public void run() {
+					try {
+						finish();
+					} finally {
+						Main.pleaseWaitDlg.setVisible(false);
+					}
+					if (errorMessage != null)
+						JOptionPane.showMessageDialog(Main.parent, errorMessage);
+				}
+			};
+
+			// make sure, this is called in the dispatcher thread ASAP
+			if (EventQueue.isDispatchThread())
+				runnable.run();
+			else
+				EventQueue.invokeAndWait(runnable);
+
+		} catch (InterruptedException e) {
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException(e);
+		}
 	}
 }
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 153)
@@ -49,5 +49,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.plugins.PluginProxy;
+import org.openstreetmap.josm.plugins.PluginInformation;
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.GBC;
@@ -109,7 +109,7 @@
 
 			String plugins = "";
-			for (Entry<String, Boolean> entry : pluginMap.entrySet())
+			for (Entry<PluginInformation, Boolean> entry : pluginMap.entrySet())
 				if (entry.getValue())
-					plugins += entry.getKey() + ",";
+					plugins += entry.getKey().name + ",";
 			if (plugins.endsWith(","))
 				plugins = plugins.substring(0, plugins.length()-1);
@@ -135,5 +135,5 @@
 		private static final String CANCELBUTTON_PROP = "OptionPane.cancelButtonText";
 		public CancelAction() {
-			super(UIManager.getString(CANCELBUTTON_PROP), 
+			super(UIManager.getString(CANCELBUTTON_PROP),
 					UIManager.getIcon("OptionPane.cancelIcon"));
 			try {
@@ -157,7 +157,7 @@
 	private JComboBox lafCombo = new JComboBox(UIManager.getInstalledLookAndFeels());
 	private JComboBox languages = new JComboBox(new Locale[]{
-			new Locale("en", "US"), 
-			new Locale("en", "GB"), 
-			Locale.GERMAN, 
+			new Locale("en", "US"),
+			new Locale("en", "GB"),
+			Locale.GERMAN,
 			Locale.FRENCH,
 			new Locale("ro", "RO")});
@@ -168,5 +168,5 @@
 
 	/**
-	 * Editfield for the Base url to the REST API from OSM. 
+	 * Editfield for the Base url to the REST API from OSM.
 	 */
 	private JTextField osmDataServer = new JTextField(20);
@@ -205,5 +205,5 @@
 	private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
 	private JList annotationSources = new JList(new DefaultListModel());
-	private Map<String, Boolean> pluginMap = new HashMap<String, Boolean>();
+	private Map<PluginInformation, Boolean> pluginMap = new HashMap<PluginInformation, Boolean>();
 
 
@@ -285,33 +285,23 @@
 
 		Box pluginPanel = Box.createVerticalBox();
-		Collection<String> availablePlugins = new HashSet<String>();
+		Collection<PluginInformation> availablePlugins = new HashSet<PluginInformation>();
 		File[] pluginFiles = new File(Main.pref.getPreferencesDir()+"plugins").listFiles();
-		if (pluginFiles != null) {
-			for (File f : pluginFiles) {
-				if (!f.isFile() || !f.getName().endsWith(".jar"))
-					continue;
-				availablePlugins.add(f.getName().substring(0, f.getName().length()-4));
-			}
-		}
+		if (pluginFiles != null)
+			for (File f : pluginFiles)
+				if (f.isFile() && f.getName().endsWith(".jar"))
+					availablePlugins.add(new PluginInformation(f));
+
 		Collection<String> enabledPlugins = Arrays.asList(Main.pref.get("plugins").split(","));
-		for (final String plugin : availablePlugins) {
-			boolean enabled = enabledPlugins.contains(plugin);
-			String desc = null;
-			for (PluginProxy p : Main.plugins) {
-				if (p.name.equals(plugin)) {
-					desc = p.getDescription();
-					break;
-				}
-			}
-
-			final JCheckBox pluginCheck = new JCheckBox(plugin, enabled);
+		for (final PluginInformation plugin : availablePlugins) {
+			boolean enabled = enabledPlugins.contains(plugin.name);
+			final JCheckBox pluginCheck = new JCheckBox(plugin.name, enabled);
 			pluginPanel.add(pluginCheck);
-			if (desc != null) {
-				pluginCheck.setToolTipText(desc);
-				JLabel label = new JLabel("<html><i>"+desc+"</i></html>");
-				label.setBorder(BorderFactory.createEmptyBorder(0,20,0,0));
-				pluginPanel.add(label);
-				pluginPanel.add(Box.createVerticalStrut(5));
-			}
+
+			pluginCheck.setToolTipText(plugin.file.getAbsolutePath());
+			JLabel label = new JLabel("<html><i>"+(plugin.description==null?"no description available":plugin.description)+"</i></html>");
+			label.setBorder(BorderFactory.createEmptyBorder(0,20,0,0));
+			pluginPanel.add(label);
+			pluginPanel.add(Box.createVerticalStrut(5));
+
 			pluginMap.put(plugin, enabled);
 			pluginCheck.addActionListener(new ActionListener(){
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 153)
@@ -49,5 +49,5 @@
  * respects clicks into the selection list. Ctrl-click will remove entries from
  * the list while single click will make the clicked entry the only selection.
- * 
+ *
  * @author imi
  */
@@ -68,10 +68,10 @@
 		}
 		@Override protected void realRun() {
-			currentAction.setText(tr("Contact {0}...", url.getHost()));
+			Main.pleaseWaitDlg.currentAction.setText(tr("Contact {0}...", url.getHost()));
 			sel = mode != SearchMode.remove ? new LinkedList<OsmPrimitive>() : Main.ds.allNonDeletedPrimitives();
 			try {
 				URLConnection con = url.openConnection();
-				InputStream in = new ProgressInputStream(con, progress, currentAction);
-				currentAction.setText(tr("Downloading..."));
+				InputStream in = new ProgressInputStream(con);
+				Main.pleaseWaitDlg.currentAction.setText(tr("Downloading..."));
 				Map<Long, String> ids = idReader.parseIds(in);
 				for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) {
@@ -236,5 +236,4 @@
 			if (loader.url != null) {
 				Main.worker.execute(loader);
-				loader.pleaseWaitDlg.setVisible(true);
 				return;
 			}
Index: src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 152)
+++ src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 153)
@@ -79,5 +79,5 @@
 		public int compareTo(ImageEntry image) {
 			return time.compareTo(image.time);
-		}		
+		}
 	}
 
@@ -93,5 +93,5 @@
 		}
 		@Override protected void realRun() throws IOException {
-			currentAction.setText(tr("Read GPS..."));
+			Main.pleaseWaitDlg.currentAction.setText(tr("Read GPS..."));
 			LinkedList<TimedPoint> gps = new LinkedList<TimedPoint>();
 
@@ -119,10 +119,10 @@
 			ArrayList<ImageEntry> data = new ArrayList<ImageEntry>(files.size());
 			int i = 0;
-			progress.setMaximum(files.size());
+			Main.pleaseWaitDlg.progress.setMaximum(files.size());
 			for (File f : files) {
 				if (cancelled)
 					break;
-				currentAction.setText(tr("Reading {0}...",f.getName()));
-				progress.setValue(i++);
+				Main.pleaseWaitDlg.currentAction.setText(tr("Reading {0}...",f.getName()));
+				Main.pleaseWaitDlg.progress.setValue(i++);
 
 				ImageEntry e = new ImageEntry();
@@ -153,5 +153,5 @@
 
 	/**
-	 * The delta added to all timestamps in files from the camera 
+	 * The delta added to all timestamps in files from the camera
 	 * to match to the timestamp from the gps receivers tracklog.
 	 */
@@ -185,6 +185,5 @@
 	public static void create(Collection<File> files, RawGpsLayer gpsLayer) {
 		Loader loader = new Loader(files, gpsLayer);
-		new Thread(loader).start();
-		loader.pleaseWaitDlg.setVisible(true);
+		Main.worker.execute(loader);
 	}
 
@@ -192,5 +191,5 @@
 		super(tr("Geotagged Images"));
 		Collections.sort(data);
-		Collections.sort(gps);					
+		Collections.sort(gps);
 		this.data = data;
 		this.gps = gps;
@@ -367,5 +366,5 @@
 				new JSeparator(),
 				new JMenuItem(new RenameLayerAction(null, this)),
-				new JSeparator(), 
+				new JSeparator(),
 				new JMenuItem(new LayerListPopup.InfoAction(this))};
 	}
Index: src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/WmsServerLayer.java	(revision 152)
+++ 	(revision )
@@ -1,109 +1,0 @@
-package org.openstreetmap.josm.gui.layer;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Point;
-
-import javax.swing.Icon;
-import javax.swing.JMenuItem;
-import javax.swing.JSeparator;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
-import org.openstreetmap.josm.data.projection.Projection;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.dialogs.LayerList;
-import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.TileCache;
-
-/**
- * This is a layer that grabs the current screen from an WMS server. The data
- * fetched this way is tiled and cached to the disc to reduce server load.
- */
-public class WmsServerLayer extends Layer {
-
-	private static Icon icon = ImageProvider.get("layer/wms");
-
-	private final TileCache cache;
-
-	private final String url;
-
-
-	public WmsServerLayer(String url) {
-		super(url.indexOf('/') != -1 ? url.substring(url.indexOf('/')+1) : url);
-
-		// 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 cache. Can't operate on {0}",Main.proj));
-
-		this.url = url;
-		cache = new TileCache(url);
-	}
-
-	@Override public Icon getIcon() {
-		return icon;
-	}
-
-	@Override public String getToolTipText() {
-		return tr("WMS layer: {0}", url);
-	}
-
-	@Override public boolean isMergable(Layer other) {
-		return false;
-	}
-
-	@Override public void mergeFrom(Layer from) {
-	}
-
-	@Override public void paint(Graphics g, final MapView mv) {
-//		EastNorth max = mv.getEastNorth(mv.getWidth(),0);
-//		EastNorth min = mv.getEastNorth(0,mv.getHeight());
-//		double width = max.east() - min.east();
-//		double height = max.north() - min.north();
-//		double tilesX = mv.getWidth() / TileCache.TILESIZE;
-//		double tilesY = mv.getHeight() / TileCache.TILESIZE;
-
-		// getting zoom level
-		int zoom = 0;
-		for (double w = mv.getScale(); w <= TileCache.worldDimension; w *= 2)
-			zoom++;
-		LatLon oneTile = Main.proj.eastNorth2latlon(new EastNorth(
-				TileCache.TILESIZE * mv.getScale(),
-				TileCache.TILESIZE * mv.getScale()));
-		if (oneTile.lat() > Projection.MAX_LAT || oneTile.lon() > Projection.MAX_LON) {
-			// just display the whole world
-			Image img = cache.get(0,0);
-			Point scr1 = mv.getPoint(Main.proj.latlon2eastNorth(new LatLon(Projection.MAX_LAT, -Projection.MAX_LON)));
-			Point scr2 = mv.getPoint(Main.proj.latlon2eastNorth(new LatLon(-Projection.MAX_LAT, Projection.MAX_LON)));
-			g.drawImage(img, scr1.x, scr1.y, scr2.x, scr2.y, 0, 0, TileCache.TILESIZE, TileCache.TILESIZE, null);
-		}
-
-//		TileCache.TileInformation info = TileCache.pos2tile(min, zoom);
-		//System.out.println(url+"bbox="+info.min.lon()+","+info.min.lat()+","+info.max.lon()+","+info.max.lat());
-	}
-
-	@Override public void visitBoundingBox(BoundingXYVisitor v) {
-		// doesn't have a bounding box
-	}
-
-	@Override public Object getInfoComponent() {
-		return getToolTipText();
-	}
-
-	@Override public Component[] getMenuEntries() {
-		return new Component[]{
-				new JMenuItem(new LayerList.ShowHideLayerAction(this)),
-				new JMenuItem(new LayerList.DeleteLayerAction(this)),
-				new JSeparator(),
-				new JMenuItem(new LayerListPopup.InfoAction(this))};
-    }
-}
Index: src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 152)
+++ src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 153)
@@ -8,4 +8,5 @@
 import java.util.LinkedList;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
@@ -40,7 +41,7 @@
     		Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
     		Collection<GpsPoint> list = new LinkedList<GpsPoint>();
-    
+
     		for (int i = 0;;++i) {
-    			currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
+    			Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
     			InputStream in = getInputStream(url+i);
     			if (in == null)
@@ -59,5 +60,5 @@
     			activeConnection = null;
     		}
-    
+
     		data.add(list);
     		return data;
@@ -86,6 +87,6 @@
     		if (in == null)
     			return null;
-    		currentAction.setText(tr("Downloading OSM data..."));
-    		final DataSet data = OsmReader.parseDataSet(in, currentAction, progress);
+    		Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
+    		final DataSet data = OsmReader.parseDataSet(in, Main.pleaseWaitDlg.currentAction, Main.pleaseWaitDlg.progress);
     		in.close();
     		activeConnection = null;
Index: src/org/openstreetmap/josm/io/ObjectListDownloader.java
===================================================================
--- src/org/openstreetmap/josm/io/ObjectListDownloader.java	(revision 152)
+++ src/org/openstreetmap/josm/io/ObjectListDownloader.java	(revision 153)
@@ -7,4 +7,5 @@
 import java.util.Collection;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -27,6 +28,6 @@
 
 	public DataSet parse() throws SAXException, IOException {
-		progress.setMaximum(toDownload.size());
-		progress.setValue(0);
+		Main.pleaseWaitDlg.progress.setMaximum(toDownload.size());
+		Main.pleaseWaitDlg.progress.setValue(0);
 		try {
 			final NameVisitor namer = new NameVisitor();
@@ -56,10 +57,10 @@
 
 	private void download(String className, long id) throws IOException, SAXException {
-		currentAction.setText(tr("Downloading {0} {1}", className, id));
+		Main.pleaseWaitDlg.currentAction.setText(tr("Downloading {0} {1}", className, id));
 		InputStream in = getInputStream(className+"/"+id);
 		if (in == null)
 			return;
 		DataSet data = OsmReader.parseDataSet(in, null, null);
-		progress.setValue(progress.getValue()+1);
+		Main.pleaseWaitDlg.progress.setValue(Main.pleaseWaitDlg.progress.getValue()+1);
 		if (data.allPrimitives().size() > 1)
 			throw new SAXException(tr("Got more than one object when expecting only one."));
Index: src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmConnection.java	(revision 152)
+++ src/org/openstreetmap/josm/io/OsmConnection.java	(revision 153)
@@ -9,5 +9,4 @@
 import java.net.PasswordAuthentication;
 
-import javax.swing.BoundedRangeModel;
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
@@ -23,5 +22,5 @@
  * Base class that handles common things like authentication for the reader and writer
  * to the osm server.
- * 
+ *
  * @author imi
  */
@@ -34,9 +33,7 @@
 		public OsmParseException(Throwable cause) {super(cause);}
 	}
-	
+
 	protected boolean cancel = false;
 	protected HttpURLConnection activeConnection;
-	protected JLabel currentAction;
-	protected BoundedRangeModel progress;
 
 	private static OsmAuth authentication;
@@ -116,11 +113,6 @@
 	}
 
-	public void setProgressInformation(JLabel currentAction, BoundedRangeModel progress) {
-		this.currentAction = currentAction;
-		this.progress = progress;
-	}
-
 	public void cancel() {
-		currentAction.setText(tr("Aborting..."));
+		Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
 		cancel = true;
 		if (activeConnection != null) {
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 152)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 153)
@@ -32,12 +32,12 @@
 /**
  * Parser for the Osm Api. Read from an input stream and construct a dataset out of it.
- * 
+ *
  * Reading process takes place in three phases. During the first phase (including xml parse),
  * all nodes are read and stored. Other information than nodes are stored in a raw list
- * 
+ *
  * The second phase reads from the raw list all segments and create Segment objects.
- * 
+ *
  * The third phase read all ways out of the remaining objects in the raw list.
- * 
+ *
  * @author Imi
  */
Index: src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 152)
+++ src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 153)
@@ -10,5 +10,5 @@
 /**
  * This DataReader read directly from the REST API of the osm server.
- * 
+ *
  * @author imi
  */
@@ -30,5 +30,5 @@
 		if (isAuthCancelled() && activeConnection.getResponseCode() == 401)
 			return null;
-		return new ProgressInputStream(activeConnection, progress, currentAction);
+		return new ProgressInputStream(activeConnection);
 	}
 }
Index: src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 152)
+++ src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 153)
@@ -26,12 +26,12 @@
 /**
  * Class that uploades all changes to the osm server.
- * 
+ *
  * This is done like this: - All objects with id = 0 are uploaded as new, except
  * those in deleted, which are ignored - All objects in deleted list are
  * deleted. - All remaining objects with modified flag set are updated.
- * 
+ *
  * This class implements visitor and will perform the correct upload action on
  * the visited element.
- * 
+ *
  * @author imi
  */
@@ -41,5 +41,5 @@
 	 * This list contain all sucessfull processed objects. The caller of
 	 * upload* has to check this after the call and update its dataset.
-	 * 
+	 *
 	 * If a server connection error occours, this may contain fewer entries
 	 * than where passed in the list to upload*.
@@ -60,6 +60,6 @@
 		initAuthentication();
 
-		progress.setMaximum(list.size());
-		progress.setValue(0);
+		Main.pleaseWaitDlg.progress.setMaximum(list.size());
+		Main.pleaseWaitDlg.progress.setValue(0);
 
 		NameVisitor v = new NameVisitor();
@@ -69,7 +69,7 @@
 					return;
 				osm.visit(v);
-				currentAction.setText(tr("Upload {0} {1} ({2})...", tr(v.className), v.name, osm.id));
+				Main.pleaseWaitDlg.currentAction.setText(tr("Upload {0} {1} ({2})...", tr(v.className), v.name, osm.id));
 				osm.visit(this);
-				progress.setValue(progress.getValue()+1);
+				Main.pleaseWaitDlg.progress.setValue(Main.pleaseWaitDlg.progress.getValue()+1);
 			}
 		} catch (RuntimeException e) {
@@ -142,9 +142,9 @@
 	 * Send the request. The objects id will be replaced if it was 0 before
 	 * (on add requests).
-	 * 
+	 *
 	 * @param requestMethod The http method used when talking with the server.
 	 * @param urlSuffix The suffix to add at the server url.
 	 * @param osm The primitive to encode to the server.
-	 * @param addBody <code>true</code>, if the whole primitive body should be added. 
+	 * @param addBody <code>true</code>, if the whole primitive body should be added.
 	 * 		<code>false</code>, if only the id is encoded.
 	 */
Index: src/org/openstreetmap/josm/io/ProgressInputStream.java
===================================================================
--- src/org/openstreetmap/josm/io/ProgressInputStream.java	(revision 152)
+++ src/org/openstreetmap/josm/io/ProgressInputStream.java	(revision 153)
@@ -5,6 +5,5 @@
 import java.net.URLConnection;
 
-import javax.swing.BoundedRangeModel;
-import javax.swing.JLabel;
+import org.openstreetmap.josm.Main;
 
 /**
@@ -15,21 +14,17 @@
 
 	private final InputStream in;
-	private final BoundedRangeModel progress;
-	private final JLabel currentAction;
 	private int readSoFar = 0;
 	private int lastDialogUpdate = 0;
 	private final URLConnection connection;
 
-	public ProgressInputStream(URLConnection con, BoundedRangeModel progress, JLabel currentAction) throws IOException {
+	public ProgressInputStream(URLConnection con) throws IOException {
 		this.connection = con;
 		this.in = con.getInputStream();
-		this.progress = progress;
-		this.currentAction = currentAction;
 		int contentLength = con.getContentLength();
 		if (contentLength > 0)
-			progress.setMaximum(contentLength);
+			Main.pleaseWaitDlg.progress.setMaximum(contentLength);
 		else
-			progress.setMaximum(0);
-		progress.setValue(0);
+			Main.pleaseWaitDlg.progress.setMaximum(0);
+		Main.pleaseWaitDlg.progress.setValue(0);
 	}
 
@@ -57,6 +52,6 @@
 	 */
 	private void advanceTicker(int amount) {
-		if (progress.getMaximum() == 0 && connection.getContentLength() != -1)
-			progress.setMaximum(connection.getContentLength());
+		if (Main.pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1)
+			Main.pleaseWaitDlg.progress.setMaximum(connection.getContentLength());
 
 		readSoFar += amount;
@@ -65,8 +60,8 @@
 			lastDialogUpdate++;
 			String progStr = " "+readSoFar/1024+"/";
-			progStr += (progress.getMaximum()==0) ? "??? KB" : (progress.getMaximum()/1024)+" KB";
-			progress.setValue(readSoFar);
+			progStr += (Main.pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (Main.pleaseWaitDlg.progress.getMaximum()/1024)+" KB";
+			Main.pleaseWaitDlg.progress.setValue(readSoFar);
 
-			String cur = currentAction.getText();
+			String cur = Main.pleaseWaitDlg.currentAction.getText();
 			int i = cur.indexOf(' ');
 			if (i != -1)
@@ -74,5 +69,5 @@
 			else
 				cur += progStr;
-			currentAction.setText(cur);
+			Main.pleaseWaitDlg.currentAction.setText(cur);
 		}
 	}
Index: src/org/openstreetmap/josm/plugins/Plugin.java
===================================================================
--- src/org/openstreetmap/josm/plugins/Plugin.java	(revision 152)
+++ src/org/openstreetmap/josm/plugins/Plugin.java	(revision 153)
@@ -13,6 +13,6 @@
  * (or else, the plugin jar will not be within the class path).
  *
- * All plugins should have at least one class subclassing this abstract base class. 
- * 
+ * All plugins should have at least one class subclassing this abstract base class.
+ *
  * The actual implementation of this interface is optional, as all functions will be called
  * via reflection. This is to be able to change this interface without the need of recompiling
@@ -25,5 +25,5 @@
  *
  *
- * The pluginname provided to the constructor is also the name of the directory to 
+ * The pluginname provided to the constructor is also the name of the directory to
  * store the plugin's own stuff (located under the josm preferences directory)
  *
@@ -40,5 +40,5 @@
 		name = s.substring(lastSlash+1, s.length()-4);
     }
-	
+
 	/**
 	 * @return The name of this plugin. This is the name of the .jar file.
@@ -54,5 +54,5 @@
 	}
 
-	
+
 
 	/**
@@ -62,10 +62,3 @@
 	 */
 	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {}
-
-	/**
-	 * Called to retrieve a one-liner description of what this plugin does for tooltips.
-	 * @return <code>null</code>, which means: "no description available".
-	 */
-	public String getDescription() {return null;}
-
 }
Index: src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 153)
+++ src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 153)
@@ -0,0 +1,51 @@
+package org.openstreetmap.josm.plugins;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+/**
+ * Encapsulate general information about a plugin. This information is available
+ * without the need of loading any class from the plugin jar file.
+ *
+ * @author imi
+ */
+public class PluginInformation {
+	public final File file;
+	public final String name;
+	public final String className;
+	public final String description;
+
+	public PluginInformation(File file) {
+		this.file = file;
+		name = file.getName().substring(0, file.getName().length()-4);
+		try {
+	        JarInputStream jar = new JarInputStream(new FileInputStream(file));
+	        Manifest manifest = jar.getManifest();
+	        className = manifest.getMainAttributes().getValue("Plugin-Class");
+	        description = manifest.getMainAttributes().getValue("Plugin-Description");
+	        jar.close();
+        } catch (IOException e) {
+        	throw new PluginException(null, name, e);
+        }
+    }
+
+	/**
+	 * Load and instantiate the plugin
+	 */
+	public PluginProxy load() {
+		try {
+			ClassLoader loader = URLClassLoader.newInstance(
+					new URL[]{new URL("file://"+file.getAbsolutePath())},
+					getClass().getClassLoader());
+			Object plugin = Class.forName(className, true, loader).newInstance();
+			return new PluginProxy(plugin, this);
+		} catch (Exception e) {
+			throw new PluginException(null, name, e);
+		}
+	}
+}
Index: src/org/openstreetmap/josm/plugins/PluginLoader.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginLoader.java	(revision 152)
+++ 	(revision )
@@ -1,60 +1,0 @@
-package org.openstreetmap.josm.plugins;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-
-/**
- * Helper class to detect and load plugins.
- * 
- * @author Immanuel.Scholz
- */
-public class PluginLoader {
-
-	/**
-	 * @return The class name from the manifest of the jar given as parameter.
-	 */
-	public String loadClassName(File pluginFile) throws PluginException {
-		try {
-			JarInputStream jar = new JarInputStream(new FileInputStream(pluginFile));
-			Manifest manifest = jar.getManifest();
-			String pluginClass = manifest.getMainAttributes().getValue("Plugin-Class");
-			jar.close();
-			return pluginClass;
-		} catch (IOException e) {
-			String name = pluginFile.getName();
-			if (name.endsWith(".jar"))
-				name = name.substring(0, name.length()-4);
-			throw new PluginException(null, name, e);
-		}
-	}
-
-	/**
-	 * Load and instantiate the plugin
-	 */
-	public PluginProxy loadPlugin(String pluginClass, File pluginFile) throws PluginException {
-		String name = pluginFile.getName();
-		if (name.endsWith(".jar"))
-			name = name.substring(0, name.length()-4);
-		try {
-			String url = "file://"+pluginFile.getAbsolutePath();
-			url = url.replace('\\', '/');
-
-			// *sic*
-			if (System.getProperty("os.name").startsWith("Windows"))
-				url = "file:/" + url.substring(7);
-
-			ClassLoader loader = URLClassLoader.newInstance(
-					new URL[]{new URL(url)},
-					getClass().getClassLoader());
-			Object plugin = Class.forName(pluginClass, true, loader).newInstance();
-			return new PluginProxy(plugin, name);
-		} catch (Exception e) {
-			throw new PluginException(null, name, e);
-		}
-	}
-}
Index: src/org/openstreetmap/josm/plugins/PluginProxy.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginProxy.java	(revision 152)
+++ src/org/openstreetmap/josm/plugins/PluginProxy.java	(revision 153)
@@ -6,7 +6,7 @@
 /**
  * Helper class for the JOSM system to communicate with the plugin.
- * 
+ *
  * This class should be of no interest for sole plugin writer.
- * 
+ *
  * @author Immanuel.Scholz
  */
@@ -14,29 +14,17 @@
 
 	public final Object plugin;
-	public final String name;
+	public final PluginInformation info;
 	public boolean misbehaving = false;
 
-	public PluginProxy(Object plugin, String name) {
+	public PluginProxy(Object plugin, PluginInformation info) {
 		this.plugin = plugin;
-		this.name = name;
+		this.info = info;
     }
 
-
-	
 	@Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
 		try {
 	        plugin.getClass().getMethod("mapFrameInitialized", MapFrame.class, MapFrame.class).invoke(plugin, oldFrame, newFrame);
         } catch (Exception e) {
-        	throw new PluginException(this, name, e);
-        }
-    }
-
-	@Override public String getDescription() {
-	    try {
-	        return (String)plugin.getClass().getMethod("getDescription").invoke(plugin);
-        } catch (NoSuchMethodException e) {
-        	return super.getDescription();
-        } catch (Exception e) {
-        	throw new PluginException(this, name, e);
+        	throw new PluginException(this, info.name, e);
         }
     }
Index: src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java
===================================================================
--- src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 152)
+++ src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java	(revision 153)
@@ -26,8 +26,8 @@
 /**
  * An exception handler, that ask the user to send a bug report.
- * 
+ *
  * @author imi
  */
-public final class BugReportExceptionHandler implements Thread.UncaughtExceptionHandler {        
+public final class BugReportExceptionHandler implements Thread.UncaughtExceptionHandler {
 
 	public void uncaughtException(Thread t, Throwable e) {
@@ -38,14 +38,14 @@
 				return;
 			}
-			
+
 			if (e instanceof PluginException) {
 				PluginProxy plugin = ((PluginException)e).getPlugin();
 				if (plugin != null && !plugin.misbehaving) {
-					JOptionPane.showMessageDialog(Main.parent, tr("The plugin {0} throwed an exception: {1}\nIt may be outdated. Please contact the plugin's autor.\nThis message will not shown again until JOSM is restarted.", plugin.name, e.getMessage()));
+					JOptionPane.showMessageDialog(Main.parent, tr("The plugin {0} throwed an exception: {1}\nIt may be outdated. Please contact the plugin's autor.\nThis message will not shown again until JOSM is restarted.", plugin.info.name, e.getMessage()));
 					plugin.misbehaving = true;
 					return;
 				}
 			}
-			
+
 			Object[] options = new String[]{tr("Do nothing"), tr("Report Bug")};
 			int answer = JOptionPane.showOptionDialog(Main.parent, tr("An unexpected exception occoured.\n\n" +
