Index: /trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java	(revision 1647)
@@ -23,5 +23,5 @@
  * @author imi
  */
-public class PreferencesAction extends JosmAction {
+public class PreferencesAction extends JosmAction implements Runnable {
 
     /**
@@ -37,4 +37,8 @@
      */
     public void actionPerformed(ActionEvent e) {
+        new Thread(this).start();
+    }
+
+    public void run() {
         PreferenceDialog prefDlg = new PreferenceDialog();
         prefDlg.setMinimumSize(new Dimension(400,300));
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 1647)
@@ -39,5 +39,5 @@
         private int num = 1;
         private String msg = "";
-        
+
         public Task(boolean newLayer, OsmServerReader reader, boolean silent,
                 int numLayers, String msg) {
@@ -65,5 +65,5 @@
                 dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server"));
             }
-            
+
             OsmDataLayer layer = new OsmDataLayer(dataSet, tr("Data Layer {0}", num), null);
             if (newLayer)
@@ -71,5 +71,5 @@
             else
                 Main.main.editLayer().mergeFrom(layer);
-            
+
             Main.pleaseWaitDlg.setCustomText("");
         }
@@ -94,5 +94,5 @@
             double t = minlon; minlon = maxlon; maxlon = t;
         }
-        
+
         boolean newLayer = action != null
                                 && (action.dialog == null || action.dialog.newLayer.isSelected());
@@ -104,9 +104,9 @@
                 message);
         currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
-        // We need submit instead of execute so we can wait for it to finish and get the error 
+        // We need submit instead of execute so we can wait for it to finish and get the error
         // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
-        task = Main.worker.submit(t, t);       
+        task = Main.worker.submit(t, t);
     }
-    
+
     public void download(DownloadAction action, double minlat, double minlon,
             double maxlat, double maxlon) {
@@ -135,5 +135,5 @@
         return "osm";
     }
-    
+
     /**
      * Finds the number of data layers currently opened
@@ -149,5 +149,5 @@
         return num;
     }
-    
+
    /*
     * (non-Javadoc)
@@ -156,5 +156,5 @@
     public String getErrorMessage() {
         if(task == null)
-            return "";        
+            return "";
 
         try {
Index: /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 1647)
@@ -28,5 +28,5 @@
      */
     public String version;
-    
+
     /**
      * All nodes goes here, even when included in other data (ways etc). This enables the instant
Index: /trunk/src/org/openstreetmap/josm/gui/GettingStarted.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 1647)
@@ -99,5 +99,5 @@
             //    everytime because of something we can't read.
             return (Main.pref.getInteger("cache.motd.html.version", myVersion) == myVersion)
-					 && Main.pref.get("cache.motd.html.lang").equals(myLang);
+            && Main.pref.get("cache.motd.html.lang").equals(myLang);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 1647)
@@ -54,10 +54,10 @@
         });
     }
-    
-    public void setIndeterminate(boolean newValue) {    
+
+    public void setIndeterminate(boolean newValue) {
         UIManager.put("ProgressBar.cycleTime", UIManager.getInt("ProgressBar.repaintInterval") * 100);
         progressBar.setIndeterminate(newValue);
     }
-    
+
     /**
      * Sets a custom text line below currentAction. Can be used to display additional information
@@ -70,5 +70,5 @@
             return;
         }
-        
+
         customText.setVisible(true);
         customText.setText(text);
Index: /trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 1647)
@@ -34,8 +34,8 @@
 
     private final String title;
-    
+
     /**
      * Create the runnable object with a given message for the user.
-     */    
+     */
     public PleaseWaitRunnable(String title) {
         this(title, false);
@@ -45,5 +45,5 @@
      * Create the runnable object with a given message for the user.
      * @param title Message for user
-     * @param ignoreException If true, exception will be propaged to calling code. If false then 
+     * @param ignoreException If true, exception will be propaged to calling code. If false then
      * exception will be thrown directly in EDT. When this runnable is executed using executor framework
      * then use false unless you read result of task (because exception will get lost if you don't)
@@ -118,5 +118,5 @@
                     public void run() {
                         throw new RuntimeException(e);
-                    }                
+                    }
                 });
             }
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java	(revision 1647)
@@ -23,7 +23,7 @@
 import java.net.URL;
 import java.util.Arrays;
