Index: trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 2598)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList;
 import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -38,4 +39,8 @@
     protected void updateEnabledState() {
         setEnabled(getEditLayer() != null);
+    }
+
+    public void updateLayer(OsmDataLayer layer) {
+        
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 2598)
@@ -3,9 +3,9 @@
 
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
@@ -15,19 +15,12 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.DataSetMerger;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.gui.ExceptionDialogUtil;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.io.UpdatePrimitivesTask;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
-import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
-import org.openstreetmap.josm.io.OsmServerObjectReader;
-import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.xml.sax.SAXException;
 
 /**
@@ -42,5 +35,5 @@
      * @param id the primitive id
      */
-    protected void handlePrimitiveGoneException(long id, OsmPrimitiveType type) {
+    public void handlePrimitiveGoneException(long id, OsmPrimitiveType type) {
         MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
         reader.append(getCurrentDataSet(),id, type);
@@ -62,5 +55,5 @@
      */
     public void updatePrimitives(final Collection<OsmPrimitive> selection) {
-        UpdatePrimitivesTask task = new UpdatePrimitivesTask(selection);
+        UpdatePrimitivesTask task = new UpdatePrimitivesTask(Main.main.getEditLayer(),selection);
         Main.worker.submit(task);
     }
@@ -70,5 +63,6 @@
      * with the data currently kept on the server.
      *
-     * @param id  the id of a primitive in the {@see DataSet} of the current edit layer
+     * @param id  the id of a primitive in the {@see DataSet} of the current edit layer. Must not be null.
+     * @throws IllegalArgumentException thrown if id is null
      * @exception IllegalStateException thrown if there is no primitive with <code>id</code> in
      *   the current dataset
@@ -76,8 +70,9 @@
      *
      */
-    public void updatePrimitive(OsmPrimitiveType type, long id) throws IllegalStateException{
+    public void updatePrimitive(PrimitiveId id) throws IllegalStateException, IllegalArgumentException{
+        ensureParameterNotNull(id, "id");
         if (getEditLayer() == null)
             throw new IllegalStateException(tr("No current dataset found"));
-        OsmPrimitive primitive = getEditLayer().data.getPrimitiveById(id, type);
+        OsmPrimitive primitive = getEditLayer().data.getPrimitiveById(id);
         if (primitive == null)
             throw new IllegalStateException(tr("Didn''t find an object with id {0} in the current dataset", id));
@@ -132,112 +127,3 @@
         updatePrimitives(selection);
     }
-
-    /**
-     * The asynchronous task for updating the data using multi fetch.
-     *
-     */
-    static class UpdatePrimitivesTask extends PleaseWaitRunnable {
-        //static private final Logger logger = Logger.getLogger(UpdatePrimitivesTask.class.getName());
-
-        private DataSet ds;
-        private boolean canceled;
-        private Exception lastException;
-        private Collection<? extends OsmPrimitive> toUpdate;
-        private MultiFetchServerObjectReader reader;
-
-        /**
-         *
-         * @param toUpdate a collection of primitives to update from the server
-         */
-        public UpdatePrimitivesTask(Collection<? extends OsmPrimitive> toUpdate) {
-            super(tr("Update objects"), 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.main.getEditLayer() != null) {
-                Main.main.getEditLayer().mergeFrom(ds);
-                Main.main.getEditLayer().onPostDownloadFromServer();
-            }
-        }
-
-        protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
-            for (OsmPrimitive primitive : toUpdate) {
-                if (primitive instanceof Node && !primitive.isNew()) {
-                    reader.append((Node)primitive);
-                } else if (primitive instanceof Way) {
-                    Way way = (Way)primitive;
-                    for (Node node: way.getNodes()) {
-                        if (!node.isNew()) {
-                            reader.append(node);
-                        }
-                    }
-                }
-            }
-        }
-
-        protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
-            for (OsmPrimitive primitive : toUpdate) {
-                if (primitive instanceof Way && !primitive.isNew()) {
-                    reader.append((Way)primitive);
-                }
-            }
-        }
-
-        protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
-            for (OsmPrimitive primitive : toUpdate) {
-                if (primitive instanceof Relation && !primitive.isNew()) {
-                    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));
-                DataSetMerger merger = new DataSetMerger(ds, theirDataSet);
-                merger.merge();
-                // a way loaded with MultiFetch may be incomplete because at least one of its
-                // nodes isn't present in the local data set. We therefore fully load all
-                // incomplete ways.
-                //
-                for (Way w : ds.getWays()) {
-                    if (w.isIncomplete()) {
-                        OsmServerObjectReader reader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */);
-                        theirDataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
-                        merger = new DataSetMerger(ds, theirDataSet);
-                        merger.merge();
-                    }
-                }
-            } catch(Exception e) {
-                if (canceled)
-                    return;
-                lastException = e;
-            }
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2598)
@@ -7,14 +7,6 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import javax.swing.JOptionPane;
@@ -24,30 +16,10 @@
 import org.openstreetmap.josm.actions.upload.RelationUploadOrderHook;
 import org.openstreetmap.josm.actions.upload.UploadHook;
