Index: /trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java	(revision 6972)
+++ /trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java	(revision 6973)
@@ -4,35 +4,15 @@
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
 
-import java.awt.Font;
-import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.lang.reflect.InvocationTargetException;
 import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
-import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.download.DownloadObjectDialog;
-import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.gui.widgets.JosmTextArea;
-import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -63,108 +43,26 @@
     /**
      * @param newLayer if the data should be downloaded into a new layer
-     * @param ids
+     * @param ids List of primitive id to download
      * @param downloadReferrers if the referrers of the object should be downloaded as well, i.e., parent relations, and for nodes, additionally, parent ways
      * @param full if the members of a relation should be downloaded as well
      */
     public static void processItems(boolean newLayer, final List<PrimitiveId> ids, boolean downloadReferrers, boolean full) {
-        OsmDataLayer layer = getEditLayer();
-        if ((layer == null) || newLayer) {
-            layer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
-            Main.main.addLayer(layer);
-        }
-        final DownloadPrimitivesTask task = new DownloadPrimitivesTask(layer, ids, full);
+        final DownloadPrimitivesWithReferrersTask task =
+                new DownloadPrimitivesWithReferrersTask(newLayer, ids, downloadReferrers, full, null);
         Main.worker.submit(task);
-
-        if (downloadReferrers) {
-            for (PrimitiveId id : ids) {
-                Main.worker.submit(new DownloadReferrersTask(layer, id));
-            }
-        }
-
-        Runnable showErrorsAndWarnings = new Runnable() {
+        Main.worker.submit(new Runnable() {
             @Override
             public void run() {
-                final Set<PrimitiveId> errs = task.getMissingPrimitives();
-                if (errs != null && !errs.isEmpty()) {
-                    try {
-                        SwingUtilities.invokeAndWait(new Runnable() {
-                            @Override
-                            public void run() {
-                                reportProblemDialog(errs,
-                                        trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
-                                        trn("One object could not be downloaded.<br>",
-                                            "{0} objects could not be downloaded.<br>",
-                                            errs.size(),
-                                            errs.size())
-                                        + tr("The server replied with response code 404.<br>"
-                                            + "This usually means, the server does not know an object with the requested id."),
-                                        tr("missing objects:"),
-                                        JOptionPane.ERROR_MESSAGE
-                                ).showDialog();
-                            }
-                        });
-                    } catch (InterruptedException ex) {
-                        Main.warn("InterruptedException while displaying error dialog");
-                    } catch (InvocationTargetException ex) {
-                        Main.warn(ex);
-                    }
-                }
-
-                final Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
-                DataSet ds = getCurrentDataSet();
-                for (PrimitiveId id : ids) {
-                    OsmPrimitive osm = ds.getPrimitiveById(id);
-                    if (osm != null && osm.isDeleted()) {
-                        del.add(id);
-                    }
-                }
-                if (!del.isEmpty()) {
-                    SwingUtilities.invokeLater(new Runnable() {
+                final List<PrimitiveId> downloaded = task.getDownloadedId();
+                if(downloaded != null) {
+                    GuiHelper.runInEDT(new Runnable() {
                         @Override
                         public void run() {
-                            reportProblemDialog(del,
-                                    trn("Object deleted", "Objects deleted", del.size()),
-                                    trn(
-                                        "One downloaded object is deleted.",
-                                        "{0} downloaded objects are deleted.",
-                                        del.size(),
-                                        del.size()),
-                                    null,
-                                    JOptionPane.WARNING_MESSAGE
-                            ).showDialog();
+                            Main.main.getCurrentDataSet().setSelected(downloaded);
                         }
                     });
                 }
             }
-        };
-        Main.worker.submit(showErrorsAndWarnings);
-    }
-
-    private static ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
-            String TITLE, String TEXT, String LIST_LABEL, int msgType) {
-        JPanel p = new JPanel(new GridBagLayout());
-        p.add(new HtmlPanel(TEXT), GBC.eop());
-        if (LIST_LABEL != null) {
-            JLabel missing = new JLabel(LIST_LABEL);
-            missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
-            p.add(missing, GBC.eol());
-        }
-        JosmTextArea txt = new JosmTextArea();
-        txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
-        txt.setEditable(false);
-        txt.setBackground(p.getBackground());
-        txt.setColumns(40);
-        txt.setRows(1);
-        txt.setText(Utils.join(", ", errs));
-        JScrollPane scroll = new JScrollPane(txt);
-        p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
-
-        return new ExtendedDialog(
-                Main.parent,
-                TITLE,
-                new String[] { tr("Ok") })
-            .setButtonIcons(new String[] { "ok" })
-            .setIcon(msgType)
-            .setContent(p, false);
+        });
     }
 }
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java	(revision 6972)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java	(revision 6973)
@@ -131,5 +131,20 @@
      */
     public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId) throws IllegalArgumentException {
-        super("Download referrers", false /* don't ignore exception*/);
+        this(targetLayer,  primitiveId, null);
+    }
+
+    /**
+     * constructor
+     *
+     * @param targetLayer the target layer. Must not be null.
+     * @param primitiveId a PrimitiveId object.
+     * @param progressMonitor ProgressMonitor to use or null to create a new one.
+     * @exception IllegalArgumentException thrown if id &lt;= 0
+     * @exception IllegalArgumentException thrown if targetLayer == null
+     *
+     */
+    public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
+            ProgressMonitor progressMonitor) throws IllegalArgumentException {
+        super("Download referrers", progressMonitor, false /* don't ignore exception*/);
         CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
         if (primitiveId.isNew())
@@ -168,5 +183,6 @@
                     public void run() {
                         targetLayer.onPostDownloadFromServer();
-                        Main.map.mapView.repaint();
+                        if(Main.map != null)
+                            Main.map.mapView.repaint();
                     }
                 }
