Index: trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 3336)
@@ -139,5 +139,5 @@
     private boolean isDataSetEmpty(OsmDataLayer layer) {
         for (OsmPrimitive osm : layer.data.allNonDeletedPrimitives())
-            if (!osm.isDeleted() || !osm.isNew())
+            if (!osm.isDeleted() || !osm.isNewOrUndeleted())
                 return false;
         return true;
Index: trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java	(revision 3336)
@@ -78,7 +78,7 @@
         HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>();
         for (OsmPrimitive p: primitives) {
-            if (p.isNew()) {
+            if (p.isNewOrUndeleted()) {
                 ret.add(p);
-            } else if (p.isVisible() && p.isModified() && !p.isIncomplete()) {
+            } else if (p.isModified() && !p.isIncomplete()) {
                 ret.add(p);
             }
@@ -171,6 +171,5 @@
      * Computes the collection of primitives to upload, given a collection of candidate
      * primitives.
-     * Some of the candidates are excluded, i.e. if they aren't modified or if they
-     * aren't visible.
+     * Some of the candidates are excluded, i.e. if they aren't modified.
      * Other primitives are added. A typical case is a primitive which is new and and
      * which is referred by a modified relation. In order to upload the relation the
@@ -187,5 +186,5 @@
 
         public void visit(Node n) {
-            if (n.isNew() || ((n.isModified() || n.isDeleted()) && n.isVisible())) {
+            if (n.isNewOrUndeleted() || n.isModified() || n.isDeleted()) {
                 // upload new nodes as well as modified and deleted ones
                 hull.add(n);
@@ -194,5 +193,5 @@
 
         public void visit(Way w) {
-            if (w.isNew() || ((w.isModified() || w.isDeleted()) && w.isVisible())) {
+            if (w.isNewOrUndeleted() || w.isModified() || w.isDeleted()) {
                 // upload new ways as well as modified and deleted ones
                 hull.add(w);
@@ -206,5 +205,5 @@
 
         public void visit(Relation r) {
-            if (r.isNew() || ((r.isModified() || r.isDeleted()) && r.isVisible())) {
+            if (r.isNewOrUndeleted() || r.isModified() || r.isDeleted()) {
                 hull.add(r);
                 for (OsmPrimitive p : r.getMemberPrimitives()) {
@@ -213,5 +212,5 @@
                     // so wont check here for deleted primitives here
                     //
-                    if (p.isNew()) {
+                    if (p.isNewOrUndeleted()) {
                         p.visit(this);
                     }
@@ -295,5 +294,5 @@
             HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>();
             for (OsmPrimitive p: toUpload) {
-                if (p.isDeleted() && !p.isNew()) {
+                if (p.isDeleted() && !p.isNewOrUndeleted()) {
                     ret.add(p);
                 }
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 3336)
@@ -562,5 +562,5 @@
     private static class Modified extends Match {
         @Override public boolean match(OsmPrimitive osm) {
-            return osm.isModified() || osm.isNew();
+            return osm.isModified() || osm.isNewOrUndeleted();
         }
         @Override public String toString() {return "modified";}
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 3336)
@@ -445,5 +445,5 @@
                 if (osm.isIncomplete())
                     incomplete = true;
-                else if (osm instanceof Node && !osm.isNew()
+                else if (osm instanceof Node && !osm.isNewOrUndeleted()
                 && !a.contains(((Node) osm).getCoor()))
                     outside = true;
Index: trunk/src/org/openstreetmap/josm/data/APIDataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/APIDataSet.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/data/APIDataSet.java	(revision 3336)
@@ -61,9 +61,9 @@
                 continue;
             }
-            if (osm.isNew() && !osm.isDeleted()) {
+            if (osm.isNewOrUndeleted() && !osm.isDeleted()) {
                 toAdd.add(osm);
             } else if (osm.isModified() && !osm.isDeleted()) {
                 toUpdate.add(osm);
-            } else if (osm.isDeleted() && !osm.isNew() && osm.isModified()) {
+            } else if (osm.isDeleted() && !osm.isNew() && osm.isModified() && osm.isVisible()) {
                 toDelete.add(osm);
             }
@@ -198,9 +198,9 @@
         toDelete.clear();
         for (OsmPrimitive osm: primitives) {
-            if (osm.isNew() && !osm.isDeleted()) {
+            if (osm.isNewOrUndeleted() && !osm.isDeleted()) {
                 toAdd.addLast(osm);
             } else if (osm.isModified() && !osm.isDeleted()) {
                 toUpdate.addLast(osm);
-            } else if (osm.isDeleted() && !osm.isNew() && osm.isModified()) {
+            } else if (osm.isDeleted() && !osm.isNew() && osm.isModified() && osm.isVisible()) {
                 toDelete.addFirst(osm);
             }
@@ -312,5 +312,5 @@
             boolean refersToNewRelation = false;
             for (RelationMember m : relation.getMembers()) {
-                if (m.isRelation() && m.getMember().isNew()) {
+                if (m.isRelation() && m.getMember().isNewOrUndeleted()) {
                     refersToNewRelation = true;
                     break;
@@ -350,10 +350,10 @@
             this.relations = new HashSet<Relation>();
             for(Relation relation: relations) {
-                if (!relation.isNew() ) {
+                if (!relation.isNewOrUndeleted() ) {
                     continue;
                 }
                 this.relations.add(relation);
                 for (RelationMember m: relation.getMembers()) {
-                    if (m.isRelation() && m.getMember().isNew()) {
+                    if (m.isRelation() && m.getMember().isNewOrUndeleted()) {
                         addDependency(relation, (Relation)m.getMember());
                     }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java	(revision 3336)
@@ -189,12 +189,8 @@
             Node targetNode = (Node)getMergeTarget(sourceNode);
             if (targetNode != null) {
-                if (targetNode.isVisible()) {
-                    newNodes.add(targetNode);
-                    if (targetNode.isDeleted() && !conflicts.hasConflictForMy(targetNode)) {
-                        conflicts.add(new Conflict<OsmPrimitive>(targetNode, sourceNode, true));
-                        targetNode.setDeleted(false);
-                    }
-                } else {
-                    target.setModified(true);
+                newNodes.add(targetNode);
+                if (targetNode.isDeleted() && !conflicts.hasConflictForMy(targetNode)) {
+                    conflicts.add(new Conflict<OsmPrimitive>(targetNode, sourceNode, true));
+                    targetNode.setDeleted(false);
                 }
             } else
@@ -220,13 +216,9 @@
             if (targetMember == null)
                 throw new IllegalStateException(tr("Missing merge target of type {0} with id {1}", sourceMember.getType(), sourceMember.getUniqueId()));
-            if (targetMember.isVisible()) {
-                RelationMember newMember = new RelationMember(sourceMember.getRole(), targetMember);
-                newMembers.add(newMember);
-                if (targetMember.isDeleted() && !conflicts.hasConflictForMy(targetMember)) {
-                    conflicts.add(new Conflict<OsmPrimitive>(targetMember, sourceMember.getMember(), true));
-                    targetMember.setDeleted(false);
-                }
-            } else {
-                target.setModified(true);
+            RelationMember newMember = new RelationMember(sourceMember.getRole(), targetMember);
+            newMembers.add(newMember);
+            if (targetMember.isDeleted() && !conflicts.hasConflictForMy(targetMember)) {
+                conflicts.add(new Conflict<OsmPrimitive>(targetMember, sourceMember.getMember(), true));
+                targetMember.setDeleted(false);
             }
         }
@@ -252,13 +244,7 @@
             // target.version > source.version => keep target version
             return true;
-        if (! target.isVisible() && source.isVisible()) {
+        if (! target.isVisible() && source.isVisible() && target.getVersion() == source.getVersion()) {
             // should not happen
-            // FIXME: this message does not make sense, source version can not be lower than
-            //        target version at this point
-            logger.warning(tr("Target object with id {0} and version {1} is visible although "
-                    + "source object with lower version {2} is not visible. "
-                    + "Cannot deal with this inconsistency. Keeping target object. ",
-                    Long.toString(target.getId()),Long.toString(target.getVersion()), Long.toString(source.getVersion())
-            ));
+            conflicts.add(target,source);
         } else if (target.isVisible() && ! source.isVisible()) {
             // this is always a conflict because the user has to decide whether
Index: trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java	(revision 3336)
@@ -127,5 +127,5 @@
     public void checkZeroNodesWays() {
         for (Way way:dataSet.getWays()) {
-            if (way.isUsable() && way.isVisible() && way.getNodesCount() == 0) {
+            if (way.isUsable() && way.getNodesCount() == 0) {
                 printError("WARN - ZERO NODES", "Way %s has zero nodes", way);
             } else if (way.isUsable() && way.getNodesCount() == 1) {
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3336)
@@ -392,4 +392,12 @@
 
     /**
+     * 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).
@@ -427,5 +435,5 @@
     public static Predicate<OsmPrimitive> nonDeletedPredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && !primitive.isDeleted();
+            return !primitive.isDeleted();
         }
     };
@@ -433,5 +441,5 @@
     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();
         }
     };
@@ -439,5 +447,5 @@
     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);
         }
     };
@@ -445,5 +453,5 @@
     public static Predicate<OsmPrimitive> modifiedPredicate = new Predicate<OsmPrimitive>() {
         public boolean evaluate(OsmPrimitive primitive) {
-            return primitive.isVisible() && primitive.isModified();
+            return primitive.isModified();
         }
     };
@@ -537,4 +545,14 @@
     public boolean isNew() {
         return id <= 0;
+    }
+
+    /**
+     *
+     * @return True if primitive is new or undeleted
+     * @see #isNew()
+     * @see #isUndeleted()
+     */
+    public boolean isNewOrUndeleted() {
+        return (id <= 0) || ((flags & (FLAG_VISIBLE + FLAG_DELETED)) == 0);
     }
 
@@ -722,5 +740,5 @@
             flags &= ~FLAG_DELETED;
         }
-        setModified(deleted);
+        setModified(deleted ^ !isVisible());
         if (dataSet != null) {
             if (deleted) {
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 3336)
@@ -420,5 +420,5 @@
             final StringBuilder text = new StringBuilder();
             String name = osm.getDisplayName(DefaultNameFormatter.getInstance());
-            if (osm.isNew() || osm.isModified()) {
+            if (osm.isNewOrUndeleted() || osm.isModified()) {
                 name = "<i><b>"+ name + "*</b></i>";
             }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 3336)
@@ -48,5 +48,4 @@
 
     private ValidationListener validationListener = new ValidationListener() {
-        @Override
         public boolean validatePreferences() {
             if (sources.hasActiveStylesChanged()) {
Index: trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 3336)
@@ -125,4 +125,5 @@
                 if (!p.isDeleted()) {
                     p.setOsmId(entry.new_id, entry.new_version);
+                    p.setVisible(true);
                 }
                 if (cs != null && !cs.isNew()) {
Index: trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 3336)
@@ -275,4 +275,5 @@
             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: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 3335)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 3336)
@@ -98,5 +98,5 @@
 
     private boolean shouldWrite(OsmPrimitive osm) {
-        return !osm.isNew() || !osm.isDeleted();
+        return !osm.isNewOrUndeleted() || !osm.isDeleted();
     }
 