-import org.openstreetmap.josm.actions.upload.UploadParameterHook;
 import org.openstreetmap.josm.data.APIDataSet;
 import org.openstreetmap.josm.data.conflict.ConflictCollection;
-import org.openstreetmap.josm.data.osm.Changeset;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
-import org.openstreetmap.josm.gui.DefaultNameFormatter;
-import org.openstreetmap.josm.gui.ExceptionDialogUtil;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
 import org.openstreetmap.josm.gui.io.UploadDialog;
-import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
+import org.openstreetmap.josm.gui.io.UploadPrimitivesTask;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.progress.ProgressMonitor;
-import org.openstreetmap.josm.io.ChangesetClosedException;
-import org.openstreetmap.josm.io.OsmApi;
-import org.openstreetmap.josm.io.OsmApiException;
-import org.openstreetmap.josm.io.OsmApiInitializationException;
-import org.openstreetmap.josm.io.OsmApiPrimitiveGoneException;
-import org.openstreetmap.josm.io.OsmServerWriter;
-import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.tools.DateUtils;
-import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.xml.sax.SAXException;
 
 /**
@@ -84,10 +56,4 @@
          */
         uploadHooks.add(new RelationUploadOrderHook());
-
-        /**
-         * Displays a screen where the actions that would be taken are displayed and
-         * give the user the possibility to cancel the upload.
-         */
-        uploadHooks.add(new UploadParameterHook());
     }
 
@@ -168,11 +134,18 @@
         if (!checkPreUploadConditions(layer, apiData))
             return;
+
+        final UploadDialog dialog = UploadDialog.getUploadDialog();
+        dialog.setUploadedPrimitives(apiData);
+        dialog.setVisible(true);
+        if (dialog.isCanceled())
+            return;
+        dialog.rememberUserInput();
+
         Main.worker.execute(
                 new UploadPrimitivesTask(
                         UploadDialog.getUploadDialog().getUploadStrategySpecification(),
                         layer,
-                        apiData.getPrimitives(),
-                        UploadDialog.getUploadDialog().getChangeset(),
-                        UploadDialog.getUploadDialog().isDoCloseAfterUpload()
+                        apiData,
+                        UploadDialog.getUploadDialog().getChangeset()
                 )
         );
@@ -194,491 +167,3 @@
         uploadData(Main.map.mapView.getEditLayer(), apiData);
     }
