Index: trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 1880)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 1881)
@@ -10,10 +10,6 @@
 import java.util.List;
 
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList;
 import org.openstreetmap.josm.data.osm.DataSource;
-import org.openstreetmap.josm.gui.OptionPaneUtil;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -43,7 +39,10 @@
         if (! isEnabled())
             return;
+        if (getEditLayer() == null)
+            return;
+
         int bboxCount = 0;
         List<Area> areas = new ArrayList<Area>();
-        for(DataSource ds : Main.map.mapView.getEditLayer().data.dataSources) {
+        for(DataSource ds : getEditLayer().data.dataSources) {
             areas.add(new Area(ds.bounds.asRect()));
         }
@@ -73,14 +72,13 @@
 
         if(bboxCount == 0) {
-            OptionPaneUtil.showMessageDialog(
-                    Main.parent,
-                    tr("No data to update found. Have you already opened or downloaded a data layer?"),
-                    tr("No data"),
-                    JOptionPane.WARNING_MESSAGE
-            );
-            return;
+            // no bounds defined in the dataset? we update all primitives in the data set
+            // using a series of multi fetch requests
+            //
+            new UpdateSelectionAction().updatePrimitives(getEditLayer().data.allPrimitives());
+        } else {
+            // bounds defined? => use the bbox downloader
+            //
+            new DownloadOsmTaskList().download(false, areas, new PleaseWaitProgressMonitor());
         }
-
-        new DownloadOsmTaskList().download(false, areas, new PleaseWaitProgressMonitor());
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 1880)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 1881)
@@ -8,6 +8,5 @@
 import java.io.IOException;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Collections;
 
 import javax.swing.JOptionPane;
@@ -15,5 +14,10 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
+import org.openstreetmap.josm.gui.ExceptionDialogUtil;
 import org.openstreetmap.josm.gui.OptionPaneUtil;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
@@ -21,5 +25,4 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
-import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -28,5 +31,4 @@
 /**
  * This action synchronizes a set of primitives with their state on the server.
- *
  *
  */
@@ -45,40 +47,7 @@
             ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
         } catch(Exception e) {
-            handleUpdateException(e);
-            return;
+            ExceptionDialogUtil.explainException(e);
         }
         Main.map.mapView.getEditLayer().mergeFrom(ds);
-    }
-
-
-    /**
-     * handle an exception thrown during updating a primitive
-     *
-     * @param id the id of the primitive
-     * @param e the exception
-     */
-    protected void handleUpdateException(Exception e) {
-        e.printStackTrace();
-        OptionPaneUtil.showMessageDialog(
-                Main.parent,
-                tr("Failed to update the selected primitives."),
-                tr("Update failed"),
-                JOptionPane.ERROR_MESSAGE
-        );
-    }
-
-    /**
-     * handles an exception case: primitive with id <code>id</code> is not in the current
-     * data set
-     *
-     * @param id the primitive id
-     */
-    protected void handleMissingPrimitive(long id) {
-        OptionPaneUtil.showMessageDialog(
-                Main.parent,
-                tr("Could not find primitive with id {0} in the current dataset", new Long(id).toString()),
-                tr("Missing primitive"),
-                JOptionPane.ERROR_MESSAGE
-        );
     }
 
