Index: src/org/openstreetmap/josm/actions/PreferencesAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/PreferencesAction.java   (revision 1732)
+++ src/org/openstreetmap/josm/actions/PreferencesAction.java   (working copy)
@@ -36,7 +36,7 @@
      * Launch the preferences dialog.
      */
     public void actionPerformed(ActionEvent e) {
-        new Thread(this).start();
+        run();
     }
 
     public void run() {
@@ -74,6 +74,7 @@
 
         dlg.setBounds(targetX, targetY, targetWidth, targetHeight);
 
+        dlg.setModal(true);
         dlg.setVisible(true);
         if (pane.getValue() instanceof Integer && (Integer)pane.getValue() == JOptionPane.OK_OPTION)
             prefDlg.ok();
Index: src/org/openstreetmap/josm/plugins/PluginDownloader.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginDownloader.java    (revision 1732)
+++ src/org/openstreetmap/josm/plugins/PluginDownloader.java    (working copy)
@@ -10,26 +10,22 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Arrays;
-import java.util.concurrent.Future;
 import java.util.Collection;
 import java.util.LinkedList;
 
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.actions.AboutAction;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.AboutAction;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.xml.sax.SAXException;
@@ -65,7 +61,10 @@
             File pluginDir = Main.pref.getPluginsDirFile();
             if (!pluginDir.exists())
                 pluginDir.mkdirs();
+            Main.pleaseWaitDlg.progress.setMaximum(toUpdate.size());
+            int progressValue = 0;
             for (PluginInformation d : toUpdate) {
+                Main.pleaseWaitDlg.progress.setValue(progressValue++);
                 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading Plugin {0}...", d.name));
                 File pluginFile = new File(pluginDir, d.name + ".jar.new");
                 if(download(d, pluginFile))
@@ -144,15 +143,12 @@
     }
 
     public Collection<PluginInformation> download(Collection<PluginInformation> download) {
+        // Execute task in current thread instead of executing it in other thread and waiting for result
+        // Waiting for result is not a good idea because the waiting thread will probably be either EDT
+        // or worker thread. Blocking one of these threads will cause deadlock
         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) {e.printStackTrace();}
-        catch(java.util.concurrent.ExecutionException e) {e.printStackTrace();}
-        return download;
+        t.run();
+        return t.failed;
     }
 
     public static boolean moveUpdatedPlugins() {
Index: src/org/openstreetmap/josm/plugins/PluginSelection.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginSelection.java (revision 1732)
+++ src/org/openstreetmap/josm/plugins/PluginSelection.java (working copy)
@@ -8,13 +8,11 @@
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -96,7 +94,7 @@
         drawPanel(pluginPanel);
     }
 
-    public Boolean finish() {
+    public boolean finish() {
         Collection<PluginInformation> toDownload = new LinkedList<PluginInformation>();
         String msg = "";
         for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
Index: src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java  (revision 1732)
+++ src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java  (working copy)
@@ -8,6 +8,7 @@
 import java.awt.event.ActionListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -35,6 +36,27 @@
 
     private final String title;
 
+    private ActionListener cancelListener = new ActionListener(){
+        public void actionPerformed(ActionEvent e) {
+            if (!cancelled) {
+                cancelled = true;
+                cancel();
+            }
+        }
+    };
+
+    private WindowListener windowListener = new WindowAdapter(){
+        @Override public void windowClosing(WindowEvent e) {
+            if (!closeDialogCalled) {
+                if (!cancelled) {
+                    cancelled = true;
+                    cancel();
+                }
+                closeDialog();
+            }
+        }
+    };
+
     /**
      * Create the runnable object with a given message for the user.
      */
@@ -52,53 +74,24 @@
     public PleaseWaitRunnable(String title, boolean ignoreException) {
         this.title = title;
         this.ignoreException = ignoreException;
-        Main.pleaseWaitDlg.cancel.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                if (!cancelled) {
-                    cancelled = true;
-                    cancel();
-                }
-            }
-        });
-        Main.pleaseWaitDlg.addWindowListener(new WindowAdapter(){
-            @Override public void windowClosing(WindowEvent e) {
-                if (!closeDialogCalled) {
-                    if (!cancelled) {
-                        cancelled = true;
-                        cancel();
-                    }
-                    closeDialog();
-                }
-            }
-        });
     }
 
-    public final void run() {
-        try {
-            try {
-                if (cancelled)
-                    return; // since realRun isn't executed, do not call to finish
+    private void prepareDialog() {
+        // reset dialog state
+        errorMessage = null;
+        closeDialogCalled = false;
 
-                // reset dialog state
-                Main.pleaseWaitDlg.setTitle(title);
-                Main.pleaseWaitDlg.cancel.setEnabled(true);
-                Main.pleaseWaitDlg.setCustomText("");
-                errorMessage = null;
-                closeDialogCalled = false;
-
-                // show the dialog
-                synchronized (this) {
-                    EventQueue.invokeLater(new Runnable() {
-                        public void run() {
-                            synchronized (PleaseWaitRunnable.this) {
-                                PleaseWaitRunnable.this.notifyAll();
-                            }
-                            Main.pleaseWaitDlg.setVisible(true);
-                        }
-                    });
-                    try {wait();} catch (InterruptedException e) {}
-                }
+        Main.pleaseWaitDlg.setTitle(title);
+        Main.pleaseWaitDlg.cancel.setEnabled(true);
+        Main.pleaseWaitDlg.setCustomText("");
+        Main.pleaseWaitDlg.cancel.addActionListener(cancelListener);
+        Main.pleaseWaitDlg.addWindowListener(windowListener);
+        Main.pleaseWaitDlg.setVisible(true);
+    }
 
+    private void doRealRun() {
+        try {
+            try {
                 realRun();
             } catch (SAXException x) {
                 x.printStackTrace();
@@ -131,6 +124,27 @@
         }
     }
 
+    public final void run() {
+        if (cancelled)
+            return; // since realRun isn't executed, do not call to finish
+
+        if (EventQueue.isDispatchThread()) {
+            new Thread(new Runnable() {
+                public void run() {
+                    doRealRun();
+                }
+            }).start();
+            prepareDialog();
+        } else {
+            EventQueue.invokeLater(new Runnable() {
+                public void run() {
+                    prepareDialog();
+                }
+            });
+            doRealRun();
+        }
+    }
+
     /**
      * User pressed cancel button.
      */
@@ -164,6 +178,8 @@
                     } finally {
                         Main.pleaseWaitDlg.setVisible(false);
                         Main.pleaseWaitDlg.dispose();
+                        Main.pleaseWaitDlg.removeWindowListener(windowListener);
+                        Main.pleaseWaitDlg.cancel.removeActionListener(cancelListener);
                     }
                     if (errorMessage != null && !silent) {
                         JOptionPane.showMessageDialog(Main.parent, errorMessage);