-
-    /**
-     * Synchronizes the local state of an {@see OsmPrimitive} with its state on the
-     * server. The method uses an individual GET for the primitive.
-     *
-     * @param id the primitive ID
-     */
-    protected void synchronizePrimitive(final OsmPrimitiveType type, final long id) {
-        Main.worker.execute(new UpdatePrimitiveTask(type, id));
-    }
-
-    /**
-     * Synchronizes the local state of the dataset with the state on the server.
-     *
-     * Reuses the functionality of {@see UpdateDataAction}.
-     *
-     * @see UpdateDataAction#actionPerformed(ActionEvent)
-     */
-    protected void synchronizeDataSet() {
-        UpdateDataAction act = new UpdateDataAction();
-        act.actionPerformed(new ActionEvent(this,0,""));
-    }
-
-    /**
-     * Handles the case that a conflict in a specific {@see OsmPrimitive} was detected while
-     * uploading
-     *
-     * @param primitiveType  the type of the primitive, either <code>node</code>, <code>way</code> or
-     *    <code>relation</code>
-     * @param id  the id of the primitive
-     * @param serverVersion  the version of the primitive on the server
-     * @param myVersion  the version of the primitive in the local dataset
-     */
-    protected void handleUploadConflictForKnownConflict(final OsmPrimitiveType primitiveType, final long id, String serverVersion, String myVersion) {
-        String lbl = "";
-        switch(primitiveType) {
-        case NODE: lbl =  tr("Synchronize node {0} only", id); break;
-        case WAY: lbl =  tr("Synchronize way {0} only", id); break;
-        case RELATION: lbl =  tr("Synchronize relation {0} only", id); break;
-        }
-        ButtonSpec[] spec = new ButtonSpec[] {
-                new ButtonSpec(
-                        lbl,
-                        ImageProvider.get("updatedata"),
-                        null,
-                        null
-                ),
-                new ButtonSpec(
-                        tr("Synchronize entire dataset"),
-                        ImageProvider.get("updatedata"),
-                        null,
-                        null
-                ),
-                new ButtonSpec(
-                        tr("Cancel"),
-                        ImageProvider.get("cancel"),
-                        null,
-                        null
-                )
-        };
-        String msg =  tr("<html>Uploading <strong>failed</strong> because the server has a newer version of one<br>"
-                + "of your nodes, ways, or relations.<br>"
-                + "The conflict is caused by the <strong>{0}</strong> with id <strong>{1}</strong>,<br>"
-                + "the server has version {2}, your version is {3}.<br>"
-                + "<br>"
-                + "Click <strong>{4}</strong> to synchronize the conflicting primitive only.<br>"
-                + "Click <strong>{5}</strong> to synchronize the entire local dataset with the server.<br>"
-                + "Click <strong>{6}</strong> to abort and continue editing.<br></html>",
-                tr(primitiveType.getAPIName()), id, serverVersion, myVersion,
-                spec[0].text, spec[1].text, spec[2].text
-        );
-        int ret = HelpAwareOptionPane.showOptionDialog(
-                Main.parent,
-                msg,
-                tr("Conflicts detected"),
-                JOptionPane.ERROR_MESSAGE,
-                null,
-                spec,
-                spec[0],
-                "/Concepts/Conflict"
-        );
-        switch(ret) {
-        case 0: synchronizePrimitive(primitiveType, id); break;
-        case 1: synchronizeDataSet(); break;
-        default: return;
-        }
-    }
-
-    /**
-     * Handles the case that a conflict was detected while uploading where we don't
-     * know what {@see OsmPrimitive} actually caused the conflict (for whatever reason)
-     *
-     */
-    protected void handleUploadConflictForUnknownConflict() {
-        ButtonSpec[] spec = new ButtonSpec[] {
-                new ButtonSpec(
-                        tr("Synchronize entire dataset"),
-                        ImageProvider.get("updatedata"),
-                        null,
-                        null
-                ),
-                new ButtonSpec(
-                        tr("Cancel"),
-                        ImageProvider.get("cancel"),
-                        null,
-                        null
-                )
-        };
-        String msg =  tr("<html>Uploading <strong>failed</strong> because the server has a newer version of one<br>"
-                + "of your nodes, ways, or relations.<br>"
-                + "<br>"
-                + "Click <strong>{0}</strong> to synchronize the entire local dataset with the server.<br>"
-                + "Click <strong>{1}</strong> to abort and continue editing.<br></html>",
-                spec[0].text, spec[1].text
-        );
-        int ret = HelpAwareOptionPane.showOptionDialog(
-                Main.parent,
-                msg,
-                tr("Conflicts detected"),
-                JOptionPane.ERROR_MESSAGE,
-                null,
-                spec,
-                spec[0],
-                "Concepts/Conflict"
-        );
-        if (ret == 0) {
-            synchronizeDataSet();
-        }
-    }
-
-    /**
-     * Handles the case that a conflict was detected while uploading where we don't
-     * know what {@see OsmPrimitive} actually caused the conflict (for whatever reason)
-     *
-     */
-    protected void handleUploadConflictForClosedChangeset(long changsetId, Date d) {
-        String msg =  tr("<html>Uploading <strong>failed</strong> because you''ve been using<br>"
-                + "changeset {0} which was already closed at {1}.<br>"
-                + "Please upload again with a new or an existing open changeset.</html>",
-                changsetId, new SimpleDateFormat().format(d)
-        );
-        JOptionPane.showMessageDialog(
-                Main.parent,
-                msg,
-                tr("Changeset closed"),
-                JOptionPane.ERROR_MESSAGE
-        );
-    }
-
-    /**
-     * Handles the case where deleting a node failed because it is still in use in
-     * a non-deleted way on the server.
-     */
-    protected void handleUploadConflictForNodeStillInUse(long nodeId, long wayId) {
-        ButtonSpec[] options = new ButtonSpec[] {
-                new ButtonSpec(
-                        tr("Prepare conflict resolution"),
-                        ImageProvider.get("ok"),
-                        tr("Click to download all parent ways for node {0}", nodeId),
-                        null /* no specific help context */
-                ),
-                new ButtonSpec(
-                        tr("Cancel"),
-                        ImageProvider.get("cancel"),
-                        tr("Click to cancel and to resume editing the map", nodeId),
-                        null /* no specific help context */
-                )
-        };
-        String msg =  tr("<html>Uploading <strong>failed</strong> because you tried "
-                + "to delete node {0} which is still in use in way {1}.<br><br>"
-                + "Click <strong>{2}</strong> to download all parent ways of node {0}.<br>"
-                + "If necessary JOSM will create conflicts which you can resolve in the Conflict Resolution Dialog."
-                + "</html>",
-                nodeId, wayId, options[0].text
-        );
-
-        int ret = HelpAwareOptionPane.showOptionDialog(
-                Main.parent,
-                msg,
-                tr("Node still in use"),
-                JOptionPane.ERROR_MESSAGE,
-                null,
-                options,
-                options[0],
-                "/Action/Upload#NodeStillInUseInWay"
-        );
-        if (ret != 0) return;
-        DownloadReferrersAction.downloadReferrers(Main.map.mapView.getEditLayer(), nodeId, OsmPrimitiveType.NODE);
-    }
-
-    /**
-     * handles an upload conflict, i.e. an error indicated by a HTTP return code 409.
-     *
-     * @param e  the exception
-     */
-    protected void handleUploadConflict(OsmApiException e) {
-        String pattern = "Version mismatch: Provided (\\d+), server had: (\\d+) of (\\S+) (\\d+)";
-        Pattern p = Pattern.compile(pattern);
-        Matcher m = p.matcher(e.getErrorHeader());
-        if (m.matches()) {
-            handleUploadConflictForKnownConflict(OsmPrimitiveType.from(m.group(3)), Long.parseLong(m.group(4)), m.group(2),m.group(1));
-            return;
-        }
-        pattern ="The changeset (\\d+) was closed at (.*)";
-        p = Pattern.compile(pattern);
-        m = p.matcher(e.getErrorHeader());
-        if (m.matches()) {
-            handleUploadConflictForClosedChangeset(Long.parseLong(m.group(1)), DateUtils.fromString(m.group(2)));
-            return;
-        }
-        pattern = "Node (\\d+) is still used by way (\\d+).";
-        p = Pattern.compile(pattern);
-        m = p.matcher(e.getErrorHeader());
-        if (m.matches()) {
-            handleUploadConflictForNodeStillInUse(Long.parseLong(m.group(1)), Long.parseLong(m.group(2)));
-            return;
-        }
-        logger.warning(tr("Warning: error header \"{0}\" did not match with an expected pattern", e.getErrorHeader()));
-        handleUploadConflictForUnknownConflict();
-    }
-
-    /**
-     * handles an precondition failed conflict, i.e. an error indicated by a HTTP return code 412.
-     *
-     * @param e  the exception
-     */
-    protected void handlePreconditionFailed(OsmApiException e) {
-        String pattern = "Precondition failed: Node (\\d+) is still used by way (\\d+).";
-        Pattern p = Pattern.compile(pattern);
-        Matcher m = p.matcher(e.getErrorHeader());
-        if (m.matches()) {
-            handleUploadConflictForNodeStillInUse(Long.parseLong(m.group(1)), Long.parseLong(m.group(2)));
-            return;
-        }
-        logger.warning(tr("Warning: error header \"{0}\" did not match with an expected pattern", e.getErrorHeader()));
-        ExceptionDialogUtil.explainPreconditionFailed(e);
-    }
-
-    /**
-     * Handles an error due to a delete request on an already deleted
-     * {@see OsmPrimitive}, i.e. a HTTP response code 410, where we know what
-     * {@see OsmPrimitive} is responsible for the error.
-     *
-     *  Reuses functionality of the {@see UpdateSelectionAction} to resolve
-     *  conflicts due to mismatches in the deleted state.
-     *
-     * @param primitiveType the type of the primitive
-     * @param id the id of the primitive
-     *
-     * @see UpdateSelectionAction#handlePrimitiveGoneException(long)
-     */
-    protected void handleGoneForKnownPrimitive(OsmPrimitiveType primitiveType, long id) {
-        UpdateSelectionAction act = new UpdateSelectionAction();
-        act.handlePrimitiveGoneException(id,primitiveType);
-    }
-
-    /**
-     * Handles an error which is caused by a delete request for an already deleted
-     * {@see OsmPrimitive} on the server, i.e. a HTTP response code of 410.
-     * Note that an <strong>update</strong> on an already deleted object results
-     * in a 409, not a 410.
-     *
-     * @param e the exception
-     */
-    protected void handleGone(OsmApiPrimitiveGoneException e) {
-        if (e.isKnownPrimitive()) {
-            handleGoneForKnownPrimitive(e.getPrimitiveType(), e.getPrimitiveId());
-        } else {
-            ExceptionDialogUtil.explainGoneForUnknownPrimitive(e);
-        }
-    }
-
-    /**
-     * error handler for any exception thrown during upload
-     *
-     * @param e the exception
-     */
-    protected void handleFailedUpload(Exception e) {
-        // API initialization failed. Notify the user and return.
-        //
-        if (e instanceof OsmApiInitializationException) {
-            ExceptionDialogUtil.explainOsmApiInitializationException((OsmApiInitializationException)e);
-            return;
-        }
-
-        if (e instanceof OsmApiPrimitiveGoneException) {
-            handleGone((OsmApiPrimitiveGoneException)e);
-            return;
-        }
-        if (e instanceof OsmApiException) {
-            OsmApiException ex = (OsmApiException)e;
-            // There was an upload conflict. Let the user decide whether
-            // and how to resolve it
-            //
-            if(ex.getResponseCode() == HttpURLConnection.HTTP_CONFLICT) {
-                handleUploadConflict(ex);
-                return;
-            }
-            // There was a precondition failed. Notify the user.
-            //
-            else if (ex.getResponseCode() == HttpURLConnection.HTTP_PRECON_FAILED) {
-                handlePreconditionFailed(ex);
-                return;
-            }
-            // Tried to update or delete a primitive which never existed on
-            // the server?
-            //
-            else if (ex.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
-                ExceptionDialogUtil.explainNotFound(ex);
-                return;
-            }
-        }
-
-        ExceptionDialogUtil.explainException(e);
-    }
-
-    /**
-     * The asynchronous task to update a specific id
-     *
-     */
-    class UpdatePrimitiveTask extends  PleaseWaitRunnable {
-
-        private boolean uploadCancelled = false;
-        private boolean uploadFailed = false;
-        private Exception lastException = null;
-        private long id;
-        private OsmPrimitiveType type;
-
-        public UpdatePrimitiveTask(OsmPrimitiveType type, long id) {
-            super(tr("Updating primitive"),false /* don't ignore exceptions */);
-            this.id = id;
-            this.type = type;
-        }
-
-        @Override protected void realRun() throws SAXException, IOException {
-            try {
-                UpdateSelectionAction act = new UpdateSelectionAction();
-                act.updatePrimitive(type, id);
-            } catch (Exception sxe) {
-                if (uploadCancelled) {
-                    System.out.println("Ignoring exception caught because upload is canceled. Exception is: " + sxe.toString());
-                    return;
-                }
-                uploadFailed = true;
-                lastException = sxe;
-            }
-        }
-
-        @Override protected void finish() {
-            if (uploadFailed) {
-                handleFailedUpload(lastException);
-            }
-        }
-
-        @Override protected void cancel() {
-            OsmApi.getOsmApi().cancel();
-            uploadCancelled = true;
-        }
-    }
-
-    /**
-     * The task for uploading a collection of primitives
-     *
-     */
-    public class UploadPrimitivesTask extends  PleaseWaitRunnable {
-        private boolean uploadCancelled = false;
-        private Exception lastException = null;
-        private Collection <OsmPrimitive> toUpload;
-        private OsmServerWriter writer;
-        private OsmDataLayer layer;
-        private Changeset changeset;
-        private boolean closeChangesetAfterUpload;
-        private HashSet<OsmPrimitive> processedPrimitives;
-        private UploadStrategySpecification strategy;
-
-        /**
-         * Creates the task
-         * @param strategy the upload strategy
-         * @param layer  the OSM data layer for which data is uploaded
-         * @param toUpload the collection of primitives to upload
-         * @param changeset the changeset to use for uploading
-         * @param closeChangesetAfterUpload true, if the changeset is to be closed after uploading
-         */
-        private UploadPrimitivesTask(UploadStrategySpecification strategy, OsmDataLayer layer, Collection <OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {
-            super(tr("Uploading data for layer ''{0}''", layer.getName()),false /* don't ignore exceptions */);
-            this.toUpload = toUpload;
-            this.layer = layer;
-            this.changeset = changeset;
-            this.strategy = strategy;
-            this.closeChangesetAfterUpload = closeChangesetAfterUpload;
-            this.processedPrimitives = new HashSet<OsmPrimitive>();
-        }
-
-        protected OsmPrimitive getPrimitive(OsmPrimitiveType type, long id) {
-            for (OsmPrimitive p: toUpload) {
-                if (OsmPrimitiveType.from(p).equals(type) && p.getId() == id)
-                    return p;
-            }
-            return null;
-        }
-
-        /**
-         * Retries to recover the upload operation from an exception which was thrown because
-         * an uploaded primitive was already deleted on the server.
-         *
-         * @param e the exception throw by the API
-         * @param monitor a progress monitor
-         * @throws OsmTransferException  thrown if we can't recover from the exception
-         */
-        protected void recoverFromGoneOnServer(OsmApiPrimitiveGoneException e, ProgressMonitor monitor) throws OsmTransferException{
-            if (!e.isKnownPrimitive()) throw e;
-            OsmPrimitive p = getPrimitive(e.getPrimitiveType(), e.getPrimitiveId());
-            if (p == null) throw e;
-            if (p.isDeleted()) {
-                // we tried to delete an already deleted primitive.
-                //
-                System.out.println(tr("Warning: object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.", p.getDisplayName(DefaultNameFormatter.getInstance())));
-                monitor.appendLogMessage(tr("Object ''{0}'' is already deleted. Skipping object in upload.",p.getDisplayName(DefaultNameFormatter.getInstance())));
-                processedPrimitives.addAll(writer.getProcessedPrimitives());
-                processedPrimitives.add(p);
-                toUpload.removeAll(processedPrimitives);
-                return;
-            }
-            // exception was thrown because we tried to *update* an already deleted
-            // primitive. We can't resolve this automatically. Re-throw exception,
-            // a conflict is going to be created later.
-            throw e;
-        }
-
-        @Override protected void realRun() throws SAXException, IOException {
-            writer = new OsmServerWriter();
-            try {
-                while(true) {
-                    try {
-                        getProgressMonitor().subTask(tr("Uploading {0} objects ...", toUpload.size()));
-                        writer.uploadOsm(strategy, toUpload, changeset, getProgressMonitor().createSubTaskMonitor(1, false));
-                        processedPrimitives.addAll(writer.getProcessedPrimitives());
-                        // if we get here we've successfully uploaded the data. Exit the loop.
-                        //
-                        break;
-                    } catch(OsmApiPrimitiveGoneException e) {
-                        // try to recover from the 410 Gone
-                        recoverFromGoneOnServer(e, getProgressMonitor());
-                    }
-                }
-                // if required close the changeset
-                //
-                if (closeChangesetAfterUpload) {
-                    if (changeset != null && changeset.getId() > 0) {
-                        OsmApi.getOsmApi().closeChangeset(changeset, progressMonitor.createSubTaskMonitor(0,false));
-                    }
-                }
-            } catch (Exception e) {
-                if (uploadCancelled) {
-                    System.out.println(tr("Ignoring caught exception because upload is canceled. Exception is: {0}", e.toString()));
-                    return;
-                }
-                lastException = e;
-            }
-        }
-
-        @Override protected void finish() {
-            if (uploadCancelled)
-                return;
-
-            // we always clean up the data, even in case of errors. It's possible the data was
-            // partially uploaded
-            //
-            layer.cleanupAfterUpload(processedPrimitives);
-            layer.fireDataChange();
-            if (lastException != null) {
-                handleFailedUpload(lastException);
-            }
-            layer.onPostUploadToServer();
-            if (lastException != null && lastException instanceof ChangesetClosedException) {
-                UploadDialog.getUploadDialog().removeChangeset(changeset);
-            } else {
-                UploadDialog.getUploadDialog().setOrUpdateChangeset(changeset);
-            }
-        }
-
-        @Override protected void cancel() {
-            uploadCancelled = true;
-            if (writer != null) {
-                writer.cancel();
-            }
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 2598)
@@ -23,4 +23,6 @@
         OsmApi api = OsmApi.getOsmApi();
         try {
+            // FIXME: this should run asynchronously and a progress monitor
+            // should be displayed.
             api.initialize(NullProgressMonitor.INSTANCE);
             long maxNodes = 0;
@@ -28,9 +30,4 @@
                 maxNodes = api.getCapabilities().getLong("waynodes","maximum");
             }
-            long maxElements = 0;
-            if (api.getCapabilities().isDefined("changesets", "maximum_elements")) {
-                maxElements = api.getCapabilities().getLong("changesets", "maximum_elements");
-            }
-
             if (maxNodes > 0) {
                 if( !checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
@@ -40,21 +37,4 @@
                 if( !checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
                     return false;
-            }
-
-            if (maxElements  > 0) {
-                int total = 0;
-                total = apiData.getPrimitivesToAdd().size() + apiData.getPrimitivesToUpdate().size() + apiData.getPrimitivesToDelete().size();
-                if(total > maxElements) {
-                    JOptionPane.showMessageDialog(
-                            Main.parent,
-                            tr("Current number of changes exceeds the max. number of changes, current is {0}, max is {1}",
-                                    total,
-                                    maxElements
-                            ),
-                            tr("API Capabilities Violation"),
-                            JOptionPane.ERROR_MESSAGE
-                    );
-                    return false;
-                }
             }
         } catch (OsmApiInitializationException e) {
Index: trunk/src/org/openstreetmap/josm/actions/upload/UploadParameterHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/upload/UploadParameterHook.java	(revision 2596)
+++ 	(revision )
@@ -1,18 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.actions.upload;
-
-import org.openstreetmap.josm.data.APIDataSet;
-import org.openstreetmap.josm.gui.io.UploadDialog;
-
-public class UploadParameterHook implements UploadHook {
-
-    public boolean checkUpload(APIDataSet apiData) {
-        final UploadDialog dialog = UploadDialog.getUploadDialog();
-        dialog.setUploadedPrimitives(apiData.getPrimitivesToAdd(),apiData.getPrimitivesToUpdate(), apiData.getPrimitivesToDelete());
-        dialog.setVisible(true);
-        if (dialog.isCanceled())
-            return false;
-        dialog.rememberUserInput();
-        return true;
-    }
-}
Index: trunk/src/org/openstreetmap/josm/data/APIDataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/APIDataSet.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/APIDataSet.java	(revision 2598)
@@ -14,4 +14,5 @@
 import java.util.logging.Logger;
 
+import org.openstreetmap.josm.actions.upload.CyclicUploadDependencyException;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -21,10 +22,9 @@
 import org.openstreetmap.josm.data.osm.Way;
 
-import org.openstreetmap.josm.actions.upload.CyclicUploadDependencyException;
-
 /**
  * Represents a collection of {@see OsmPrimitive}s which should be uploaded to the
  * API.
- * The collection is derived from the modified primitives of an {@see DataSet}.
+ * The collection is derived from the modified primitives of an {@see DataSet} and it provides methods
+ * for sorting the objects in upload order.
  *
  */
@@ -212,4 +212,20 @@
 
     /**
+     * Replies the number of objects to upload
+     * 
+     * @return the number of objects to upload
+     */
+    public int getSize() {
+        return toAdd.size() + toUpdate.size() + toDelete.size();
+    }
+
+    public void removeProcessed(Collection<OsmPrimitive> processed) {
+        if (processed == null) return;
+        toAdd.removeAll(processed);
+        toUpdate.removeAll(processed);
+        toDelete.removeAll(processed);
+    }
+
+    /**
      * Adjusts the upload order for new relations. Child relations are uploaded first,
      * parent relations second.
Index: trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 2598)
@@ -1,6 +1,4 @@
 // License: GPL. Copyright 2007 by Martijn van Oosterhout and others
 package org.openstreetmap.josm.data.osm;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.util.Collection;
@@ -100,8 +98,4 @@
     }
 
-    public String getLocalName(){
-        return tr("Changeset {0}",getId());
-    }
-
     public String getDisplayName(NameFormatter formatter) {
         return formatter.format(this);
@@ -308,3 +302,7 @@
         return tags.keySet();
     }
+
+    public boolean isNew() {
+        return id <= 0;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/PrimitiveData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/PrimitiveData.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/PrimitiveData.java	(revision 2598)
@@ -173,3 +173,6 @@
     }
 
+    public boolean isNew() {
+        return id <= 0;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/PrimitiveId.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/PrimitiveId.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/PrimitiveId.java	(revision 2598)
@@ -5,6 +5,12 @@
 
     long getUniqueId();
-
     OsmPrimitiveType getType();
 
+    /**
+     * Replies true if this id represents a new primitive.
+     * 
+     * @return true if this id represents a new primitive.
+     */
+    boolean isNew();
+
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java	(revision 2598)
@@ -171,3 +171,7 @@
         return member.getUniqueId();
     }
+
+    public boolean isNew() {
+        return member.isNew();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java	(revision 2598)
@@ -51,3 +51,6 @@
     }
 
+    public boolean isNew() {
+        return memberId <= 0;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java	(revision 2598)
@@ -18,4 +18,8 @@
     public long getUniqueId() {
         return id;
+    }
+
+    public boolean isNew() {
+        return id <= 0;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 2596)
+++ trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 2598)
@@ -59,5 +59,5 @@
                 tr("Error"),
                 JOptionPane.ERROR_MESSAGE,
-                ht("/ErrorMessages#ChangesetClosedException")
+                ht("/Action/Upload#ChangesetClosed")
         );
     }