@@ -91,67 +60,6 @@
      */
     public void updatePrimitives(final Collection<OsmPrimitive> selection) {
-
-        /**
-         * The asynchronous task for updating the data using multi fetch.
-         *
-         */
-        class UpdatePrimitiveTask extends PleaseWaitRunnable {
-            private DataSet ds;
-            private boolean cancelled;
-            Exception lastException;
-
-            public UpdatePrimitiveTask() {
-                super("Update primitives", false /* don't ignore exception*/);
-                cancelled = false;
-            }
-
-            protected void showLastException() {
-                String msg = lastException.getMessage();
-                if (msg == null) {
-                    msg = lastException.toString();
-                }
-                OptionPaneUtil.showMessageDialog(
-                        Main.map,
-                        msg,
-                        tr("Error"),
-                        JOptionPane.ERROR_MESSAGE
-                );
-            }
-
-            @Override
-            protected void cancel() {
-                cancelled = true;
-                OsmApi.getOsmApi().cancel();
-            }
-
-            @Override
-            protected void finish() {
-                if (cancelled)
-                    return;
-                if (lastException != null) {
-                    showLastException();
-                    return;
-                }
-                if (ds != null) {
-                    Main.map.mapView.getEditLayer().mergeFrom(ds);
-                }
-            }
-
-            @Override
-            protected void realRun() throws SAXException, IOException, OsmTransferException {
-                progressMonitor.indeterminateSubTask("");
-                try {
-                    MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
-                    reader.append(selection);
-                    ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
-                } catch(Exception e) {
-                    if (cancelled)
-                        return;
-                    lastException = e;
-                }
-            }
-        }
-
-        Main.worker.submit(new UpdatePrimitiveTask());
+        UpdatePrimitivesTask task = new UpdatePrimitivesTask(selection);
+        Main.worker.submit(task);
     }
 
@@ -161,11 +69,16 @@
      *
      * @param id  the id of a primitive in the {@see DataSet} of the current edit layser
-     *
-     */
-    public void updatePrimitive(long id) {
-        OsmPrimitive primitive = Main.map.mapView.getEditLayer().data.getPrimitiveById(id);
-        Set<OsmPrimitive> s = new HashSet<OsmPrimitive>();
-        s.add(primitive);
-        updatePrimitives(s);
+     * @exception IllegalStateException thrown if there is no primitive with <code>id</code> in
+     *   the current dataset
+     * @exception IllegalStateException thrown if there is no current dataset
+     * 
+     */
+    public void updatePrimitive(long id) throws IllegalStateException{
+        if (getEditLayer() == null)
+            throw new IllegalStateException(tr("No current dataset found"));
+        OsmPrimitive primitive = getEditLayer().data.getPrimitiveById(id);
+        if (primitive == null)
+            throw new IllegalStateException(tr("Didn't find a primitive with id {0} in the current dataset", id));
+        updatePrimitives(Collections.singleton(primitive));
     }
 
@@ -213,3 +126,91 @@
         updatePrimitives(selection);
     }
+
+    /**
+     * The asynchronous task for updating the data using multi fetch.
+     *
+     */
+    class UpdatePrimitivesTask extends PleaseWaitRunnable {
+        private DataSet ds;
+        private boolean canceled;
+        private Exception lastException;
+        private Collection<? extends OsmPrimitive> toUpdate;
+        private MultiFetchServerObjectReader reader;
+
+        public UpdatePrimitivesTask(Collection<? extends OsmPrimitive> toUpdate) {
+            super("Update primitives", false /* don't ignore exception*/);
+            canceled = false;
+            this.toUpdate = toUpdate;
+        }
+
+        @Override
+        protected void cancel() {
+            canceled = true;
+            if (reader != null) {
+                reader.cancel();
+            }
+        }
+
+        @Override
+        protected void finish() {
+            if (canceled)
+                return;
+            if (lastException != null) {
+                ExceptionDialogUtil.explainException(lastException);
+                return;
+            }
+            if (ds != null) {
+                Main.map.mapView.getEditLayer().mergeFrom(ds);
+            }
+        }
+
+        protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
+            for (OsmPrimitive primitive : toUpdate) {
+                if (primitive instanceof Node && primitive.id > 0) {
+                    reader.append((Node)primitive);
+                } else if (primitive instanceof Way) {
+                    Way way = (Way)primitive;
+                    for (Node node: way.nodes) {
+                        reader.append(node);
+                    }
+                }
+            }
+        }
+
+        protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
+            for (OsmPrimitive primitive : toUpdate) {
+                if (primitive instanceof Way && primitive.id > 0) {
+                    reader.append((Way)primitive);
+                }
+            }
+        }
+
+        protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
+            for (OsmPrimitive primitive : toUpdate) {
+                if (primitive instanceof Relation && primitive.id > 0) {
+                    reader.append((Relation)primitive);
+                }
+            }
+        }
+
+        @Override
+        protected void realRun() throws SAXException, IOException, OsmTransferException {
+            progressMonitor.indeterminateSubTask("");
+            this.ds = new DataSet();
+            DataSet theirDataSet;
+            try {
+                reader = new MultiFetchServerObjectReader();
+                initMultiFetchReaderWithNodes(reader);
+                initMultiFetchReaderWithWays(reader);
+                initMultiFetchReaderWithRelations(reader);
+                theirDataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
+                MergeVisitor merger = new MergeVisitor(ds, theirDataSet);
+                merger.merge();
+            } catch(Exception e) {
+                if (canceled)
+                    return;
+                lastException = e;
+            }
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 1880)
+++ trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 1881)
@@ -63,4 +63,6 @@
     private DataSet outputDataSet;
 