Index: /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java	(revision 6972)
+++ /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java	(revision 6973)
@@ -9,4 +9,5 @@
 import java.util.Set;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AutoScaleAction;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -52,5 +53,21 @@
      */
     public DownloadPrimitivesTask(OsmDataLayer layer, List<PrimitiveId> ids, boolean fullRelation) throws IllegalArgumentException {
-        super(tr("Download objects"), false /* don't ignore exception */);
+        this(layer, ids, fullRelation, null);
+    }
+
+    /**
+     * Creates the  task
+     *
+     * @param layer the layer in which primitives are updated. Must not be null.
+     * @param ids a collection of primitives to update from the server. Set to
+     *     the empty collection if null.
+     * @param fullRelation true if a full download is required, i.e.,
+     *     a download including the immediate children of a relation.
+     * @param progressMonitor ProgressMonitor to use or null to create a new one.
+     * @throws IllegalArgumentException thrown if layer is null.
+     */
+    public DownloadPrimitivesTask(OsmDataLayer layer, List<PrimitiveId> ids, boolean fullRelation,
+            ProgressMonitor progessMonitor) throws IllegalArgumentException {
+        super(tr("Download objects"), progessMonitor, false /* don't ignore exception */);
         ensureParameterNotNull(layer, "layer");
         this.ids = ids;
@@ -84,5 +101,6 @@
             public void run() {
                 layer.mergeFrom(ds);
-                AutoScaleAction.zoomTo(ds.allPrimitives());
+                if(Main.map != null)
+                    AutoScaleAction.zoomTo(ds.allPrimitives());
                 layer.onPostDownloadFromServer();
             }
Index: /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java	(revision 6973)
+++ /trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java	(revision 6973)
@@ -0,0 +1,229 @@
+package org.openstreetmap.josm.gui.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.Font;
+import java.awt.GridBagLayout;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.gui.widgets.JosmTextArea;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.SAXException;
+
+/**
+ * Task for downloading a set of primitives with all referrers.
+ */
+public class DownloadPrimitivesWithReferrersTask extends PleaseWaitRunnable {
+    /** If true download into a new layer */
+    private final boolean newLayer;
+    /** List of primitives id to download */
+    private final List<PrimitiveId> ids;
+    /** If true, download members for relation */
+    private final boolean full;
+    /** If true, download also referrers */
+    private final boolean downloadReferrers;
+
+    /** Temporary layer where downloaded primitives are put */
+    private OsmDataLayer tmpLayer;
+    /** Reference to the task that download requested primitives */
+    private DownloadPrimitivesTask mainTask;
+    /** Flag indicated that user ask for cancel this task */
+    private boolean canceled = false;
+    /** Reference to the task currently running */
+    private PleaseWaitRunnable currentTask = null;
+
+    /**
+     * Constructor
+     *
+     * @param newLayer if the data should be downloaded into a new layer
+     * @param ids List of primitive id to download
+     * @param downloadReferrers if the referrers of the object should be downloaded as well,
+     *     i.e., parent relations, and for nodes, additionally, parent ways
+     * @param full if the members of a relation should be downloaded as well
+     * @param monitor ProgressMonitor to use, or null to create a new one
+     */
+    public DownloadPrimitivesWithReferrersTask(boolean newLayer, List<PrimitiveId> ids, boolean downloadReferrers,
+            boolean full, ProgressMonitor monitor) {
+        super(tr("Download objects"), monitor, false);
+        this.ids = ids;
+        this.downloadReferrers = downloadReferrers;
+        this.full = full;
+        this.newLayer = newLayer;
+        // All downloaded primitives are put in a tmpLayer
+        tmpLayer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
+        //Main.main.addLayer(tmpLayer);
+    }
+
+    /**
+     * Cancel recursively the task. Do not call directly
+     * @see DownloadPrimitivesWithReferrersTask#operationCancel
+     */
+    @Override
+    protected void cancel() {
+        synchronized(this) {
+            canceled = true;
+            if(currentTask != null)
+                currentTask.operationCanceled();
+        }
+    }
+
+    @Override
+    protected void realRun() throws SAXException, IOException, OsmTransferException {
+        getProgressMonitor().setTicksCount(ids.size()+1);
+        // First, download primitives
+        mainTask = new DownloadPrimitivesTask(tmpLayer, ids, full, getProgressMonitor().createSubTaskMonitor(1, false));
+        currentTask = mainTask;
+        synchronized(this) {
+            if(canceled) {
+                currentTask = null;
+                return;
+            }
+        }
+        currentTask.run();
+        // Then, download referrers for each primitive
+        if(downloadReferrers)
+            for(PrimitiveId id : ids) {
+                synchronized(this) {
+                    if(canceled) {
+                        currentTask = null;
+                        return;
+                    }
+                    currentTask = new DownloadReferrersTask(
+                            tmpLayer, id, getProgressMonitor().createSubTaskMonitor(1, false));
+                }
+                currentTask.run();
+            }
+        currentTask = null;
+    }
+
+    @Override
+    protected void finish() {
+        if(canceled)
+            return;
+
+        // Append downloaded data to JOSM
+        OsmDataLayer layer = Main.main.getEditLayer();
+        if(layer == null || this.newLayer)
+            Main.main.addLayer(tmpLayer);
+        else
+            layer.mergeFrom(tmpLayer);
+
+        // Warm about missing primitives
+        final Set<PrimitiveId> errs = mainTask.getMissingPrimitives();
+        if (errs != null && !errs.isEmpty())
+            GuiHelper.runInEDTAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    reportProblemDialog(errs,
+                            trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
+                            trn("One object could not be downloaded.<br>",
+                                    "{0} objects could not be downloaded.<br>",
+                                    errs.size(),
+                                    errs.size())
+                                    + tr("The server replied with response code 404.<br>"
+                                         + "This usually means, the server does not know an object with the requested id."),
+                            tr("missing objects:"),
+                            JOptionPane.ERROR_MESSAGE
+                            ).showDialog();
+                }
+            });
+
+        // Warm about deleted primitives
+        final Set<PrimitiveId> del = new HashSet<PrimitiveId>();
+        DataSet ds = Main.main.getCurrentDataSet();
+        for (PrimitiveId id : ids) {
+            OsmPrimitive osm = ds.getPrimitiveById(id);
+            if (osm != null && osm.isDeleted()) {
+                del.add(id);
+            }
+        }
+        if (!del.isEmpty())
+            GuiHelper.runInEDTAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    reportProblemDialog(del,
+                            trn("Object deleted", "Objects deleted", del.size()),
+                            trn(
+                                "One downloaded object is deleted.",
+                                "{0} downloaded objects are deleted.",
+                                del.size(),
+                                del.size()),
+                            null,
+                            JOptionPane.WARNING_MESSAGE
+                    ).showDialog();
+                }
+            });
+    }
+
+    /**
+     * Return id of really downloaded primitives.
+     * @return List of primitives id or null if no primitives was downloaded
+     */
+    public List<PrimitiveId> getDownloadedId() {
+        if(canceled)
+            return null;
+        ArrayList<PrimitiveId> downloaded = new ArrayList<PrimitiveId>(ids);
+        downloaded.removeAll(mainTask.getMissingPrimitives());
+        return downloaded;
+    }
+
+    /**
+     * Dialog for report a problem during download.
+     * @param errs Primitives involved
+     * @param TITLE Title of dialog
+     * @param TEXT Detail message
+     * @param LIST_LABEL List of primitives description
+     * @param msgType Type of message {@see JOptionPane}
+     * @return The Dialog object
+     */
+    private static ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
+            String TITLE, String TEXT, String LIST_LABEL, int msgType) {
+        JPanel p = new JPanel(new GridBagLayout());
+        p.add(new HtmlPanel(TEXT), GBC.eop());
+        if (LIST_LABEL != null) {
+            JLabel missing = new JLabel(LIST_LABEL);
+            missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
+            p.add(missing, GBC.eol());
+        }
+        JosmTextArea txt = new JosmTextArea();
+        txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
+        txt.setEditable(false);
+        txt.setBackground(p.getBackground());
+        txt.setColumns(40);
+        txt.setRows(1);
+        txt.setText(Utils.join(", ", errs));
+        JScrollPane scroll = new JScrollPane(txt);
+        p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
+
+        return new ExtendedDialog(
+                Main.parent,
+                TITLE,
+                new String[] { tr("Ok") })
+        .setButtonIcons(new String[] { "ok" })
+        .setIcon(msgType)
+        .setContent(p, false);
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 6972)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 6973)
@@ -8,7 +8,7 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.DownloadPrimitiveAction;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
@@ -33,5 +33,5 @@
         return new String[]{"objects"};
     }
-    
+
     @Override
     public String[] getOptionalParams() {
@@ -61,13 +61,19 @@
             final boolean relationMembers = Boolean.parseBoolean(args.get("relation_members"));
             final boolean referrers = args.containsKey("referrers") ? Boolean.parseBoolean(args.get("referrers")) : true;
-            GuiHelper.runInEDTAndWait(new Runnable() {
-                @Override public void run() {
-                    DownloadPrimitiveAction.processItems(newLayer, ps, referrers, relationMembers);
-                }
-            });
-            GuiHelper.executeByMainWorkerInEDT(new Runnable() {
+            final DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(
+                    newLayer, ps, referrers, relationMembers, null);
+            Main.worker.submit(task);
+            Main.worker.submit(new Runnable() {
                 @Override
                 public void run() {
-                    Main.main.getCurrentDataSet().setSelected(ps);
+                    final List<PrimitiveId> downloaded = task.getDownloadedId();
+                    if(downloaded != null) {
+                        GuiHelper.runInEDT(new Runnable() {
+                            @Override
+                            public void run() {
+                                Main.main.getCurrentDataSet().setSelected(downloaded);
+                            }
+                        });
+                    }
                     AddTagsDialog.addTags(args, sender);
                     ps.clear();
