Index: /applications/editors/josm/plugins/reverter/src/reverter/ChangesetIdQuery.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/ChangesetIdQuery.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/ChangesetIdQuery.java	(revision 21634)
@@ -19,6 +19,5 @@
     private JFormattedTextField tcid = new JFormattedTextField(NumberFormat.getInstance());
 
-    public int ChangesetId()
-    {
+    public int ChangesetId() {
         try {
           return NumberFormat.getInstance().parse(tcid.getText()).intValue();
Index: /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java	(revision 21634)
@@ -1,15 +1,16 @@
 package reverter;
 
-import java.util.HashMap;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.ConflictAddCommand;
 import org.openstreetmap.josm.command.DeleteCommand;
+import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.ChangesetDataSet;
@@ -28,5 +29,5 @@
 import org.openstreetmap.josm.data.osm.history.HistoryWay;
 import org.openstreetmap.josm.data.osm.history.RelationMember;
-import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
@@ -34,63 +35,43 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 
+/**
+ * Fetches and stores data for reverting of specific changeset.
+ * @author Upliner
+ *
+ */
 public class ChangesetReverter {
     public final int changesetId;
     public final Changeset changeset;
 
-    private final DataSet ds;
-    private final ChangesetDataSet osmchange;
+    private final OsmDataLayer layer; // data layer associated with reverter 
+    private final DataSet ds; // DataSet associated with reverter 
+    private final ChangesetDataSet cds; // Current changeset data 
+    private DataSet nds; // Dataset that contains new objects downloaded by reverter
 
     private final HashSet<PrimitiveId> missing = new HashSet<PrimitiveId>();
-    private LinkedList<Command> cmds;
-
-    static class MyCsDataset {
-        public HashMap<PrimitiveId,Integer> created = new HashMap<PrimitiveId,Integer>();
-        public HashMap<PrimitiveId,Integer> updated = new HashMap<PrimitiveId,Integer>();
-        public HashMap<PrimitiveId,Integer> deleted = new HashMap<PrimitiveId,Integer>();
-
-        private static void put(HashMap<PrimitiveId,Integer> map,PrimitiveId id,int version) {
-            if (map.containsKey(id)) {
-                if (version < map.get(id))
-                    map.put(id, version);
-            } else {
-                map.put(id, version);
-            }
-        }
-        
-        private void addEntry(ChangesetDataSetEntry entry) {
-            HistoryOsmPrimitive t = entry.getPrimitive();
-            if (entry.getModificationType() == ChangesetModificationType.CREATED) {
-                put(created, new SimplePrimitiveId(t.getId(),t.getType()), (int)t.getVersion());
-            } else if (entry.getModificationType() == ChangesetModificationType.UPDATED) {
-                put(updated, new SimplePrimitiveId(t.getId(),t.getType()), (int)t.getVersion());
-            } else if (entry.getModificationType() == ChangesetModificationType.DELETED) {
-                put(deleted, new SimplePrimitiveId(t.getId(),t.getType()), (int)t.getVersion());
-            } else throw new AssertionError();
-        }
-        
-        public MyCsDataset(ChangesetDataSet ds) {
-            Iterator<ChangesetDataSetEntry> iterator = ds.iterator();
-            while (iterator.hasNext()) {
-                addEntry(iterator.next());
-            }
-        }
-    }
-    
-    private void AddIfMissing(PrimitiveId id) {
-        if (ds.getPrimitiveById(id) == null) {
+
+    private final HashSet<HistoryOsmPrimitive> created = new HashSet<HistoryOsmPrimitive>();
+    private final HashSet<HistoryOsmPrimitive> updated = new HashSet<HistoryOsmPrimitive>();
+    private final HashSet<HistoryOsmPrimitive> deleted = new HashSet<HistoryOsmPrimitive>();
+
+    //// Handling missing objects
+    ////////////////////////////////////////
+    private void addIfMissing(PrimitiveId id) {
+        OsmPrimitive p = ds.getPrimitiveById(id); 
+        if (p == null || p.isIncomplete()) {
             missing.add(id);
         }
     }
-    private void AddMissingIds(Set<HistoryOsmPrimitive> primitives) {
+    private void addMissingHistoryIds(Iterable<HistoryOsmPrimitive> primitives) {
         for (HistoryOsmPrimitive p : primitives) {
-            AddIfMissing(new SimplePrimitiveId(p.getId(),p.getType()));
+            addIfMissing(p.getPrimitiveId());
             if (p.getType() == OsmPrimitiveType.WAY) {
                 for (long nd : ((HistoryWay)p).getNodes()) {
-                    AddIfMissing(new SimplePrimitiveId(nd,OsmPrimitiveType.NODE));
+                    addIfMissing(new SimplePrimitiveId(nd,OsmPrimitiveType.NODE));
                 }
             }
             if (p.getType() == OsmPrimitiveType.RELATION) {
                 for (RelationMember member : ((HistoryRelation)p).getMembers()) {
-                    AddIfMissing(new SimplePrimitiveId(member.getPrimitiveId(),
+                    addIfMissing(new SimplePrimitiveId(member.getPrimitiveId(),
                             member.getPrimitiveType()));
                 }
@@ -98,70 +79,85 @@
         }
     }
-    private void CheckMissing() {
+
+    private void addMissingIds(Iterable<OsmPrimitive> primitives) {
+        for (OsmPrimitive p : primitives) {
+            addIfMissing(p);
+            if (p.getType() == OsmPrimitiveType.WAY) {
+                for (Node nd : ((Way)p).getNodes()) {
+                    addIfMissing(nd);
+                }
+            }
+            if (p.getType() == OsmPrimitiveType.RELATION) {
+                for (org.openstreetmap.josm.data.osm.RelationMember member
+                        : ((Relation)p).getMembers()) {
+                    addIfMissing(member.getMember());
+                }
+            }
+        }
+    }
+    
+    /**
+     * creates a reverter for specific changeset and fetches initial data
+     * @param changesetId
+     * @param monitor
+     * @throws OsmTransferException
+     */
+    public ChangesetReverter(int changesetId, ProgressMonitor monitor) throws OsmTransferException {
+        this.changesetId = changesetId;
+        this.layer = Main.main.getEditLayer();
+        this.ds = layer.data;
+
+        OsmServerChangesetReader csr = new OsmServerChangesetReader();
+        monitor.beginTask("", 2);
+        try {
+            changeset = csr.readChangeset(changesetId, monitor.createSubTaskMonitor(1, false));
+            cds = csr.downloadChangeset(changesetId, monitor.createSubTaskMonitor(1, false));
+        } finally {
+            monitor.finishTask();
+        }
+        
+        // Build our own lists of created/updated/modified objects for better performance
+        Iterator<ChangesetDataSetEntry> iterator = cds.iterator();
+        while (iterator.hasNext()) {
+            ChangesetDataSetEntry entry = iterator.next();
+            if (entry.getModificationType() == ChangesetModificationType.CREATED) {
+                created.add(entry.getPrimitive());
+            } else if (entry.getModificationType() == ChangesetModificationType.UPDATED) {
+                updated.add(entry.getPrimitive());
+            } else if (entry.getModificationType() == ChangesetModificationType.DELETED) {
+                deleted.add(entry.getPrimitive());
+            } else throw new AssertionError();
+        }
+        
         /* Create list of objects that created or modified my the changeset but
          * doesn't present in the current dataset. 
          */
         missing.clear();
-        AddMissingIds(osmchange.
-                getPrimitivesByModificationType(ChangesetModificationType.CREATED));
-        AddMissingIds(osmchange.
-                getPrimitivesByModificationType(ChangesetModificationType.UPDATED));
-    }
-    
-    public ChangesetReverter(int changesetId) throws OsmTransferException {
-        this.changesetId = changesetId;
-        this.ds = Main.main.getCurrentDataSet();
-
-        OsmServerChangesetReader csr = new OsmServerChangesetReader();
-        changeset = csr.readChangeset(changesetId, NullProgressMonitor.INSTANCE);
-        osmchange = csr.downloadChangeset(changesetId, NullProgressMonitor.INSTANCE);
-        CheckMissing();
-    }
-
-    public void RevertChangeset(ProgressMonitor progressMonitor) throws OsmTransferException {
-        final MyCsDataset cds = new MyCsDataset(osmchange);
+        addMissingHistoryIds(created);
+        addMissingHistoryIds(updated);
+    }
+
+    /**
+     * fetch objects that was updated or deleted by changeset
+     * @param progressMonitor
+     * @throws OsmTransferException
+     */
+    public void downloadObjectsHistory(ProgressMonitor progressMonitor) throws OsmTransferException {
         final OsmServerMultiObjectReader rdr = new OsmServerMultiObjectReader();
         
-        progressMonitor.beginTask("",cds.updated.size()+cds.deleted.size()+2);
-        progressMonitor.worked(1);
+        progressMonitor.beginTask("Downloading objects history",updated.size()+deleted.size()+1);
         try {
-            // Fetch objects that was updated or deleted by changeset
-            for (Map.Entry<PrimitiveId,Integer> entry : cds.updated.entrySet()) {
-                rdr.ReadObject(entry.getKey().getUniqueId(), entry.getValue()-1, entry.getKey().getType(),
+            for (HistoryOsmPrimitive entry : updated) {
+                rdr.ReadObject(entry.getPrimitiveId(), (int)entry.getVersion()-1,
                         progressMonitor.createSubTaskMonitor(1, true));
                 if (progressMonitor.isCancelled()) return;
             }
-            for (Map.Entry<PrimitiveId,Integer> entry : cds.deleted.entrySet()) {
-                rdr.ReadObject(entry.getKey().getUniqueId(), entry.getValue()-1, entry.getKey().getType(),
+            for (HistoryOsmPrimitive entry : deleted) {
+                rdr.ReadObject(entry.getPrimitiveId(), (int)entry.getVersion()-1,
                         progressMonitor.createSubTaskMonitor(1, true));
                 if (progressMonitor.isCancelled()) return;
             }
-            final DataSet nds = rdr.parseOsm(progressMonitor.createSubTaskMonitor(1, true));
-            
-            // Mark objects that have visible=false to be deleted
-            LinkedList<OsmPrimitive> toDelete = new LinkedList<OsmPrimitive>();
-            for (OsmPrimitive p : nds.allPrimitives()) {
-                if (!p.isVisible()) {
-                    OsmPrimitive dp = ds.getPrimitiveById(p);
-                    if (dp != null) toDelete.add(dp);
-                }
-            }
-            
-            // Create commands to restore/update all affected objects 
-            this.cmds = new DataSetToCmd(nds,ds).getCommandList();
-            
-            // Mark all created objects to be deleted
-            for (PrimitiveId id : cds.created.keySet()) {
-                OsmPrimitive p = ds.getPrimitiveById(id);
-                if (p != null) toDelete.add(p);
-            }
-            // Create a Command to delete all marked objects
-            List<? extends OsmPrimitive> list;
-            list = OsmPrimitive.getFilteredList(toDelete, Relation.class);
-            if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
-            list = OsmPrimitive.getFilteredList(toDelete, Way.class);
-            if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
-            list = OsmPrimitive.getFilteredList(toDelete, Node.class);
-            if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
+            nds = rdr.parseOsm(progressMonitor.createSubTaskMonitor(1, true));
+            addMissingIds(nds.allPrimitives());
         } finally {
             progressMonitor.finishTask();
@@ -169,5 +165,5 @@
     }
     
-    public void DownloadMissingPrimitives(ProgressMonitor monitor) throws OsmTransferException {
+    public void downloadMissingPrimitives(ProgressMonitor monitor) throws OsmTransferException {
         MultiFetchServerObjectReader rdr = new MultiFetchServerObjectReader();
         for (PrimitiveId id : missing) {
@@ -185,35 +181,66 @@
             }
         }
-        DataSet from = rdr.parseOsm(monitor);
-        for (Node n : from.getNodes()) {
-            if (ds.getPrimitiveById(n) == null) {
-                ds.addPrimitive(new Node(n));
-            }
-        }
-        for (Way w : from.getWays()) {
-            if (ds.getPrimitiveById(w) == null) {
-                Way nw = new Way(w.getId());
-                ds.addPrimitive(nw);
-                nw.load(w.save());
-            }
-        }
-        final LinkedList<Relation> rels = new LinkedList<Relation>();
-        for (Relation r : from.getRelations()) {
-            if (ds.getPrimitiveById(r) == null) {
-                ds.addPrimitive(new Relation(r.getId()));
-                rels.add(r);
-            }
-        }
-        for (Relation r : rels) {
-            ((Relation)ds.getPrimitiveById(r)).load(r.save());
-        }
+        layer.mergeFrom(rdr.parseOsm(monitor));
         missing.clear();
     }
     
+    /**
+     * Builds a list of commands that will revert the changeset
+     * 
+     */
     public List<Command> getCommands() {
+        if (this.nds == null) return null;
+        LinkedList<OsmPrimitive> toDelete = new LinkedList<OsmPrimitive>();
+        LinkedList<Command> cmds = new LinkedList<Command>();
+        for (OsmPrimitive p : nds.allPrimitives()) {
+            if (p.isIncomplete()) continue;
+            OsmPrimitive dp = ds.getPrimitiveById(p);
+            if (dp == null)
+                throw new IllegalStateException(tr("Missing merge target for {0} with id {1}",
+                        p.getType(), p.getUniqueId()));
+            // Mark objects that have visible=false to be deleted
+            if (!p.isVisible()) {
+                toDelete.add(dp);
+            }
+            // Check object version
+            if (p.getVersion() != dp.getVersion()
+                    && (p.isVisible() || dp.isVisible())) {
+                Conflict<? extends OsmPrimitive> c;
+                switch (dp.getType()) {
+                case NODE:
+                    c = new Conflict<Node>((Node)p,new Node((Node)dp),!p.isVisible());
+                    break;
+                case WAY:
+                    c = new Conflict<Way>((Way)p,new Way((Way)dp),!p.isVisible());
+                    break;
+                case RELATION:
+                    c = new Conflict<Relation>((Relation)p,new Relation((Relation)dp),!p.isVisible());
+                    break;
+                default: throw new AssertionError();
+                }
+                cmds.add(new ConflictAddCommand(layer,c));
+            }
+        }
+        
+        // Create commands to restore/update all affected objects 
+        cmds.addAll(new DataSetToCmd(nds,ds).getCommandList());
+        
+        // Mark all created objects to be deleted
+        for (HistoryOsmPrimitive id : created) {
+            OsmPrimitive p = ds.getPrimitiveById(id.getPrimitiveId());
+            if (p != null) toDelete.add(p);
+        }
+        // Create a Command to delete all marked objects
+        List<? extends OsmPrimitive> list;
+        list = OsmPrimitive.getFilteredList(toDelete, Relation.class);
+        if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
+        list = OsmPrimitive.getFilteredList(toDelete, Way.class);
+        if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
+        list = OsmPrimitive.getFilteredList(toDelete, Node.class);
+        if (!list.isEmpty()) cmds.add(new DeleteCommand(list));
         return cmds;
     }
-    public Set<PrimitiveId> getMissingObjects() {
-        return missing;
+    public boolean haveMissingObjects() {
+        return !missing.isEmpty();
     }
 }
Index: /applications/editors/josm/plugins/reverter/src/reverter/DataSetToCmd.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/DataSetToCmd.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/DataSetToCmd.java	(revision 21634)
@@ -9,5 +9,4 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.ChangeNodesCommand;
@@ -15,4 +14,9 @@
 import org.openstreetmap.josm.data.osm.*;
 
+/**
+ * Modified {@see org.openstreetmap.josm.data.osm.DataSetMerger} that
+ * produces list of commands instead of directly merging layers.
+ *
+ */
 final class DataSetToCmd {
 
@@ -21,10 +25,4 @@
     private final DataSet targetDataSet;
 
-    /**
-     * A map of all primitives that got replaced with other primitives.
-     * Key is the PrimitiveId in their dataset, the value is the PrimitiveId in my dataset
-     */
-    private final Map<OsmPrimitive, OsmPrimitive> mergedMap = new HashMap<OsmPrimitive, OsmPrimitive>();
-    
     private final LinkedList<Command> cmds = new LinkedList<Command>();
 
@@ -47,35 +45,26 @@
         if (source.isIncomplete()) return;
         if (!source.isVisible()) return;
-        OsmPrimitive target = targetDataSet.getPrimitiveById(source.getId(), source.getType());
-        if (target == null) {
-            switch(source.getType()) {
-            case NODE: target = new Node(source.getId()); break;
-            case WAY: target = new Way(source.getId()); break;
-            case RELATION: target = new Relation(source.getId()); break;
-            default: throw new AssertionError();
-            }
-            target.mergeFrom(source);
-            target.setOsmId(target.getId(), (int)source.getVersion()+1);
-            target.setModified(true);
-            cmds.add(new AddCommand(target));
-        } else {
-            OsmPrimitive newTarget = null;
-            switch(target.getType()) {
-            case NODE: newTarget = new Node((Node)target); break;
-            case WAY: newTarget = new Way((Way)target); break;
-            case RELATION: newTarget = new Relation((Relation)target); break;
-            default: throw new AssertionError();
-            }
-            newTarget.mergeFrom(source);
-            newTarget.setOsmId(target.getId(), (int)source.getVersion()+1);
-            newTarget.setDeleted(false);
-            cmds.add(new ChangeCommand(target,newTarget));
+        OsmPrimitive target = getMergeTarget(source);
+        if (target.getVersion() == 0)
+            throw new IllegalStateException(tr("Target of type {0} with id {1} have invalid version",
+                    target.getType(), target.getUniqueId()));
+        OsmPrimitive newTarget;
+        switch(target.getType()) {
+        case NODE: newTarget = new Node((Node)target); break;
+        case WAY: newTarget = new Way((Way)target); break;
+        case RELATION: newTarget = new Relation((Relation)target); break;
+        default: throw new AssertionError();
         }
-        mergedMap.put(source, target);
+        newTarget.mergeFrom(source);
+        newTarget.setOsmId(target.getId(), (int)target.getVersion());
+        newTarget.setDeleted(false);
+        cmds.add(new ChangeCommand(target,newTarget));
     }
 
     private OsmPrimitive getMergeTarget(OsmPrimitive mergeSource) {
-        OsmPrimitive p = mergedMap.get(mergeSource);
-        if (p == null) p = targetDataSet.getPrimitiveById(mergeSource.getId(), mergeSource.getType());
+        OsmPrimitive p = targetDataSet.getPrimitiveById(mergeSource.getId(), mergeSource.getType());
+        if (p == null)
+            throw new IllegalStateException(tr("Missing merge target of type {0} with id {1}",
+                    mergeSource.getType(), mergeSource.getUniqueId()));
         return p;
     }
@@ -106,13 +95,8 @@
         if (!source.isVisible()) return;
         Way target = (Way)getMergeTarget(source);
-        if (target == null)
-            throw new IllegalStateException(tr("Missing merge target for way with id {0}", source.getUniqueId()));
 
         List<Node> newNodes = new ArrayList<Node>(source.getNodesCount());
         for (Node sourceNode : source.getNodes()) {
             Node targetNode = (Node)getMergeTarget(sourceNode);
-            if (targetNode == null)
-                throw new IllegalStateException(tr("Missing merge target for node with id {0}", sourceNode.getUniqueId()));
-
             newNodes.add(targetNode);
         }
@@ -131,11 +115,7 @@
         if (!source.isVisible()) return;
         Relation target = (Relation) getMergeTarget(source);
-        if (target == null)
-            throw new IllegalStateException(tr("Missing merge target for relation with id {0}", source.getUniqueId()));
         LinkedList<RelationMember> newMembers = new LinkedList<RelationMember>();
         for (RelationMember sourceMember : source.getMembers()) {
             OsmPrimitive targetMember = getMergeTarget(sourceMember.getMember());
-            if (targetMember == null)
-                throw new IllegalStateException(tr("Missing merge target of type {0} with id {1}", sourceMember.getType(), sourceMember.getUniqueId()));
             newMembers.add(new RelationMember(sourceMember.getRole(), targetMember));
         }
@@ -144,6 +124,5 @@
         cmds.add(new ChangeCommand(target,newRelation));
     }
-    private void merge()
-    {
+    private void merge() {
         for (Node node: sourceDataSet.getNodes()) {
             mergePrimitive(node);
Index: /applications/editors/josm/plugins/reverter/src/reverter/MultiOsmReader.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/MultiOsmReader.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/MultiOsmReader.java	(revision 21634)
@@ -48,5 +48,5 @@
 
 /**
- * Parser for the Osm Api. Read from an input stream and construct a dataset out of it.
+ * Modified {@see org.openstreetmap.josm.io.OsmReader} that can handle multiple XML streams.
  *
  */
@@ -426,5 +426,5 @@
      * @throws IllegalDataException thrown if a data integrity problem is detected
      */
-    protected void processWaysAfterParsing() throws IllegalDataException{
+    protected void processWaysAfterParsing() throws IllegalDataException {
         for (Long externalWayId: ways.keySet()) {
             Way w = (Way)externalIdMap.get(new SimplePrimitiveId(externalWayId, OsmPrimitiveType.WAY));
@@ -556,6 +556,5 @@
         }
     }
-    public void ProcessData() throws IllegalDataException
-    {
+    public void ProcessData() throws IllegalDataException {
         processNodesAfterParsing();
         processWaysAfterParsing();
Index: /applications/editors/josm/plugins/reverter/src/reverter/ObjectsHistoryAction.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/ObjectsHistoryAction.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/ObjectsHistoryAction.java	(revision 21634)
@@ -12,6 +12,5 @@
 public class ObjectsHistoryAction extends JosmAction {
 
-    public ObjectsHistoryAction()
-    {
+    public ObjectsHistoryAction() {
         super(tr("Objects history"),null,tr("History reverter"),
                 Shortcut.registerShortcut("tool:history",
Index: /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java	(revision 21634)
@@ -8,4 +8,5 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.OsmServerReader;
@@ -15,6 +16,8 @@
 public class OsmServerMultiObjectReader extends OsmServerReader {
     private MultiOsmReader rdr = new MultiOsmReader();
-    public void ReadObject(long id,int version,OsmPrimitiveType type,ProgressMonitor progressMonitor) throws OsmTransferException
-    {
+    public void ReadObject(PrimitiveId id, int version, ProgressMonitor progressMonitor) throws OsmTransferException {
+        ReadObject(id.getUniqueId(), version, id.getType(), progressMonitor);
+    }
+    public void ReadObject(long id,int version,OsmPrimitiveType type,ProgressMonitor progressMonitor) throws OsmTransferException {
         StringBuffer sb = new StringBuffer();
         sb.append(type.getAPIName());
@@ -53,10 +56,8 @@
         } catch (Exception e) {
             throw new OsmTransferException(e);
-        } finally
-        {
+        } finally {
             progressMonitor.finishTask();
             activeConnection = null;
         }
     }
-
 }
Index: /applications/editors/josm/plugins/reverter/src/reverter/RevertChangesetAction.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/RevertChangesetAction.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/RevertChangesetAction.java	(revision 21634)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -22,6 +23,5 @@
 public class RevertChangesetAction extends JosmAction {
 
-    public RevertChangesetAction()
-    {
+    public RevertChangesetAction() {
         super(tr("Revert changeset"),null,tr("Revert changeset"),
                 Shortcut.registerShortcut("tool:revert",
@@ -37,5 +37,5 @@
     }
 
-    public void actionPerformed(ActionEvent arg0) {
+    public void actionPerformed(ActionEvent arg0)  {
         if (getCurrentDataSet() == null)
             return;
@@ -46,26 +46,34 @@
         if (changesetId == 0) return;
         Main.worker.submit(new PleaseWaitRunnable(tr("Reverting...")) {
+            private ChangesetReverter rev;
+            private boolean downloadConfirmed = false;
+            
+            private boolean checkMissing() throws OsmTransferException {
+                if (!rev.haveMissingObjects()) return true;
+                if (!downloadConfirmed) {
+                    downloadConfirmed = JOptionPane.showConfirmDialog(Main.parent,
+                            tr("This changeset have objects that doesn't present in current dataset.\n" + 
+                                    "It is needed to download them before reverting. Do you want to continue?"),
+                            tr("Confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
+                    if (!downloadConfirmed) return false;
+                }
+                final PleaseWaitProgressMonitor monitor = 
+                    new PleaseWaitProgressMonitor(tr("Fetching missing primitives"));
+                try {
+                    rev.downloadMissingPrimitives(monitor);
+                } finally {
+                    monitor.close();
+                }
+                return true;
+            }
+            
             @Override
             protected void realRun() throws OsmTransferException {
-                ChangesetReverter rev = new ChangesetReverter(changesetId);
-                if (!rev.getMissingObjects().isEmpty())
-                {
-                    if (JOptionPane.showConfirmDialog(Main.parent,
-                            tr("This changeset have objects outside the downloaded area.\n" + 
-                                    "It is needed to download them before reverting. Do you want to continue?"),
-                            tr("Confirm"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
-                        final PleaseWaitProgressMonitor monitor = 
-                            new PleaseWaitProgressMonitor(tr("Fetching missing primitives"));
-                        try {
-                            rev.DownloadMissingPrimitives(monitor);
-                        } finally {
-                            monitor.close();
-                        }
-                    } else {
-                        return;
-                    }
-                }
-                rev.RevertChangeset(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, true));
+                rev = new ChangesetReverter(changesetId, NullProgressMonitor.INSTANCE);
+                progressMonitor.indeterminateSubTask("Downloading changeset");
+                if (!checkMissing()) return;
+                rev.downloadObjectsHistory(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
                 if (progressMonitor.isCancelled()) return;
+                if (!checkMissing()) return;
                 List<Command> cmds = rev.getCommands();
                 Command cmd = new SequenceCommand(tr("Revert changeset #{0}",changesetId),cmds);
@@ -82,4 +90,3 @@
         });
     }
-
 }
Index: /applications/editors/josm/plugins/reverter/src/reverter/ReverterPlugin.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/ReverterPlugin.java	(revision 21633)
+++ /applications/editors/josm/plugins/reverter/src/reverter/ReverterPlugin.java	(revision 21634)
@@ -15,6 +15,5 @@
 
 public class ReverterPlugin extends Plugin {
-    public ReverterPlugin(PluginInformation info)
-    {
+    public ReverterPlugin(PluginInformation info) {
         super(info);
         JMenu historyMenu = Main.main.menu.addMenu(marktr("History"), KeyEvent.VK_R, Main.main.menu.defaultMenuPos,ht("/Plugin/Reverter"));