+    private boolean cancelled = false;
+
     /**
      * constructor
@@ -230,5 +232,5 @@
      *
      */
-    public MultiFetchServerObjectReader append(Collection<OsmPrimitive> primitives) {
+    public MultiFetchServerObjectReader append(Collection<? extends OsmPrimitive> primitives) {
         if (primitives == null) return this;
         for (OsmPrimitive primitive : primitives) {
@@ -363,4 +365,5 @@
         for (long id : pkg) {
             try {
+                progressMonitor.setCustomText(tr("Fetching {0} with id {1} from ''{2}''", type.getLocalizedDisplayNameSingular(), id, OsmApi.getOsmApi().getBaseUrl()));
                 singleGetId(type, id, progressMonitor);
             } catch(OsmApiException e) {
@@ -394,7 +397,8 @@
      */
     protected void fetchPrimitives(Set<Long> ids, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
+        progressMonitor.setCustomText(tr("Fetching a package of {0} from ''{1}''", type.getLocalizedDisplayNameSingular(), OsmApi.getOsmApi().getBaseUrl()));
         Set<Long> toFetch = new HashSet<Long>(ids);
         toFetch.addAll(ids);
-        while(! toFetch.isEmpty()) {
+        while(! toFetch.isEmpty() && !isCanceled()) {
             Set<Long> pkg = extractIdPackage(toFetch);
             try {
@@ -435,7 +439,9 @@
         try {
             missingPrimitives = new HashSet<Long>();
-
+            if (isCanceled())return null;
             fetchPrimitives(nodes,OsmPrimitiveType.NODE, progressMonitor);
+            if (isCanceled())return null;
             fetchPrimitives(ways,OsmPrimitiveType.WAY, progressMonitor);
+            if (isCanceled())return null;
             fetchPrimitives(relations,OsmPrimitiveType.RELATION, progressMonitor);
             return outputDataSet;
Index: trunk/src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 1880)
+++ trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 1881)
@@ -145,3 +145,13 @@
         con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
     }
+
+    /**
+     * Replies true if this connection is canceled
+     * 
+     * @return true if this connection is canceled
+     * @return
+     */
+    public boolean isCanceled() {
+        return cancel;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 1880)
+++ trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 1881)
@@ -329,18 +329,18 @@
         for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) {
             Way w = new Way(e.getKey().id);
-            boolean failed = false;
+            boolean incomplete = false;
             for (long id : e.getValue()) {
                 Node n = findNode(id);
                 if (n == null) {
-                    failed = true;
-                    break;
+                    n = new Node(id);
+                    n.incomplete = true;
+                    incomplete = true;
                 }
                 w.nodes.add(n);
             }
-            if (failed) {
-                logger.warning(tr("marked way {0} incomplete because referred nodes are missing in the loaded data", e.getKey().id));
+            if (incomplete) {
+                logger.warning(tr("marked way {0} with {1} nodes incomplete because at least one node was missing in the loaded data and is therefore incomplete too", e.getKey().id, w.nodes.size()));
                 e.getKey().copyTo(w);
                 w.incomplete = true;
-                w.nodes.clear();
                 ds.addPrimitive(w);
             } else {
