Index: trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/actions/PreferencesAction.java	(revision 1738)
@@ -37,5 +37,5 @@
      */
     public void actionPerformed(ActionEvent e) {
-        new Thread(this).start();
+        run();
     }
 
@@ -75,4 +75,5 @@
         dlg.setBounds(targetX, targetY, targetWidth, targetHeight);
 
+        dlg.setModal(true);
         dlg.setVisible(true);
         if (pane.getValue() instanceof Integer && (Integer)pane.getValue() == JOptionPane.OK_OPTION)
Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 1738)
@@ -148,10 +148,10 @@
 
     public LatLon interpolate(LatLon ll2, double proportion) {
-        return new LatLon(this.x + proportion * (ll2.x - this.x),
-            this.y + proportion * (ll2.y - this.y));
+        return new LatLon(this.lat() + proportion * (ll2.lat() - this.lat()),
+            this.lon() + proportion * (ll2.lon() - this.lon()));
     }
 
     public LatLon getCenter(LatLon ll2) {
-        return new LatLon((this.x + ll2.x)/2.0, (this.y + ll2.y)/2.0);
+        return new LatLon((this.lat() + ll2.lat())/2.0, (this.lon() + ll2.lon())/2.0);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 1738)
@@ -9,4 +9,5 @@
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -36,4 +37,25 @@
     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.
@@ -53,51 +75,22 @@
         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() {
+    }
+
+    private void prepareDialog() {
+        // reset dialog state
+        errorMessage = null;
+        closeDialogCalled = false;
+
+        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 {
-                if (cancelled)
-                    return; // since realRun isn't executed, do not call to finish
-
-                // 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) {}
-                }
-
                 realRun();
             } catch (SAXException x) {
@@ -129,4 +122,25 @@
                 });
             }
+        }
+    }
+
+    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();
         }
     }
@@ -165,4 +179,6 @@
                         Main.pleaseWaitDlg.setVisible(false);
                         Main.pleaseWaitDlg.dispose();
+                        Main.pleaseWaitDlg.removeWindowListener(windowListener);
+                        Main.pleaseWaitDlg.cancel.removeActionListener(cancelListener);
                     }
                     if (errorMessage != null && !silent) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java	(revision 1738)
@@ -686,5 +686,5 @@
                 Date time = new Date(tp.time.getTime() - (delta+gpstimezone));
                 if (time.after(e.time) && lastTP != null) {
-                    e.pos.setCoor(lastTP.pos.getCenter(tp.pos));
+                    e.pos = new CachedLatLon(lastTP.pos.getCenter(tp.pos));
                     break;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 1738)
@@ -485,5 +485,5 @@
                                             hdop = 0;
                                         }
-                                        int hdoplvl = Math.round(hdop * 25);
+                                        int hdoplvl = Math.round(hdop * Main.pref.getInteger("hdop.factor", 25));
                                         // High hdop is bad, but high values in colors are green.
                                         // Therefore inverse the logic
@@ -1093,6 +1093,6 @@
                 WayPoint R = null;
                 for (WayPoint S : seg) {
+                    EastNorth c = R.getEastNorth();
                     if (R == null) {
-                        EastNorth c = R.getEastNorth();
                         R = S;
                         rx = c.east();
@@ -1107,5 +1107,4 @@
                         }
                     } else {
-                        EastNorth c = S.getEastNorth();
                         sx = c.east();
                         sy = c.north();
Index: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1738)
@@ -169,5 +169,5 @@
             }
             for (Entry<String, String> e : osm.keys.entrySet()) {
-                if (!("created_by".equals(e.getKey())))
+                if ((osm instanceof Changeset) || !("created_by".equals(e.getKey())))
                     out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) +
                             "' v='"+XmlWriter.encode(e.getValue())+ "' />");
Index: trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java	(revision 1738)
@@ -11,7 +11,5 @@
 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;
@@ -20,8 +18,6 @@
 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;
@@ -29,6 +25,6 @@
 import javax.swing.JOptionPane;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AboutAction;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
@@ -66,5 +62,8 @@
             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");
@@ -145,13 +144,10 @@
 
     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;
     }
 
Index: trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java	(revision 1732)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java	(revision 1738)
@@ -9,5 +9,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -15,5 +14,4 @@
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
@@ -25,5 +23,4 @@
 import java.util.Map;
 import java.util.Set;
-import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.Map.Entry;
@@ -72,6 +69,5 @@
             PluginInformation description = availablePlugins.get(local.name);
 
-            if (description != null && (description.version == null || description.version.equals("")) ?
-            (local.version != null && local.version.equals("")) : !description.version.equals(local.version)) {
+            if (description.version != null && !description.version.equals(local.version)) {
                 toUpdate.add(description);
                 toUpdateStr.append(description.name+"\n");
@@ -97,9 +93,11 @@
     }
 
-    public Boolean finish() {
+    public boolean finish() {
         Collection<PluginInformation> toDownload = new LinkedList<PluginInformation>();
+        Collection<String> installedPlugins = Main.pref.getCollection("plugins", null);
+
         String msg = "";
         for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
-            if(entry.getValue())
+            if(entry.getValue() && !installedPlugins.contains(entry.getKey()))
             {
                 String name = entry.getKey();
@@ -138,5 +136,5 @@
     /* return true when plugin list changed */
     public void drawPanel(JPanel pluginPanel) {
-        availablePlugins = getAvailablePlugins();
+        loadPlugins();
         Collection<String> enabledPlugins = Main.pref.getCollection("plugins", null);
 
@@ -224,22 +222,6 @@
     }
 
-    /**
-     * Return information about a loaded plugin.
-     *
-     * Note that if you call this in your plugins bootstrap, you may get <code>null</code> if
-     * the plugin requested is not loaded yet.
-     *
-     * @return The PluginInformation to a specific plugin, but only if the plugin is loaded.
-     * If it is not loaded, <code>null</code> is returned.
-     */
-    private static PluginInformation getLoaded(String pluginName) {
-        for (PluginProxy p : PluginHandler.pluginList)
-            if (p.info.name.equals(pluginName))
-                return p.info;
-        return null;
-    }
-
-    private Map<String, PluginInformation> getAvailablePlugins() {
-        SortedMap<String, PluginInformation> availablePlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
+    private void loadPlugins() {
+        availablePlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
             public int compare(String o1, String o2) {
                 return o1.compareToIgnoreCase(o2);
@@ -348,5 +330,4 @@
                 localPlugins.put(proxy.info.name, proxy.info);
         }
-        return availablePlugins;
     }
 }