+import java.util.concurrent.Future;
 import java.util.Collection;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.LinkedList;
 
 import javax.swing.JOptionPane;
@@ -39,9 +39,12 @@
     private static final class UpdateTask extends PleaseWaitRunnable {
         private final Collection<PluginInformation> toUpdate;
+        public final Collection<PluginInformation> failed = new LinkedList<PluginInformation>();
         private String errors = "";
         private int count = 0;
+        private boolean update;
 
-        private UpdateTask(Collection<PluginInformation> toUpdate) {
-            super(tr("Update Plugins"));
+        private UpdateTask(Collection<PluginInformation> toUpdate, boolean up) {
+            super(up ? tr("Update Plugins") : tr("Download Plugins"));
+            update = up;
             this.toUpdate = toUpdate;
         }
@@ -52,8 +55,9 @@
 
         @Override protected void finish() {
+            Main.pleaseWaitDlg.setVisible(false);
             if (errors.length() > 0)
                 JOptionPane.showMessageDialog(Main.parent, tr("There were problems with the following plugins:\n\n {0}",errors));
             else
-                JOptionPane.showMessageDialog(Main.parent, trn("{0} Plugin successfully updated. Please restart JOSM.", "{0} Plugins successfully updated. Please restart JOSM.", count, count));
+                JOptionPane.showMessageDialog(Main.parent, trn("{0} Plugin successfully downloaded. Please restart JOSM.", "{0} Plugins successfully downloaded. Please restart JOSM.", count, count));
         }
 
@@ -63,7 +67,11 @@
                 pluginDir.mkdirs();
             for (PluginInformation d : toUpdate) {
+                Main.pleaseWaitDlg.currentAction.setText(tr("Downloading Plugin {0}...", d.name));
                 File pluginFile = new File(pluginDir, d.name + ".jar.new");
                 if (download(d, pluginFile))
+                {
                     count++;
+                    failed.add(d);
+                }
                 else
                     errors += d.name + "\n";
@@ -103,22 +111,4 @@
     }
 
-    public static boolean downloadPlugin(PluginInformation pd) {
-        File file = new File(Main.pref.getPluginsDirFile(), pd.name + ".jar");
-        if (!download(pd, file)) {
-            JOptionPane.showMessageDialog(Main.parent, tr("Could not download plugin: {0} from {1}", pd.name, pd.downloadlink));
-        } else {
-            try {
-                PluginInformation.findPlugin(pd.name);
-                return true;
-            } catch (Exception e) {
-                e.printStackTrace();
-                JOptionPane.showMessageDialog(Main.parent, tr("The plugin {0} seems to be broken or could not be downloaded automatically.", pd.name));
-            }
-        }
-        if (file.exists())
-            file.delete();
-        return false;
-    }
-
     private static boolean download(PluginInformation pd, File file) {
         if(pd.mainversion > AboutAction.getVersionNumber())
@@ -141,17 +131,27 @@
             out.close();
             in.close();
+            new PluginInformation(file);
             return true;
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
+        file.delete(); /* cleanup */
         return false;
     }
 
     public static void update(Collection<PluginInformation> update) {
-        Main.worker.execute(new UpdateTask(update));
+        Main.worker.execute(new UpdateTask(update, true));
+    }
+
+    public Collection<PluginInformation> download(Collection<PluginInformation> download) {
+        UpdateTask t = new UpdateTask(download, false);
+        try {
+            Future<UpdateTask> ta = Main.worker.submit(t, t);
+            t = ta.get();
+            return t.failed;
+        }
+        catch(java.lang.InterruptedException e) {}
+        catch(java.util.concurrent.ExecutionException e) {}
+        return download;
     }
 
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 1647)
@@ -110,9 +110,6 @@
         stage = stageStr == null ? 50 : Integer.parseInt(stageStr);
         version = attr.getValue("Plugin-Version");
-        try {
-            mainversion = Integer.parseInt(attr.getValue("Plugin-Mainversion"));
-        } catch(NumberFormatException e) {
-            e.printStackTrace();
-        }
+        try { mainversion = Integer.parseInt(attr.getValue("Plugin-Mainversion")); }
+        catch(NumberFormatException e) {}
         author = attr.getValue("Author");
 
Index: /trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java	(revision 1646)
+++ /trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java	(revision 1647)
@@ -98,7 +98,24 @@
         String msg = "";
         for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
-            if (entry.getValue() && PluginInformation.findPlugin(entry.getKey()) == null) {
-                toDownload.add(availablePlugins.get(entry.getKey()));
-                msg += entry.getKey() + "\n";
+            if(entry.getValue())
+            {
+                String name = entry.getKey();
+                PluginInformation ap = availablePlugins.get(name);
+                PluginInformation pi = PluginInformation.findPlugin(name);
+                boolean add = false;
+                if(pi == null)
+                    add = true;
+                else if(!pi.version.equals(ap.version))
+                {
+                    add = true;
+                    for (PluginProxy proxy : PluginHandler.pluginList)
+                        if(proxy.info.name.equals(ap.name))
+                            add = false;
+                }
+                if(add)
+                {
+                    toDownload.add(ap);
+                    msg += name + "\n";
+                }
             }
         }
@@ -109,11 +126,8 @@
                         new String[] {tr("Download Plugins"), tr("Cancel")},
                         new String[] {"download.png", "cancel.png"}).getValue();
