Index: src/org/openstreetmap/josm/io/DiffResultProcessor.java
===================================================================
--- src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 3330)
+++ src/org/openstreetmap/josm/io/DiffResultProcessor.java	(working copy)
@@ -124,6 +124,7 @@
                 processed.add(p);
                 if (!p.isDeleted()) {
                     p.setOsmId(entry.new_id, entry.new_version);
+                    p.setVisible(true);
                 }
                 if (cs != null && !cs.isNew()) {
                     p.setChangesetId(cs.getId());
Index: src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmApi.java	(revision 3330)
+++ src/org/openstreetmap/josm/io/OsmApi.java	(working copy)
@@ -274,6 +274,7 @@
             ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true), monitor);
             osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim()));
             osm.setChangesetId(getChangeset().getId());
+            osm.setVisible(true);
         } catch(NumberFormatException e) {
             throw new OsmTransferException(tr("Unexpected format of new version of modified primitive ''{0}''. Got ''{1}''.", osm.getId(), ret));
         }
Index: src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmWriter.java	(revision 3330)
+++ src/org/openstreetmap/josm/io/OsmWriter.java	(working copy)
@@ -97,7 +97,7 @@
     }
 
     private boolean shouldWrite(OsmPrimitive osm) {
-        return !osm.isNew() || !osm.isDeleted();
+        return (!osm.isNew() && osm.isVisible()) || !osm.isDeleted();
     }
 
     public void writeDataSources(DataSet ds) {
Index: src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3330)
+++ src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(working copy)
@@ -391,6 +391,14 @@
     }
 
     /**
+     * Replies <code>true</code> if the object has been deleted on the server and was undeleted by the user.
+     * @return <code>true</code> if the object has been undeleted
+     */
+    public boolean isUndeleted() {
+        return (flags & (FLAG_VISIBLE + FLAG_DELETED)) == 0;
+    }
+
+    /**
      * Replies <code>true</code>, if the object is usable (i.e. complete
      * and not deleted).
      *
@@ -426,25 +434,25 @@
 
     public static Predicate<OsmPrimitive> nonDeletedPredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted();
+            return !primitive.isDeleted();
         }
     };
 
     public static Predicate<OsmPrimitive> nonDeletedCompletePredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete();
+            return !primitive.isDeleted() && !primitive.isIncomplete();
         }
     };
 
     public static Predicate<OsmPrimitive> nonDeletedPhysicalPredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof Relation);
+            return !primitive.isDeleted() && !primitive.isIncomplete() && !(primitive instanceof Relation);
         }
     };
 
     public static Predicate<OsmPrimitive> modifiedPredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && primitive.isModified();
+            return primitive.isModified();
         }
     };
 
@@ -721,7 +729,7 @@
         } else {
             flags &= ~FLAG_DELETED;
         }
-        setModified(deleted);
+        setModified(deleted ^ !isVisible());
         if (dataSet != null) {
             if (deleted) {
                 dataSet.firePrimitivesRemoved(Collections.singleton(this), false);
Index: src/org/openstreetmap/josm/data/APIDataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/APIDataSet.java	(revision 3330)
+++ src/org/openstreetmap/josm/data/APIDataSet.java	(working copy)
@@ -56,10 +56,14 @@
         toUpdate.clear();
         toDelete.clear();
 
+        boolean sortUpdated = false;
         for (OsmPrimitive osm :ds.allPrimitives()) {
             if (osm.get("josm/ignore") != null) {
                 continue;
             }
+            if (osm.isUndeleted()) {
+                sortUpdated = true;
+            }
             if (osm.isNew() && !osm.isDeleted()) {
                 toAdd.add(osm);
             } else if (osm.isModified() && !osm.isDeleted()) {
@@ -70,6 +74,9 @@
         }
         sortDeleted();
         sortNew();
+        if (sortUpdated) {
+            sortUpdated();
+        }
     }
 
     /**
@@ -131,7 +138,38 @@
                 }
         );
     }
+
     /**
+     * Ensures that primitives are modified in the following order: Nodes, then Ways,
+     * then Relations. It's necessary for uploading undeleted objects.
+     *
+     */
+    protected void sortUpdated() {
+        Collections.sort(
+                toUpdate,
+                new Comparator<OsmPrimitive>() {
+                    public int compare(OsmPrimitive o1, OsmPrimitive o2) {
+                        if (o1 instanceof Node && o2 instanceof Node)
+                            return 0;
+                        else if (o1 instanceof Node)
+                            return -1;
+                        else if (o2 instanceof Node)
+                            return 1;
+
+                        if (o1 instanceof Way && o2 instanceof Way)
+                            return 0;
+                        else if (o1 instanceof Way && o2 instanceof Relation)
+                            return -1;
+                        else if (o2 instanceof Way && o1 instanceof Relation)
+                            return 1;
+
+                        return 0;
+                    }
+                }
+        );
+    }
+
+    /**
      * initializes the API data set with the modified primitives in <code>ds</code>
      *
      * @param ds the data set. Ignored, if null.