-            if (answer != 1)
-                for (PluginInformation pd : toDownload)
-                    pluginMap.put(pd.name, false);
-            else
-                for (PluginInformation pd : toDownload)
-                    if (!PluginDownloader.downloadPlugin(pd))
-                        pluginMap.put(pd.name, false);
+            Collection<PluginInformation> error =
+            (answer != 1 ? toDownload : new PluginDownloader().download(toDownload));
+            for (PluginInformation pd : error)
+                pluginMap.put(pd.name, false);
 
         }
@@ -209,28 +223,4 @@
             pluginCheck.addActionListener(new ActionListener(){
                 public void actionPerformed(ActionEvent e) {
-                    // if user enabled a plugin, it is not loaded but found somewhere on disk: offer to delete jar
-                    if (pluginCheck.isSelected()) {
-                        PluginInformation plinfo = PluginInformation.findPlugin(plugin.name);
-                        if ((getLoaded(plugin.name) == null) && (plinfo != null)) {
-                            try {
-                                int answer = new ExtendedDialog(Main.parent,
-                                    tr("Plugin already exists"),
-                                    tr("Plugin archive already available. Do you want to download"
-                                        + " the current version by deleting existing archive?\n\n{0}",
-                                        plinfo.file.getCanonicalPath()),
-                                    new String[] {tr("Delete and Download"), tr("Cancel")},
-                                    new String[] {"download.png", "cancel.png"}).getValue();
-
-                                if (answer == 1) {
-                                    if (!plinfo.file.delete()) {
-                                        JOptionPane.showMessageDialog(Main.parent, tr("Error deleting plugin file: {0}", plinfo.file.getCanonicalPath()));
-                                    }
-                                }
-                            } catch (IOException e1) {
-                                e1.printStackTrace();
-                                JOptionPane.showMessageDialog(Main.parent, tr("Error deleting plugin file: {0}", e1.getMessage()));
-                            }
-                        }
-                    }
                     pluginMap.put(plugin.name, pluginCheck.isSelected());
                 }
