Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 1750)
@@ -150,7 +150,7 @@
         panel.setVisible(false);
         panel.removeAll();
-        if (map != null)
+        if (map != null) {
             map.fillPanel(panel);
-        else {
+        } else {
             old.destroy();
             panel.add(gettingStarted, BorderLayout.CENTER);
@@ -169,8 +169,10 @@
         if (map != null) {
             map.mapView.removeLayer(layer);
-            if (layer instanceof OsmDataLayer)
+            if (layer instanceof OsmDataLayer) {
                 ds = new DataSet();
-            if (map.mapView.getAllLayers().isEmpty())
+            }
+            if (map.mapView.getAllLayers().isEmpty()) {
                 setMapFrame(null);
+            }
         }
     }
@@ -182,10 +184,12 @@
     public Main(SplashScreen splash) {
         main = this;
-//        platform = determinePlatformHook();
+        //        platform = determinePlatformHook();
         platform.startupHook();
         contentPane.add(panel, BorderLayout.CENTER);
         panel.add(gettingStarted, BorderLayout.CENTER);
 
-        if(splash != null) splash.setStatus(tr("Creating main GUI"));
+        if(splash != null) {
+            splash.setStatus(tr("Creating main GUI"));
+        }
         menu = new MainMenu();
 
@@ -197,5 +201,5 @@
         contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
         .put(Shortcut.registerShortcut("system:help", tr("Help"),
-        KeyEvent.VK_F1, Shortcut.GROUP_DIRECT).getKeyStroke(), "Help");
+                KeyEvent.VK_F1, Shortcut.GROUP_DIRECT).getKeyStroke(), "Help");
         contentPane.getActionMap().put("Help", menu.help);
 
@@ -223,10 +227,27 @@
     }
     /**
-     * @return The edit osm layer. If none exists, it will be created.
-     */
-    public final OsmDataLayer editLayer() {
-        if (map == null || map.mapView.editLayer == null)
+     * Replies the current edit layer. Creates one if no {@see OsmDataLayer}
+     * exists. Replies null, if the currently active layer isn't an instance
+     * of {@see OsmDataLayer}.
+     * 
+     * @return the current edit layer
+     */
+    public final OsmDataLayer createOrGetEditLayer() {
+        if (map == null || map.mapView.getEditLayer() == null) {
             menu.newAction.actionPerformed(null);
-        return map.mapView.editLayer;
+        }
+        return map.mapView.getEditLayer();
+    }
+
+    /**
+     * Replies true if this map view has an edit layer
+     * 
+     * @return true if this map view has an edit layer
+     */
+    public boolean hasEditLayer() {
+        if (map == null) return false;
+        if (map.mapView == null) return false;
+        if (map.mapView.getEditLayer() == null) return false;
+        return true;
     }
 
@@ -263,7 +284,8 @@
         if(!Main.proj.equals(oldProj))
         {
-            if(b != null)
+            if(b != null) {
                 map.mapView.zoomTo(b);
-            /* TODO - remove layers with fixed projection */
+                /* TODO - remove layers with fixed projection */
+            }
         }
     }
@@ -279,6 +301,7 @@
             try {
                 String laf = Main.pref.get("laf");
-                if(laf != null && laf.length() > 0)
+                if(laf != null && laf.length() > 0) {
                     UIManager.setLookAndFeel(laf);
+                }
             }
             catch (final javax.swing.UnsupportedLookAndFeelException e) {
@@ -310,8 +333,10 @@
                     x = Integer.valueOf(m.group(5));
                     y = Integer.valueOf(m.group(7));
-                    if (m.group(4).equals("-"))
+                    if (m.group(4).equals("-")) {
                         x = screenDimension.width - x - w;
-                    if (m.group(6).equals("-"))
+                    }
+                    if (m.group(6).equals("-")) {
                         y = screenDimension.height - y - h;
+                    }
                 }
                 bounds = new Rectangle(x,y,w,h);
@@ -324,9 +349,10 @@
             }
         }
-        if (bounds == null)
+        if (bounds == null) {
             bounds = !args.containsKey("no-maximize") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
-
-            // preinitialize a wait dialog for all early downloads (e.g. via command line)
-            pleaseWaitDlg = new PleaseWaitDialog(null);
+        }
+
+        // preinitialize a wait dialog for all early downloads (e.g. via command line)
+        pleaseWaitDlg = new PleaseWaitDialog(null);
     }
 
@@ -335,13 +361,19 @@
         pleaseWaitDlg = new PleaseWaitDialog(parent);
 
-        if (args.containsKey("download"))
-            for (String s : args.get("download"))
+        if (args.containsKey("download")) {
+            for (String s : args.get("download")) {
                 downloadFromParamString(false, s);
-        if (args.containsKey("downloadgps"))
-            for (String s : args.get("downloadgps"))
+            }
+        }
+        if (args.containsKey("downloadgps")) {
+            for (String s : args.get("downloadgps")) {
                 downloadFromParamString(true, s);
-        if (args.containsKey("selection"))
-            for (String s : args.get("selection"))
+            }
+        }
+        if (args.containsKey("selection")) {
+            for (String s : args.get("selection")) {
                 SearchAction.search(s, SearchAction.SearchMode.add, false, false);
+            }
+        }
     }
 
@@ -360,24 +392,25 @@
             if (modified) {
                 final String msg = uploadedModified ? "\n"
-                +tr("Hint: Some changes came from uploading new data to the server.") : "";
-                int result = new ExtendedDialog(parent, tr("Unsaved Changes"),
-                new javax.swing.JLabel(tr("There are unsaved changes. Discard the changes and continue?")+msg),
-                new String[] {tr("Save and Exit"), tr("Discard and Exit"), tr("Cancel")},
-                new String[] {"save.png", "exit.png", "cancel.png"}).getValue();
-
-                // Save before exiting
-                if(result == 1) {
-                    Boolean savefailed = false;
-                    for (final Layer l : map.mapView.getAllLayers()) {
-                        if (l instanceof OsmDataLayer && ((OsmDataLayer)l).isModified()) {
-                            SaveAction save = new SaveAction(l);
-                            if(!save.doSave())
-                                savefailed = true;
+                        +tr("Hint: Some changes came from uploading new data to the server.") : "";
+                        int result = new ExtendedDialog(parent, tr("Unsaved Changes"),
+                                new javax.swing.JLabel(tr("There are unsaved changes. Discard the changes and continue?")+msg),
+                                new String[] {tr("Save and Exit"), tr("Discard and Exit"), tr("Cancel")},
+                                new String[] {"save.png", "exit.png", "cancel.png"}).getValue();
+
+                        // Save before exiting
+                        if(result == 1) {
+                            Boolean savefailed = false;
+                            for (final Layer l : map.mapView.getAllLayers()) {
+                                if (l instanceof OsmDataLayer && ((OsmDataLayer)l).isModified()) {
+                                    SaveAction save = new SaveAction(l);
+                                    if(!save.doSave()) {
+                                        savefailed = true;
+                                    }
+                                }
+                            }
+                            return savefailed;
                         }
-                    }
-                    return savefailed;
-                }
-                else if(result != 2) // Cancel exiting unless the 2nd button was clicked
-                    return true;
+                        else if(result != 2) // Cancel exiting unless the 2nd button was clicked
+                            return true;
             }
         }
@@ -388,7 +421,7 @@
         if (s.startsWith("http:")) {
             final Bounds b = OsmUrlToBounds.parse(s);
-            if (b == null)
+            if (b == null) {
                 JOptionPane.showMessageDialog(Main.parent, tr("Ignoring malformed URL: \"{0}\"", s));
-            else {
+            } else {
                 //DownloadTask osmTask = main.menu.download.downloadTasks.get(0);
                 DownloadTask osmTask = new DownloadOsmTask();
@@ -428,6 +461,6 @@
             platform = new PlatformHookWindows();
         } else if (os.equals("Linux") || os.equals("Solaris") ||
-            os.equals("SunOS") || os.equals("AIX") ||
-            os.equals("FreeBSD") || os.equals("NetBSD") || os.equals("OpenBSD")) {
+                os.equals("SunOS") || os.equals("AIX") ||
+                os.equals("FreeBSD") || os.equals("NetBSD") || os.equals("OpenBSD")) {
             platform = new PlatformHookUnixoid();
         } else if (os.toLowerCase().startsWith("mac os x")) {
@@ -468,12 +501,16 @@
                 int x = (int)bounds.getX();
                 int y = (int)bounds.getY();
-                if (width > screenDimension.width)
+                if (width > screenDimension.width) {
                     width = screenDimension.width;
-                if (height > screenDimension.height)
+                }
+                if (height > screenDimension.height) {
                     width = screenDimension.height;
-                if (x < 0)
+                }
+                if (x < 0) {
                     x = 0;
-                if (y < 0)
+                }
+                if (y < 0) {
                     y = 0;
+                }
                 newGeometry = width + "x" + height + "+" + x + "+" + y;
             }
Index: trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 1750)
@@ -8,4 +8,5 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
+import java.util.HashSet;
 
 import javax.swing.JOptionPane;
@@ -70,11 +71,18 @@
         BoundingXYVisitor v = new BoundingXYVisitor();
         if (mode.equals("data")) {
-            for (Layer l : Main.map.mapView.getAllLayers())
+            for (Layer l : Main.map.mapView.getAllLayers()) {
                 l.visitBoundingBox(v);
-        } else if (mode.equals("layer"))
+            }
+        } else if (mode.equals("layer")) {
             Main.map.mapView.getActiveLayer().visitBoundingBox(v);
-        else if (mode.equals("selection") || mode.equals("conflict")) {
-            Collection<OsmPrimitive> sel = mode.equals("selection") ? Main.ds.getSelected()
-                    : Main.map.conflictDialog.conflicts.keySet();
+        } else if (mode.equals("selection") || mode.equals("conflict")) {
+            Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
+            if (mode.equals("selection")) {
+                sel = Main.ds.getSelected();
+            } else if (mode.equals("conflict")) {
+                if (Main.map.conflictDialog.getConflicts() != null) {
+                    sel = Main.map.conflictDialog.getConflicts().getMyConflictParties();
+                }
+            }
             if (sel.isEmpty()) {
                 JOptionPane.showMessageDialog(Main.parent,
@@ -82,6 +90,7 @@
                 return null;
             }
-            for (OsmPrimitive osm : sel)
+            for (OsmPrimitive osm : sel) {
                 osm.visit(v);
+            }
             // increase bbox by 0.001 degrees on each side. this is required
             // especially if the bbox contains one single node, but helpful
Index: trunk/src/org/openstreetmap/josm/actions/CopyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 1750)
@@ -48,5 +48,5 @@
 
         Main.pasteBuffer = copyData();
-        Main.pasteSource = Main.main.editLayer();
+        Main.pasteSource = Main.main.createOrGetEditLayer();
         Main.main.menu.paste.setEnabled(true); /* now we have a paste buffer we can make paste available */
 
Index: trunk/src/org/openstreetmap/josm/actions/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DeleteAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/DeleteAction.java	(revision 1750)
@@ -25,5 +25,5 @@
 
     public void actionPerformed(ActionEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
         new org.openstreetmap.josm.actions.mapmode.DeleteAction(Main.map)
Index: trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java	(revision 1750)
@@ -28,5 +28,5 @@
 
     public void actionPerformed(ActionEvent e) {
-        PasteAction.pasteData(CopyAction.copyData(), Main.main.editLayer(), e);
+        PasteAction.pasteData(CopyAction.copyData(), Main.main.createOrGetEditLayer(), e);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 1750)
@@ -64,5 +64,5 @@
             return;
 
-        exportGpx(file, this.layer == null ? Main.main.editLayer() : this.layer);
+        exportGpx(file, this.layer == null ? Main.main.createOrGetEditLayer() : this.layer);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/MoveAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MoveAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/MoveAction.java	(revision 1750)
@@ -46,15 +46,14 @@
             sc = Shortcut.registerShortcut("core:moveright", tr("Move objects {0}", directiontext), KeyEvent.VK_RIGHT, Shortcut.GROUPS_ALT1+Shortcut.GROUP_DIRECT);
         }
-        if (text) {
+        if (text)
             return directiontext;
-        } else {
+        else
             return sc;
-        }
     }
 
     public MoveAction(Direction dir) {
         super(tr("Move {0}", calltosupermustbefirststatementinconstructor(dir, true)), null,
-              tr("Moves Objects {0}", calltosupermustbefirststatementinconstructor(dir, true)),
-              (Shortcut)calltosupermustbefirststatementinconstructor(dir, false), true);
+                tr("Moves Objects {0}", calltosupermustbefirststatementinconstructor(dir, true)),
+                (Shortcut)calltosupermustbefirststatementinconstructor(dir, false), true);
         myDirection = dir;
     }
@@ -92,9 +91,10 @@
         ? Main.main.undoRedo.commands.getLast() : null;
 
-        if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).objects))
+        if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).getMovedNodes())) {
             ((MoveCommand)c).moveAgain(distx, disty);
-        else
+        } else {
             Main.main.undoRedo.add(
                     c = new MoveCommand(selection, distx, disty));
+        }
 
         for (Node n : affectedNodes) {
Index: trunk/src/org/openstreetmap/josm/actions/PasteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PasteAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/PasteAction.java	(revision 1750)
@@ -69,5 +69,5 @@
             Node nnew = new Node(n);
             nnew.id = 0;
-            if (Main.main.editLayer() == source) {
+            if (Main.main.createOrGetEditLayer() == source) {
                 nnew.setEastNorth(nnew.getEastNorth().add(offsetEast, offsetNorth));
             }
Index: trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 1750)
@@ -20,4 +20,5 @@
 import org.apache.tools.bzip2.CBZip2OutputStream;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -49,8 +50,10 @@
         Layer layer = this.layer;
         if (layer == null && Main.map != null && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
-                || Main.map.mapView.getActiveLayer() instanceof GpxLayer))
+                || Main.map.mapView.getActiveLayer() instanceof GpxLayer)) {
             layer = Main.map.mapView.getActiveLayer();
-        if (layer == null)
-            layer = Main.main.editLayer();
+        }
+        if (layer == null) {
+            layer = Main.main.createOrGetEditLayer();
+        }
 
         if (!checkSaveConditions(layer))
@@ -87,18 +90,19 @@
         }
 
-        if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && 1 != new ExtendedDialog(Main.parent, tr("Empty document"), tr("The document contains no data."), new String[] {tr("Save anyway"), tr("Cancel")}, new String[] {"save.png", "cancel.png"}).getValue()) {
-            return false;
-        }
-        if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null) {
-            return false;
-        }
-        if (!Main.map.conflictDialog.conflicts.isEmpty()) {
-            int answer = new ExtendedDialog(Main.parent,
-                tr("Conflicts"),
-                tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"),
-                new String[] {tr("Reject Conflicts and Save"), tr("Cancel")},
-                new String[] {"save.png", "cancel.png"}).getValue();
-
-            if (answer != 1) return false;
+        if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && 1 != new ExtendedDialog(Main.parent, tr("Empty document"), tr("The document contains no data."), new String[] {tr("Save anyway"), tr("Cancel")}, new String[] {"save.png", "cancel.png"}).getValue())
+            return false;
+        if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null)
+            return false;
+        if (layer instanceof OsmDataLayer)  {
+            ConflictCollection conflicts = ((OsmDataLayer)layer).getConflicts();
+            if (conflicts != null && !conflicts.isEmpty()) {
+                int answer = new ExtendedDialog(Main.parent,
+                        tr("Conflicts"),
+                        tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"),
+                        new String[] {tr("Reject Conflicts and Save"), tr("Cancel")},
+                        new String[] {"save.png", "cancel.png"}).getValue();
+
+                if (answer != 1) return false;
+            }
         }
         return true;
@@ -148,7 +152,7 @@
             OsmGzipImporter osmGzipImporter = new OsmGzipImporter();
             OsmBzip2Importer osmBzip2Importer = new OsmBzip2Importer();
-            if (gpxImExporter.acceptFile(file))
+            if (gpxImExporter.acceptFile(file)) {
                 GpxExportAction.exportGpx(file, layer);
-            else if (osmImExporter.acceptFile(file)
+            } else if (osmImExporter.acceptFile(file)
                     || osmGzipImporter.acceptFile(file)
                     || osmBzip2Importer.acceptFile(file))
@@ -180,6 +184,7 @@
                 w.close();
                 // FIXME - how to close?
-                if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null))
+                if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null)) {
                     tmpFile.delete();
+                }
             } else {
                 JOptionPane.showMessageDialog(Main.parent, tr("Unknown file extension."));
Index: trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java	(revision 1750)
@@ -32,5 +32,5 @@
         int bboxCount = 0;
         List<Area> areas = new ArrayList<Area>();
-        for(DataSource ds : Main.main.editLayer().data.dataSources) {
+        for(DataSource ds : Main.main.createOrGetEditLayer().data.dataSources) {
             areas.add(new Area(ds.bounds.asRect()));
         }
Index: trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java	(revision 1750)
@@ -35,5 +35,5 @@
     protected void handlePrimitiveGoneException(long id) {
         MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
-        reader.append(Main.main.editLayer().data,id);
+        reader.append(Main.main.createOrGetEditLayer().data,id);
         DataSet ds = null;
         try {
@@ -43,5 +43,5 @@
             return;
         }
-        Main.main.editLayer().mergeFrom(ds);
+        Main.main.createOrGetEditLayer().mergeFrom(ds);
     }
 
@@ -90,9 +90,9 @@
             return;
         }
-        Main.main.editLayer().mergeFrom(ds);
+        Main.main.createOrGetEditLayer().mergeFrom(ds);
     }
 
     public void updatePrimitive(long id) {
-        OsmPrimitive primitive = Main.main.editLayer().data.getPrimitiveById(id);
+        OsmPrimitive primitive = Main.main.createOrGetEditLayer().data.getPrimitiveById(id);
         Set<OsmPrimitive> s = new HashSet<OsmPrimitive>();
         s.add(primitive);
Index: trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 1750)
@@ -23,4 +23,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -159,5 +160,6 @@
         }
 
-        if (!Main.map.conflictDialog.conflicts.isEmpty()) {
+        ConflictCollection conflicts = Main.main.createOrGetEditLayer().getConflicts();
+        if (conflicts !=null && !conflicts.isEmpty()) {
             JOptionPane.showMessageDialog(Main.parent,tr("There are unresolved conflicts. You have to resolve these first."));
             Main.map.conflictDialog.action.button.setSelected(true);
@@ -212,5 +214,5 @@
                 try {
                     server.uploadOsm(Main.ds.version, all);
-                    Main.main.editLayer().cleanData(server.processed, !add.isEmpty());
+                    Main.main.createOrGetEditLayer().cleanData(server.processed, !add.isEmpty());
                 } catch (Exception sxe) {
                     if (uploadCancelled) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 1750)
@@ -39,5 +39,4 @@
         private DataSet dataSet;
         private boolean newLayer;
-        private int num = 1;
         private String msg = "";
 
@@ -69,9 +68,9 @@
             }
             rememberDownloadedData(dataSet);
-            OsmDataLayer layer = new OsmDataLayer(dataSet, tr("Data Layer {0}", num), null);
+            OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
             if (newLayer) {
                 Main.main.addLayer(layer);
             } else {
-                Main.main.editLayer().mergeFrom(layer);
+                Main.main.createOrGetEditLayer().mergeFrom(layer);
             }
 
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java	(revision 1750)
@@ -42,5 +42,5 @@
     public void download(boolean newLayer, List<Rectangle2D> rects) {
         if(newLayer) {
-            Layer l = new OsmDataLayer(new DataSet(), tr("Data Layer"), null);
+            Layer l = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
             Main.main.addLayer(l);
             Main.map.mapView.setActiveLayer(l);
@@ -98,5 +98,5 @@
         }
 
-        Set<Long> myPrimitiveIds = Main.main.editLayer().data.getPrimitiveIds();
+        Set<Long> myPrimitiveIds = Main.main.createOrGetEditLayer().data.getPrimitiveIds();
         Set<Long> downloadedIds = getDownloadedIds();
         myPrimitiveIds.removeAll(downloadedIds);
@@ -108,5 +108,5 @@
 
     protected void checkPotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) {
-        DataSet ds =  Main.main.editLayer().data;
+        DataSet ds =  Main.main.createOrGetEditLayer().data;
         ArrayList<OsmPrimitive> toSelect = new ArrayList<OsmPrimitive>();
         for (Long id : potentiallyDeleted) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 1750)
@@ -64,5 +64,5 @@
     @Override public void actionPerformed(ActionEvent e) {
         super.actionPerformed(e);
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
         doActionPerformed(e);
@@ -70,5 +70,5 @@
 
     public void doActionPerformed(ActionEvent e) {
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
         boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
@@ -96,5 +96,5 @@
         if (e.getButton() != MouseEvent.BUTTON1)
             return;
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
         boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 1750)
@@ -240,5 +240,5 @@
      */
     public void eventDispatched(AWTEvent event) {
-        if(Main.map == null || Main.map.mapView == null || !Main.map.mapView.isDrawableLayer())
+        if(Main.map == null || Main.map.mapView == null || !Main.map.mapView.isActiveLayerDrawable())
             return;
         updateKeyModifiers((InputEvent) event);
@@ -251,5 +251,5 @@
      */
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
         computeHelperLine();
@@ -288,5 +288,5 @@
         if (e.getButton() != MouseEvent.BUTTON1)
             return;
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
 
@@ -576,5 +576,5 @@
 
     @Override public void mouseMoved(MouseEvent e) {
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
 
@@ -705,5 +705,5 @@
      */
     @Override public void mouseExited(MouseEvent e) {
-        if(!Main.map.mapView.isDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerDrawable())
             return;
         mousePos = e.getPoint();
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 1750)
@@ -126,5 +126,5 @@
      */
     @Override public void mouseDragged(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
         if (mode == Mode.select) return;
@@ -195,5 +195,5 @@
      */
     @Override public void mousePressed(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
         if (!(Boolean)this.getValue("active")) return;
@@ -227,5 +227,5 @@
      */
     @Override public void mouseReleased(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
         restoreCursor();
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 1750)
@@ -96,7 +96,7 @@
     public SelectAction(MapFrame mapFrame) {
         super(tr("Select"), "move/move", tr("Select, move and rotate objects"),
-            Shortcut.registerShortcut("mapmode:select", tr("Mode: {0}", tr("Select")), KeyEvent.VK_S, Shortcut.GROUP_EDIT),
-            mapFrame,
-            getCursor("normal", "selection", Cursor.DEFAULT_CURSOR));
+                Shortcut.registerShortcut("mapmode:select", tr("Mode: {0}", tr("Select")), KeyEvent.VK_S, Shortcut.GROUP_EDIT),
+                mapFrame,
+                getCursor("normal", "selection", Cursor.DEFAULT_CURSOR));
         putValue("help", "Action/Move/Move");
         selectionManager = new SelectionManager(this, false, mapFrame.mapView);
@@ -131,6 +131,6 @@
         Main.map.mapView.addMouseListener(this);
         Main.map.mapView.addMouseMotionListener(this);
-        Main.map.mapView.enableVirtualNodes(
-        Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0);
+        Main.map.mapView.setVirtualNodesEnabled(
+                Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0);
     }
 
@@ -140,5 +140,5 @@
         Main.map.mapView.removeMouseListener(this);
         Main.map.mapView.removeMouseMotionListener(this);
-        Main.map.mapView.enableVirtualNodes(false);
+        Main.map.mapView.setVirtualNodesEnabled(false);
     }
 
@@ -149,5 +149,5 @@
      */
     @Override public void mouseDragged(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
 
@@ -162,6 +162,7 @@
                 return;
 
-        if (mode == Mode.move)
+        if (mode == Mode.move) {
             setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+        }
 
         if (mousePos == null) {
@@ -196,6 +197,6 @@
             virtualCmds.add(new MoveCommand(virtualNode, dx, dy));
             String text = trn("Add and move a virtual new node to way",
-            "Add and move a virtual new node to {0} ways", virtualWays.size(),
-            virtualWays.size());
+                    "Add and move a virtual new node to {0} ways", virtualWays.size(),
+                    virtualWays.size());
 
             Main.main.undoRedo.add(new SequenceCommand(text, virtualCmds));
@@ -214,14 +215,16 @@
 
             Command c = !Main.main.undoRedo.commands.isEmpty()
-                ? Main.main.undoRedo.commands.getLast() : null;
-            if (c instanceof SequenceCommand)
+            ? Main.main.undoRedo.commands.getLast() : null;
+            if (c instanceof SequenceCommand) {
                 c = ((SequenceCommand)c).getLastCommand();
+            }
 
             if (mode == Mode.move) {
-                if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).objects))
+                if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).getMovedNodes())) {
                     ((MoveCommand)c).moveAgain(dx,dy);
-                else
+                } else {
                     Main.main.undoRedo.add(
-                        c = new MoveCommand(selection, dx, dy));
+                            c = new MoveCommand(selection, dx, dy));
+                }
 
                 for (Node n : affectedNodes) {
@@ -231,5 +234,5 @@
 
                         JOptionPane.showMessageDialog(Main.parent,
-                            tr("Cannot move objects outside of the world."));
+                                tr("Cannot move objects outside of the world."));
                         restoreCursor();
                         return;
@@ -237,8 +240,9 @@
                 }
             } else if (mode == Mode.rotate) {
-                if (c instanceof RotateCommand && affectedNodes.equals(((RotateCommand)c).objects))
+                if (c instanceof RotateCommand && affectedNodes.equals(((RotateCommand)c).getRotatedNodes())) {
                     ((RotateCommand)c).rotateAgain(mouseStartEN, mouseEN);
-                else
+                } else {
                     Main.main.undoRedo.add(new RotateCommand(selection, mouseStartEN, mouseEN));
+                }
             }
         }
@@ -255,6 +259,7 @@
      */
     @Override public void mouseMoved(MouseEvent e) {
-        if (needMouseMove && mode == Mode.rotate)
+        if (needMouseMove && mode == Mode.rotate) {
             mouseDragged(e);
+        }
     }
 
@@ -271,10 +276,11 @@
         {
             Collection<WaySegment> nearestWaySegs = allSegements
-                 ? c.getNearestWaySegments(p)
-                 : Collections.singleton(c.getNearestWaySegment(p));
+            ? c.getNearestWaySegments(p)
+                    : Collections.singleton(c.getNearestWaySegment(p));
 
             for(WaySegment nearestWS : nearestWaySegs) {
-                if (nearestWS == null)
+                if (nearestWS == null) {
                     continue;
+                }
 
                 osm = nearestWS.way;
@@ -294,12 +300,15 @@
                             if(virtualWayNode != null) {
                                 if(  !w.nodes.get(nearestWS.lowerIndex+1).equals(virtualWayNode)
-                                  && !w.nodes.get(nearestWS.lowerIndex  ).equals(virtualWayNode))
+                                        && !w.nodes.get(nearestWS.lowerIndex  ).equals(virtualWayNode)) {
                                     continue;
-                            } else
+                                }
+                            } else {
                                 virtualWayNode = w.nodes.get(nearestWS.lowerIndex+1);
+                            }
 
                             virtualWays.add(nearestWS);
-                            if(virtualNode == null)
+                            if(virtualNode == null) {
                                 virtualNode = new Node(Main.map.mapView.getLatLon(pc.x, pc.y));
+                            }
                         }
                     }
@@ -322,5 +331,5 @@
      */
     @Override public void mousePressed(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
 
@@ -335,6 +344,7 @@
         // We don't want to change to draw tool if the user tries to (de)select
         // stuff but accidentally clicks in an empty area when selection is empty
-        if(shift || ctrl)
+        if(shift || ctrl) {
             cancelDrawMode = true;
+        }
 
         mouseDownTime = System.currentTimeMillis();
@@ -345,5 +355,7 @@
 
         if (ctrl && shift) {
-            if (Main.ds.getSelected().isEmpty()) selectPrims(osmColl, true, false, false, false);
+            if (Main.ds.getSelected().isEmpty()) {
+                selectPrims(osmColl, true, false, false, false);
+            }
             mode = Mode.rotate;
             setCursor(ImageProvider.getCursor("rotate", null));
@@ -354,6 +366,6 @@
             // move.
             selectPrims(osmColl,
-                shift || Main.ds.getSelected().containsAll(osmColl),
-                ctrl, false, false);
+                    shift || Main.ds.getSelected().containsAll(osmColl),
+                    ctrl, false, false);
             mode = Mode.move;
         } else {
@@ -373,6 +385,7 @@
         // Mode.move   redraws when mouseDragged is called
         // Mode.rotate redraws here
-        if(mode == Mode.rotate)
+        if(mode == Mode.rotate) {
             Main.map.mapView.repaint();
+        }
 
         mousePos = e.getPoint();
@@ -383,5 +396,5 @@
      */
     @Override public void mouseReleased(MouseEvent e) {
-        if(!Main.map.mapView.isVisibleDrawableLayer())
+        if(!Main.map.mapView.isActiveLayerVisible())
             return;
 
@@ -402,6 +415,6 @@
             if (!didMove) {
                 selectPrims(
-                    Main.map.mapView.getNearestCollection(e.getPoint()),
-                    shift, ctrl, true, false);
+                        Main.map.mapView.getNearestCollection(e.getPoint()),
+                        shift, ctrl, true, false);
 
                 // If the user double-clicked a node, change to draw mode
@@ -423,7 +436,7 @@
                 for (OsmPrimitive osm : selection)
                 {
-                    if(osm instanceof Node)
+                    if(osm instanceof Node) {
                         s.add(osm);
-                    else if(osm instanceof Way)
+                    } else if(osm instanceof Way)
                     {
                         s.add(osm);
@@ -433,9 +446,9 @@
                     {
                         if(1 != new ExtendedDialog(Main.parent, tr("Move elements"),
-                        tr("You did move more than {0} elements. "
-                        + "Moving a large number of elements is often an error.\n"
-                        + "Really move them?", max),
-                        new String[] {tr("Move them"), tr("Undo move")},
-                        new String[] {"reorder.png", "cancel.png"}).getValue())
+                                tr("You did move more than {0} elements. "
+                                        + "Moving a large number of elements is often an error.\n"
+                                        + "Really move them?", max),
+                                        new String[] {tr("Move them"), tr("Undo move")},
+                                        new String[] {"reorder.png", "cancel.png"}).getValue())
                         {
                             Main.main.undoRedo.undo();
@@ -451,6 +464,7 @@
                         LinkedList<Node> selNodes = new LinkedList<Node>();
                         for (OsmPrimitive osm : selection)
-                            if (osm instanceof Node)
+                            if (osm instanceof Node) {
                                 selNodes.add((Node)osm);
+                            }
                         if (selNodes.size() > 0) {
                             selNodes.add(n);
@@ -474,13 +488,14 @@
 
     public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift,
-    boolean ctrl, boolean released, boolean area) {
+            boolean ctrl, boolean released, boolean area) {
         if ((shift && ctrl) || (ctrl && !released))
             return; // not allowed together
 
         Collection<OsmPrimitive> curSel;
-        if (!ctrl && !shift)
+        if (!ctrl && !shift) {
             curSel = new LinkedList<OsmPrimitive>(); // new selection will replace the old.
-        else
+        } else {
             curSel = Main.ds.getSelected();
+        }
 
         for (OsmPrimitive osm : selectionList)
@@ -488,11 +503,12 @@
             if (ctrl)
             {
-                if(curSel.contains(osm))
+                if(curSel.contains(osm)) {
                     curSel.remove(osm);
-                else if(!area)
+                } else if(!area) {
                     curSel.add(osm);
-            }
-            else
+                }
+            } else {
                 curSel.add(osm);
+            }
         }
         Main.ds.setSelected(curSel);
@@ -501,13 +517,12 @@
 
     @Override public String getModeHelpText() {
-        if (mode == Mode.select) {
+        if (mode == Mode.select)
             return tr("Release the mouse button to select the objects in the rectangle.");
-        } else if (mode == Mode.move) {
+        else if (mode == Mode.move)
             return tr("Release the mouse button to stop moving. Ctrl to merge with nearest node.");
-        } else if (mode == Mode.rotate) {
+        else if (mode == Mode.rotate)
             return tr("Release the mouse button to stop rotating.");
-        } else {
+        else
             return tr("Move objects by dragging; Shift to add to selection (Ctrl to toggle); Shift-Ctrl to rotate selected; or change selection");
-        }
     }
 
Index: trunk/src/org/openstreetmap/josm/command/AddCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/AddCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/AddCommand.java	(revision 1750)
@@ -10,12 +10,8 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
 import org.openstreetmap.josm.data.osm.visitor.DeleteVisitor;
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
-import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 
 /**
@@ -23,5 +19,5 @@
  * way.
  *
- * See {@link ChangeCommand ChangeCommand} for comments on relation back references.
+ * See {@see ChangeCommand} for comments on relation back references.
  *
  * @author imi
@@ -34,21 +30,19 @@
     private final OsmPrimitive osm;
 
-    private DataSet ds;
-
     /**
      * Create the command and specify the element to add.
      */
     public AddCommand(OsmPrimitive osm) {
+        super();
         this.osm = osm;
-        this.ds = Main.main.editLayer().data;
     }
 
     @Override public boolean executeCommand() {
-        osm.visit(new AddVisitor(ds));
+        osm.visit(new AddVisitor(getLayer().data));
         return true;
     }
 
     @Override public void undoCommand() {
-        osm.visit(new DeleteVisitor(ds));
+        osm.visit(new DeleteVisitor(getLayer().data));
     }
 
@@ -57,13 +51,9 @@
     }
 
-    // faster implementation
-    @Override public boolean invalidBecauselayerRemoved(Layer oldLayer) {
-        return oldLayer instanceof OsmDataLayer && ((OsmDataLayer)oldLayer).data == ds;
-    }
-
     @Override public MutableTreeNode description() {
         NameVisitor v = new NameVisitor();
         osm.visit(v);
-        return new DefaultMutableTreeNode(new JLabel(tr("Add")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(
+                new JLabel(tr("Add {0} {1}", tr(v.className), v.name), v.icon, JLabel.HORIZONTAL));
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/ChangeCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 1750)
@@ -25,4 +25,5 @@
 
     public ChangeCommand(OsmPrimitive osm, OsmPrimitive newOsm) {
+        super();
         this.osm = osm;
         this.newOsm = newOsm;
@@ -43,5 +44,5 @@
         NameVisitor v = new NameVisitor();
         osm.visit(v);
-        return new DefaultMutableTreeNode(new JLabel(tr("Change")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(new JLabel(tr("Change {0} {1}", tr(v.className), v.name), v.icon, JLabel.HORIZONTAL));
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java	(revision 1750)
@@ -40,4 +40,5 @@
 
     public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
+        super();
         this.objects = new LinkedList<OsmPrimitive>();
         this.key = key;
@@ -45,6 +46,7 @@
         if (value == null) {
             for (OsmPrimitive osm : objects) {
-                if(osm.get(key) != null)
+                if(osm.get(key) != null) {
                     this.objects.add(osm);
+                }
             }
         } else {
@@ -64,6 +66,7 @@
         String val = object.get(key);
         if ((value == null && val != null)
-        || (value != null && (val == null || !value.equals(val))))
+                || (value != null && (val == null || !value.equals(val)))) {
             this.objects.add(object);
+        }
     }
 
@@ -95,5 +98,5 @@
             text = value == null
             ? tr("Remove \"{0}\" for {1} ''{2}''", key, tr(v.className), v.name)
-            : tr("Set {0}={1} for {2} ''{3}''",key,value, tr(v.className), v.name);
+                    : tr("Set {0}={1} for {2} ''{3}''",key,value, tr(v.className), v.name);
         }
         else
@@ -101,5 +104,5 @@
             text = value == null
             ? tr("Remove \"{0}\" for {1} {2}", key, objects.size(), trn("object","objects",objects.size()))
-            : tr("Set {0}={1} for {2} {3}",key,value, objects.size(), trn("object","objects",objects.size()));
+                    : tr("Set {0}={1} for {2} {3}",key,value, objects.size(), trn("object","objects",objects.size()));
         }
         DefaultMutableTreeNode root = new DefaultMutableTreeNode(new JLabel(text, ImageProvider.get("data", "key"), JLabel.HORIZONTAL));
Index: trunk/src/org/openstreetmap/josm/command/ChangeRelationMemberRoleCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ChangeRelationMemberRoleCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/ChangeRelationMemberRoleCommand.java	(revision 1750)
@@ -13,6 +13,4 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 
@@ -36,4 +34,5 @@
 
     public ChangeRelationMemberRoleCommand(Relation relation, int position, String newRole) {
+        super();
         this.relation = relation;
         this.position = position;
@@ -67,5 +66,5 @@
         NameVisitor v = new NameVisitor();
         relation.visit(v);
-        return new DefaultMutableTreeNode(new JLabel(tr("ChangeRelationMemberRole")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(new JLabel(tr("ChangeRelationMemberRole {0} {1}", tr(v.className), v.name), v.icon, JLabel.HORIZONTAL));
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/Command.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/Command.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/Command.java	(revision 1750)
@@ -11,5 +11,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -25,80 +24,74 @@
  * one atomic action on a specific dataset, such as move or delete.
  *
- * Remember that the command must be executable and undoable, even if the
- * Main.ds has changed, so the command must save the dataset it operates on
- * if necessary.
- *
+ * The command remembers the {@see OsmDataLayer} it is operating on.
+ * 
  * @author imi
  */
 abstract public class Command {
 
-   private static final class CloneVisitor extends AbstractVisitor {
-      public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
+    private static final class CloneVisitor extends AbstractVisitor {
+        public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
 
-      public void visit(Node n) {
-         orig.put(n, new Node(n));
-      }
-      public void visit(Way w) {
-         orig.put(w, new Way(w));
-      }
-      public void visit(Relation e) {
-         orig.put(e, new Relation(e));
-      }
-   }
+        public void visit(Node n) {
+            orig.put(n, new Node(n));
+        }
+        public void visit(Way w) {
+            orig.put(w, new Way(w));
+        }
+        public void visit(Relation e) {
+            orig.put(e, new Relation(e));
+        }
+    }
 
-   private CloneVisitor orig;
+    /** the map of OsmPrimitives in the original state to OsmPrimitives in cloned state */
+    private Map<OsmPrimitive, OsmPrimitive> cloneMap = new HashMap<OsmPrimitive, OsmPrimitive>();
 
-   protected DataSet ds;
+    /** the layer which this command is applied to */
+    private OsmDataLayer layer;
 
-   public Command() {
-      this.ds = Main.main.editLayer().data;
-   }
-   /**
-    * Executes the command on the dataset. This implementation will remember all
-    * primitives returned by fillModifiedData for restoring them on undo.
-    */
-   public boolean did_execute = false;
-   public boolean executeCommand() {
-      did_execute = true;
-      orig = new CloneVisitor();
-      Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
-      fillModifiedData(all, all, all);
-      for (OsmPrimitive osm : all)
-         osm.visit(orig);
-      return true;
-   }
+    public Command() {
+        this.layer = Main.main.map.mapView.getEditLayer();
+    }
+    /**
+     * Executes the command on the dataset. This implementation will remember all
+     * primitives returned by fillModifiedData for restoring them on undo.
+     */
+    public boolean executeCommand() {
+        CloneVisitor visitor = new CloneVisitor();
+        Collection<OsmPrimitive> all = new HashSet<OsmPrimitive>();
+        fillModifiedData(all, all, all);
+        for (OsmPrimitive osm : all) {
+            osm.visit(visitor);
+        }
+        cloneMap = visitor.orig;
+        return true;
+    }
 
-   /**
-    * Undoes the command.
-    * It can be assumed that all objects are in the same state they were before.
-    * It can also be assumed that executeCommand was called exactly once before.
-    *
-    * This implementation undoes all objects stored by a former call to executeCommand.
-    */
-   public void undoCommand() {
-      for (Entry<OsmPrimitive, OsmPrimitive> e : orig.orig.entrySet())
-         e.getKey().cloneFrom(e.getValue());
-   }
+    /**
+     * Undoes the command.
+     * It can be assumed that all objects are in the same state they were before.
+     * It can also be assumed that executeCommand was called exactly once before.
+     *
+     * This implementation undoes all objects stored by a former call to executeCommand.
+     */
+    public void undoCommand() {
+        for (Entry<OsmPrimitive, OsmPrimitive> e : cloneMap.entrySet()) {
+            e.getKey().cloneFrom(e.getValue());
+        }
+    }
 
-   /**
-    * Called when a layer has been removed to have the command remove itself from
-    * any buffer if it is not longer applicable to the dataset (e.g. it was part of
-    * the removed layer)
-    */
-   public boolean invalidBecauselayerRemoved(Layer oldLayer) {
-      if (!(oldLayer instanceof OsmDataLayer))
-         return false;
-      HashSet<OsmPrimitive> modified = new HashSet<OsmPrimitive>();
-      fillModifiedData(modified, modified, modified);
-      if (modified.isEmpty())
-         return false;
-
-      HashSet<OsmPrimitive> all = new HashSet<OsmPrimitive>(((OsmDataLayer)oldLayer).data.allPrimitives());
-      for (OsmPrimitive osm : all)
-         if (all.contains(osm))
-                 return true;
-
-      return false;
-   }
+    /**
+     * Called when a layer has been removed to have the command remove itself from
+     * any buffer if it is not longer applicable to the dataset (e.g. it was part of
+     * the removed layer)
+     * 
+     * @param oldLayer the old layer
+     * @return true if this command
+     */
+    public boolean invalidBecauselayerRemoved(Layer oldLayer) {
+        if (!(oldLayer instanceof OsmDataLayer))
+            return false;
+        return layer == oldLayer;
+    }
 
     /**
@@ -107,28 +100,40 @@
      */
     public OsmPrimitive getOrig(OsmPrimitive osm) {
-        OsmPrimitive o = orig.orig.get(osm);
+        OsmPrimitive o = cloneMap.get(osm);
         if (o != null)
-             return o;
+            return o;
         Main.debug("unable to find osm with id: " + osm.id + " hashCode: " + osm.hashCode());
-        for (OsmPrimitive t : orig.orig.keySet()) {
-             OsmPrimitive to = orig.orig.get(t);
-             Main.debug("now: " + t.id + " hashCode: " + t.hashCode());
-             Main.debug("orig: " + to.id + " hashCode: " + to.hashCode());
+        for (OsmPrimitive t : cloneMap.keySet()) {
+            OsmPrimitive to = cloneMap.get(t);
+            Main.debug("now: " + t.id + " hashCode: " + t.hashCode());
+            Main.debug("orig: " + to.id + " hashCode: " + to.hashCode());
         }
         return o;
     }
 
-   /**
-    * Fill in the changed data this command operates on.
-    * Add to the lists, don't clear them.
-    *
-    * @param modified The modified primitives
-    * @param deleted The deleted primitives
-    * @param added The added primitives
-    */
-   abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
-         Collection<OsmPrimitive> deleted,
-         Collection<OsmPrimitive> added);
+    /**
+     * Replies the layer this command is (or was) applied to.
+     * 
+     * @return
+     */
+    protected  OsmDataLayer getLayer() {
+        return layer;
+    }
 
-   abstract public MutableTreeNode description();
+    /**
+     * Fill in the changed data this command operates on.
+     * Add to the lists, don't clear them.
+     *
+     * @param modified The modified primitives
+     * @param deleted The deleted primitives
+     * @param added The added primitives
+     */
+    abstract public void fillModifiedData(Collection<OsmPrimitive> modified,
+            Collection<OsmPrimitive> deleted,
+            Collection<OsmPrimitive> added);
+
+    abstract public MutableTreeNode description();
+
+
+
 }
Index: trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 1750)
+++ trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java	(revision 1750)
@@ -0,0 +1,75 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.command;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+/**
+ * This is the common basse class for {@see Command}s which manipulate {@see Conflict}s in
+ * addition to {@see OsmPrimitive}s.
+ * 
+ * A ConflictResolverCommand can remember a collection of conflicts it resolves. Upon undoing
+ * it reconstitutes these conflicts.
+ *
+ */
+public abstract class ConflictResolveCommand extends Command {
+    private static final Logger logger = Logger.getLogger(ConflictResolveCommand.class.getName());
+
+    /** the list of resolved conflicts */
+    private ConflictCollection resolvedConflicts;
+
+    public ConflictResolveCommand() {
+        super();
+        resolvedConflicts = new ConflictCollection();
+    }
+
+    /**
+     * remembers a conflict in the internal list of remembered conflicts
+     * 
+     * @param c the remembered conflict
+     */
+    protected void rememberConflict(Conflict c) {
+        if (! resolvedConflicts.hasConflictForMy(c.getMy())) {
+            resolvedConflicts.add(c);
+        }
+    }
+
+    /**
+     * reconstitutes all remembered conflicts. Add the remembered conflicts to the
+     * set of conflicts of the {@see OsmDataLayer} this command was applied to.
+     * 
+     */
+    protected void reconstituteConflicts() {
+        OsmDataLayer editLayer = getLayer();
+        for(Conflict c : resolvedConflicts) {
+            if (!editLayer.getConflicts().hasConflictForMy(c.getMy())) {
+                editLayer.getConflicts().add(c);
+            }
+        }
+    }
+
+    @Override
+    public void undoCommand() {
+        super.undoCommand();
+
+        if (! Main.map.mapView.hasLayer(getLayer())) {
+            logger.warning(tr("Can't undo command ''{0}'' because layer ''{1}'' is not present anymore",
+                    this.toString(),
+                    getLayer().toString()
+            ));
+            return;
+        }
+
+        Main.map.mapView.setActiveLayer(getLayer());
+        reconstituteConflicts();
+    }
+
+
+
+}
Index: trunk/src/org/openstreetmap/josm/command/CoordinateConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/CoordinateConflictResolveCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/CoordinateConflictResolveCommand.java	(revision 1750)
@@ -10,9 +10,7 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.conflict.MergeDecisionType;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -22,12 +20,8 @@
  *
  */
-public class CoordinateConflictResolveCommand extends Command {
+public class CoordinateConflictResolveCommand extends ConflictResolveCommand {
 
-    /** my node (in the local dataset). merge decisions are applied to this
-     *  node
-     */
-    private final Node my;
-    /** their node (in the server dataset) */
-    private final Node their;
+    /** the conflict to resolve */
+    private Conflict<Node> conflict;
 
     /** the merge decision */
@@ -42,6 +36,5 @@
      */
     public CoordinateConflictResolveCommand(Node my, Node their, MergeDecisionType decision) {
-        this.my = my;
-        this.their = their;
+        this.conflict = new Conflict<Node>(my,their);
         this.decision = decision;
     }
@@ -52,5 +45,5 @@
         return new DefaultMutableTreeNode(
                 new JLabel(
-                        tr("Resolve conflicts in coordinates in {0}",my.id),
+                        tr("Resolve conflicts in coordinates in {0}",conflict.getMy().id),
                         ImageProvider.get("data", "object"),
                         JLabel.HORIZONTAL
@@ -69,8 +62,14 @@
             // do nothing
         } else if (decision.equals(MergeDecisionType.KEEP_THEIR)) {
+            Node my = conflict.getMy();
+            Node their = conflict.getTheir();
             my.setCoor(their.getCoor());
         } else
             // should not happen
             throw new IllegalStateException(tr("cannot resolve undecided conflict"));
+
+        // remember the layer this command was applied to
+        //
+        rememberConflict(conflict);
 
         return true;
@@ -80,18 +79,5 @@
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        modified.add(my);
-    }
-
-    @Override
-    public void undoCommand() {
-        // restore former state of modified primitives
-        //
-        super.undoCommand();
-
-        // restore a conflict if necessary
-        //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.addConflict(my, their);
-        }
+        modified.add(conflict.getMy());
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 1750)
@@ -42,7 +42,7 @@
 
     /**
-     * The primitive that get deleted.
-     */
-    private final Collection<? extends OsmPrimitive> data;
+     * The primitives that get deleted.
+     */
+    private final Collection<? extends OsmPrimitive> toDelete;
 
     /**
@@ -50,5 +50,6 @@
      */
     public DeleteCommand(Collection<? extends OsmPrimitive> data) {
-        this.data = data;
+        super();
+        this.toDelete = data;
     }
 
@@ -58,10 +59,10 @@
      */
     public DeleteCommand(OsmPrimitive data) {
-        this.data = Collections.singleton(data);
+        this.toDelete = Collections.singleton(data);
     }
 
     @Override public boolean executeCommand() {
         super.executeCommand();
-        for (OsmPrimitive osm : data) {
+        for (OsmPrimitive osm : toDelete) {
             osm.delete(true);
         }
@@ -71,5 +72,5 @@
     @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        deleted.addAll(data);
+        deleted.addAll(toDelete);
     }
 
@@ -77,6 +78,6 @@
         NameVisitor v = new NameVisitor();
 
-        if (data.size() == 1) {
-            data.iterator().next().visit(v);
+        if (toDelete.size() == 1) {
+            toDelete.iterator().next().visit(v);
             return new DefaultMutableTreeNode(new JLabel(tr("Delete {1} {0}", v.name, tr(v.className)), v.icon,
                     JLabel.HORIZONTAL));
@@ -85,5 +86,5 @@
         String cname = null;
         String cnamem = null;
-        for (OsmPrimitive osm : data) {
+        for (OsmPrimitive osm : toDelete) {
             osm.visit(v);
             if (cname == null) {
@@ -95,7 +96,7 @@
             }
         }
-        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new JLabel(tr("Delete {0} {1}", data.size(), trn(
-                cname, cnamem, data.size())), ImageProvider.get("data", cname), JLabel.HORIZONTAL));
-        for (OsmPrimitive osm : data) {
+        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new JLabel(tr("Delete {0} {1}", toDelete.size(), trn(
+                cname, cnamem, toDelete.size())), ImageProvider.get("data", cname), JLabel.HORIZONTAL));
+        for (OsmPrimitive osm : toDelete) {
             osm.visit(v);
             root.add(new DefaultMutableTreeNode(v.toLabel()));
@@ -276,13 +277,5 @@
             Relation rel = new Relation(cur);
             for (OsmPrimitive osm : relationsToBeChanged.get(cur)) {
-                for (RelationMember rm : rel.members) {
-                    if (rm.member == osm) {
-                        RelationMember mem = new RelationMember();
-                        mem.role = rm.role;
-                        mem.member = rm.member;
-                        rel.members.remove(mem);
-                        break;
-                    }
-                }
+                rel.removeMembersFor(osm);
             }
             cmds.add(new ChangeCommand(cur, rel));
Index: trunk/src/org/openstreetmap/josm/command/DeletedStateConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeletedStateConflictResolveCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/DeletedStateConflictResolveCommand.java	(revision 1750)
@@ -10,7 +10,8 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.conflict.MergeDecisionType;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -19,17 +20,11 @@
  *
  */
-public class DeletedStateConflictResolveCommand extends Command {
+public class DeletedStateConflictResolveCommand extends ConflictResolveCommand {
 
-    /** my primitive (in the local dataset). merge decisions are applied to this
-     *  node
-     */
-    private final OsmPrimitive my;
-    /** their primitive (in the server dataset) */
-    private final OsmPrimitive their;
+    /** the conflict to resolve */
+    private Conflict<OsmPrimitive> conflict;
 
     /** the merge decision */
     private final MergeDecisionType decision;
-
-
 
     /**
@@ -41,6 +36,5 @@
      */
     public DeletedStateConflictResolveCommand(OsmPrimitive my, OsmPrimitive their, MergeDecisionType decision) {
-        this.my = my;
-        this.their = their;
+        this.conflict = new Conflict<OsmPrimitive>(my, their);
         this.decision = decision;
     }
@@ -51,5 +45,5 @@
         return new DefaultMutableTreeNode(
                 new JLabel(
-                        tr("Resolve conflicts in deleted state in {0}",my.id),
+                        tr("Resolve conflicts in deleted state in {0}",conflict.getMy().id),
                         ImageProvider.get("data", "object"),
                         JLabel.HORIZONTAL
@@ -65,17 +59,19 @@
         super.executeCommand();
 
+        OsmDataLayer layer = getLayer();
+
         if (decision.equals(MergeDecisionType.KEEP_MINE)) {
-            if (my.deleted) {
+            if (conflict.getMy().deleted) {
                 // because my was involved in a conflict it my still be referred
                 // to from a way or a relation. Fix this now.
                 //
-                Main.main.editLayer().data.unlinkReferencesToPrimitive(my);
+                layer.data.unlinkReferencesToPrimitive(conflict.getMy());
             }
         } else if (decision.equals(MergeDecisionType.KEEP_THEIR)) {
-            if (their.deleted) {
-                Main.main.editLayer().data.unlinkReferencesToPrimitive(my);
-                my.delete(true);
+            if (conflict.getTheir().deleted) {
+                layer.data.unlinkReferencesToPrimitive(conflict.getMy());
+                conflict.getMy().delete(true);
             } else {
-                my.deleted = their.deleted;
+                conflict.getMy().deleted = conflict.getTheir().deleted;
             }
         } else
@@ -83,4 +79,5 @@
             throw new IllegalStateException(tr("cannot resolve undecided conflict"));
 
+        rememberConflict(conflict);
         return true;
     }
@@ -89,18 +86,5 @@
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        modified.add(my);
-    }
-
-    @Override
-    public void undoCommand() {
-        // restore former state of modified primitives
-        //
-        super.undoCommand();
-
-        // restore a conflict if necessary
-        //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.addConflict(my, their);
-        }
+        modified.add(conflict.getMy());
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/MoveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/MoveCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/MoveCommand.java	(revision 1750)
@@ -15,5 +15,4 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.Node;
@@ -32,5 +31,5 @@
      * The objects that should be moved.
      */
-    public Collection<Node> objects = new LinkedList<Node>();
+    private Collection<Node> nodes = new LinkedList<Node>();
     /**
      * x difference movement. Coordinates are in northern/eastern
@@ -64,8 +63,9 @@
      */
     public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) {
+        super();
         this.x = x;
         this.y = y;
-        this.objects = AllNodesVisitor.getAllNodes(objects);
-        for (Node n : this.objects) {
+        this.nodes = AllNodesVisitor.getAllNodes(objects);
+        for (Node n : this.nodes) {
             OldState os = new OldState();
             os.latlon = new LatLon(n.getCoor());
@@ -84,5 +84,5 @@
      */
     public void moveAgain(double x, double y) {
-        for (Node n : objects) {
+        for (Node n : nodes) {
             n.setEastNorth(n.getEastNorth().add(x, y));
         }
@@ -92,5 +92,5 @@
 
     @Override public boolean executeCommand() {
-        for (Node n : objects) {
+        for (Node n : nodes) {
             n.setEastNorth(n.getEastNorth().add(x, y));
             n.modified = true;
@@ -101,5 +101,5 @@
     @Override public void undoCommand() {
         Iterator<OldState> it = oldState.iterator();
-        for (Node n : objects) {
+        for (Node n : nodes) {
             OldState os = it.next();
             n.setCoor(os.latlon);
@@ -109,10 +109,15 @@
 
     @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
-        for (OsmPrimitive osm : objects)
+        for (OsmPrimitive osm : nodes) {
             modified.add(osm);
+        }
     }
 
     @Override public MutableTreeNode description() {
-        return new DefaultMutableTreeNode(new JLabel(tr("Move")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(new JLabel(tr("Move")+" "+nodes.size()+" "+trn("node","nodes",nodes.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL));
+    }
+
+    public Collection<Node> getMovedNodes() {
+        return nodes;
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/PurgePrimitivesCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/PurgePrimitivesCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/PurgePrimitivesCommand.java	(revision 1750)
@@ -6,7 +6,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
+import java.util.logging.Logger;
 
 import javax.swing.JLabel;
@@ -15,4 +14,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -34,6 +35,7 @@
  * 
  */
-public class PurgePrimitivesCommand extends Command{
-
+public class PurgePrimitivesCommand extends ConflictResolveCommand{
+
+    static private final Logger logger = Logger.getLogger(PurgePrimitivesCommand.class.getName());
 
     /**
@@ -144,5 +146,4 @@
     private ArrayList<OsmParentChildPair> pairs;
 
-    private Map<OsmPrimitive, OsmPrimitive> resolvedConflicts;
 
     /**
@@ -154,5 +155,4 @@
         purgedPrimitives = new ArrayList<OsmPrimitive>();
         pairs = new ArrayList<OsmParentChildPair>();
-        resolvedConflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
     }
 
@@ -219,14 +219,15 @@
             purge(toPurge, Main.ds, hive);
             if (toPurge instanceof Node) {
-                Main.ds.nodes.remove(toPurge);
+                getLayer().data.nodes.remove(toPurge);
             } else if (primitive instanceof Way) {
-                Main.ds.ways.remove(toPurge);
+                getLayer().data.ways.remove(toPurge);
             } else if (primitive instanceof Relation) {
-                Main.ds.relations.remove(toPurge);
+                getLayer().data.relations.remove(toPurge);
             }
             purgedPrimitives.add(toPurge);
-            if (Main.map.conflictDialog.conflicts.containsKey(toPurge)) {
-                resolvedConflicts.put(toPurge, Main.map.conflictDialog.conflicts.get(toPurge));
-                Main.map.conflictDialog.removeConflictForPrimitive(toPurge);
+            ConflictCollection conflicts = getLayer().getConflicts();
+            if (conflicts.hasConflictForMy(toPurge)) {
+                rememberConflict(conflicts.getConflictForMy(toPurge));
+                conflicts.remove(toPurge);
             }
         }
@@ -246,17 +247,19 @@
     @Override
     public void undoCommand() {
+        if (! Main.map.mapView.hasLayer(getLayer())) {
+            logger.warning(tr("Can't undo command ''{0}'' because layer ''{1}'' is not present anymore",
+                    this.toString(),
+                    getLayer().toString()
+            ));
+            return;
+        }
+        Main.map.mapView.setActiveLayer(getLayer());
 
         // restore purged primitives
         //
         for (OsmPrimitive purged : purgedPrimitives) {
-            Main.ds.addPrimitive(purged);
-        }
-
-        // restore conflicts
-        //
-        for (OsmPrimitive primitive : resolvedConflicts.keySet()) {
-            Main.map.conflictDialog.addConflict(primitive, resolvedConflicts.get(primitive));
-        }
-
+            getLayer().data.addPrimitive(purged);
+        }
+        reconstituteConflicts();
         // will restore the former references to the purged nodes
         //
Index: trunk/src/org/openstreetmap/josm/command/RelationMemberConflictResolverCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/RelationMemberConflictResolverCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/RelationMemberConflictResolverCommand.java	(revision 1750)
@@ -6,4 +6,5 @@
 import java.util.Collection;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.swing.JLabel;
@@ -15,4 +16,5 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -23,4 +25,5 @@
  */
 public class RelationMemberConflictResolverCommand extends Command {
+    private static final Logger logger = Logger.getLogger(RelationMemberConflictResolverCommand.class.getName());
 
     /** my relation */
@@ -32,4 +35,7 @@
      */
     private final List<RelationMember> mergedMembers;
+
+    /** the layer this conflict is resolved in */
+    private OsmDataLayer layer;
 
     /**
@@ -71,4 +77,7 @@
             my.members.add(n);
         }
+
+        // remember the layer
+        layer = Main.main.map.mapView.getEditLayer();
         return true;
     }
@@ -82,4 +91,15 @@
     @Override
     public void undoCommand() {
+        if (! Main.map.mapView.hasLayer(layer)) {
+            logger.warning(tr("Can't undo command ''{0}'' because layer ''{1}'' is not present anymore",
+                    this.toString(),
+                    layer.toString()
+            ));
+            return;
+        }
+
+        Main.map.mapView.setActiveLayer(layer);
+        OsmDataLayer editLayer = Main.map.mapView.getEditLayer();
+
         // restore the former state
         //
@@ -88,6 +108,6 @@
         // restore a conflict if necessary
         //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.conflicts.put(my,their);
+        if (!editLayer.getConflicts().hasConflictForMy(my)) {
+            editLayer.getConflicts().add(my,their);
         }
     }
Index: trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java	(revision 1750)
@@ -64,5 +64,5 @@
         NameVisitor v = new NameVisitor();
         relation.visit(v);
-        return new DefaultMutableTreeNode(new JLabel(tr("RemoveRelationMember")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(new JLabel(tr("RemoveRelationMember {0} {1}", tr(v.className), v.name), v.icon, JLabel.HORIZONTAL));
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/RotateCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/RotateCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/RotateCommand.java	(revision 1750)
@@ -30,5 +30,5 @@
      * The objects to rotate.
      */
-    public Collection<Node> objects = new LinkedList<Node>();
+    private Collection<Node> nodes = new LinkedList<Node>();
 
     /**
@@ -70,8 +70,8 @@
     public RotateCommand(Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) {
 
-        this.objects = AllNodesVisitor.getAllNodes(objects);
+        this.nodes = AllNodesVisitor.getAllNodes(objects);
         pivot = new EastNorth(0,0);
 
-        for (Node n : this.objects) {
+        for (Node n : this.nodes) {
             OldState os = new OldState();
             os.latlon = new LatLon(n.getCoor());
@@ -81,5 +81,5 @@
             pivot = pivot.add(os.eastNorth.east(), os.eastNorth.north());
         }
-        pivot = new EastNorth(pivot.east()/this.objects.size(), pivot.north()/this.objects.size());
+        pivot = new EastNorth(pivot.east()/this.nodes.size(), pivot.north()/this.nodes.size());
 
         rotationAngle = Math.PI/2;
@@ -105,5 +105,5 @@
      */
     private void rotateNodes(boolean setModified) {
-        for (Node n : objects) {
+        for (Node n : nodes) {
             double cosPhi = Math.cos(rotationAngle);
             double sinPhi = Math.sin(rotationAngle);
@@ -114,6 +114,7 @@
             double ny = -cosPhi * x + sinPhi * y + pivot.north();
             n.setEastNorth(new EastNorth(nx, ny));
-            if (setModified)
+            if (setModified) {
                 n.modified = true;
+            }
         }
     }
@@ -125,5 +126,5 @@
 
     @Override public void undoCommand() {
-        for (Node n : objects) {
+        for (Node n : nodes) {
             OldState os = oldState.get(n);
             n.setCoor(os.latlon);
@@ -133,10 +134,15 @@
 
     @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
-        for (OsmPrimitive osm : objects)
+        for (OsmPrimitive osm : nodes) {
             modified.add(osm);
+        }
     }
 
     @Override public MutableTreeNode description() {
-        return new DefaultMutableTreeNode(new JLabel(tr("Rotate")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL));
+        return new DefaultMutableTreeNode(new JLabel(tr("Rotate {0} {1}",nodes.size(),trn("node","nodes",nodes.size())), ImageProvider.get("data", "node"), JLabel.HORIZONTAL));
+    }
+
+    public Collection<Node> getRotatedNodes() {
+        return nodes;
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/SequenceCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/SequenceCommand.java	(revision 1750)
@@ -33,4 +33,5 @@
      */
     public SequenceCommand(String name, Collection<Command> sequenz) {
+        super();
         this.name = name;
         this.sequence = new Command[sequenz.size()];
@@ -45,11 +46,11 @@
     }
 
-    public int executed_commands = 0;
     @Override public boolean executeCommand() {
         for (int i=0; i < sequence.length; i++) {
             Command c = sequence[i];
             boolean result = c.executeCommand();
-            if (!result)
+            if (!result) {
                 Main.debug("SequenceCommand, executing command[" + i + "] " +  c + " result: " + result);
+            }
             if (!result && !continueOnError) {
                 this.undoCommands(i-1);
@@ -72,6 +73,7 @@
         if (!sequence_complete)
             return;
-        for (int i = start; i >= 0; --i)
+        for (int i = start; i >= 0; --i) {
             sequence[i].undoCommand();
+        }
     }
 
@@ -81,12 +83,14 @@
 
     @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
-        for (Command c : sequence)
+        for (Command c : sequence) {
             c.fillModifiedData(modified, deleted, added);
+        }
     }
 
     @Override public MutableTreeNode description() {
         DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("Sequence")+": "+name);
-        for (Command c : sequence)
+        for (Command c : sequence) {
             root.add(c.description());
+        }
         return root;
     }
Index: trunk/src/org/openstreetmap/josm/command/TagConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/TagConflictResolveCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/TagConflictResolveCommand.java	(revision 1750)
@@ -6,4 +6,5 @@
 import java.util.Collection;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.swing.JLabel;
@@ -11,10 +12,7 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.conflict.Conflict;
 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.gui.conflict.MergeDecisionType;
 import org.openstreetmap.josm.gui.conflict.tags.TagMergeItem;
@@ -25,15 +23,14 @@
  *
  */
-public class TagConflictResolveCommand extends Command {
+public class TagConflictResolveCommand extends ConflictResolveCommand {
+    private static final Logger logger = Logger.getLogger(TagConflictResolveCommand.class.getName());
 
-    /** my primitive (in the local dataset). merge decisions are applied to this
-     *  primitive
-     */
-    private final OsmPrimitive my;
-    /** their primitive (in the server dataset) */
-    private final OsmPrimitive their;
+
+    /** the conflict to resolve */
+    private Conflict<OsmPrimitive> conflict;
 
     /** the list of merge decisions, represented as {@see TagMergeItem}s */
     private final List<TagMergeItem> mergeItems;
+
 
     /**
@@ -60,6 +57,5 @@
      */
     public TagConflictResolveCommand(OsmPrimitive my, OsmPrimitive their, List<TagMergeItem> mergeItems) {
-        this.my = my;
-        this.their = their;
+        this.conflict = new Conflict<OsmPrimitive>(my,their);
         this.mergeItems = mergeItems;
     }
@@ -70,5 +66,5 @@
         return new DefaultMutableTreeNode(
                 new JLabel(
-                        tr("Resolve {0} tag conflicts in {1} {2}",getNumDecidedConflicts(), OsmPrimitiveType.from(my).getLocalizedDisplayNameSingular(), my.id),
+                        tr("Resolve {0} tag conflicts in {1} {2}",getNumDecidedConflicts(), OsmPrimitiveType.from(conflict.getMy()).getLocalizedDisplayNameSingular(), conflict.getMy().id),
                         ImageProvider.get("data", "object"),
                         JLabel.HORIZONTAL
@@ -88,7 +84,8 @@
         for (TagMergeItem item: mergeItems) {
             if (! item.getMergeDecision().equals(MergeDecisionType.UNDECIDED)) {
-                item.applyToMyPrimitive(my);
+                item.applyToMyPrimitive(conflict.getMy());
             }
         }
+        rememberConflict(conflict);
         return true;
     }
@@ -97,18 +94,5 @@
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        modified.add(my);
-    }
-
-    @Override
-    public void undoCommand() {
-        // restore former state of modified primitives
-        //
-        super.undoCommand();
-
-        // restore a conflict if necessary
-        //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.addConflict(my, their);
-        }
+        modified.add(conflict.getMy());
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java	(revision 1750)
@@ -6,6 +6,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.logging.Logger;
 
 import javax.swing.JLabel;
@@ -15,21 +14,21 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
- * Represents a command for undeleting a node which was deleted on the server.
+ * Represents a command for undeleting an {@see OsmPrimitive} which was deleted on the server.
  * The command remembers the former node id and sets the node id to 0. This turns
  * the node into a new node which can be uploaded to the server.
  *
  */
-public class UndeletePrimitivesCommand extends Command {
+public class UndeletePrimitivesCommand extends ConflictResolveCommand {
+    static private final Logger logger = Logger.getLogger(UndeletePrimitivesCommand.class.getName());
 
     /** the node to undelete */
     private ArrayList<OsmPrimitive> toUndelete;
-    private Map<OsmPrimitive,OsmPrimitive> resolvedConflicts;
 
     protected UndeletePrimitivesCommand() {
         toUndelete = new ArrayList<OsmPrimitive>();
-        resolvedConflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
     }
     /**
@@ -77,8 +76,9 @@
     public boolean executeCommand() {
         super.executeCommand();
+
         for(OsmPrimitive primitive: toUndelete) {
-            if (Main.map.conflictDialog.conflicts.containsKey(primitive)) {
-                resolvedConflicts.put(primitive, Main.map.conflictDialog.conflicts.get(primitive));
-                Main.map.conflictDialog.removeConflictForPrimitive(primitive);
+            if(getLayer().getConflicts().hasConflictForMy(primitive)) {
+                rememberConflict(getLayer().getConflicts().getConflictForMy(primitive));
+                getLayer().getConflicts().remove(primitive);
             }
             primitive.id = 0;
@@ -92,13 +92,3 @@
         modified.addAll(toUndelete);
     }
-    @Override
-    public void undoCommand() {
-        super.undoCommand();
-
-        for (OsmPrimitive my: resolvedConflicts.keySet()) {
-            if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-                Main.map.conflictDialog.addConflict(my, resolvedConflicts.get(my));
-            }
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java	(revision 1750)
@@ -10,5 +10,5 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
@@ -20,8 +20,8 @@
  *
  */
-public class VersionConflictResolveCommand extends Command {
+public class VersionConflictResolveCommand extends ConflictResolveCommand {
 
-    private final OsmPrimitive my;
-    private final OsmPrimitive their;
+    /** the conflict to resolve */
+    private Conflict<OsmPrimitive> conflict;
 
     /**
@@ -31,6 +31,5 @@
      */
     public VersionConflictResolveCommand(OsmPrimitive my, OsmPrimitive their) {
-        this.my = my;
-        this.their = their;
+        conflict = new Conflict<OsmPrimitive>(my, their);
     }
 
@@ -39,5 +38,5 @@
         return new DefaultMutableTreeNode(
                 new JLabel(
-                        tr("Resolve version conflicts for {0} {1}",OsmPrimitiveType.from(my).getLocalizedDisplayNameSingular(), my.id),
+                        tr("Resolve version conflicts for {0} {1}",OsmPrimitiveType.from(conflict.getMy()).getLocalizedDisplayNameSingular(),conflict.getMy().id),
                         ImageProvider.get("data", "object"),
                         JLabel.HORIZONTAL
@@ -49,6 +48,7 @@
     public boolean executeCommand() {
         super.executeCommand();
-        my.version = Math.max(my.version, their.version);
-        Main.map.conflictDialog.removeConflictForPrimitive(my);
+        conflict.getMy().version = Math.max(conflict.getMy().version, conflict.getTheir().version);
+        getLayer().getConflicts().remove(conflict);
+        rememberConflict(conflict);
         return true;
     }
@@ -57,16 +57,5 @@
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        modified.add(my);
-    }
-
-    @Override
-    public void undoCommand() {
-        super.undoCommand();
-
-        // restore a conflict if necessary
-        //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.addConflict(my, their);
-        }
+        modified.add(conflict.getMy());
     }
 }
Index: trunk/src/org/openstreetmap/josm/command/WayNodesConflictResolverCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/WayNodesConflictResolverCommand.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/command/WayNodesConflictResolverCommand.java	(revision 1750)
@@ -6,4 +6,5 @@
 import java.util.Collection;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.swing.JLabel;
@@ -11,5 +12,5 @@
 import javax.swing.tree.MutableTreeNode;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -22,14 +23,16 @@
  *
  */
-public class WayNodesConflictResolverCommand extends Command {
+public class WayNodesConflictResolverCommand extends ConflictResolveCommand {
 
-    /** my way */
-    private final Way my;
-    /** their way */
-    private final Way their;
+    static private final Logger logger = Logger.getLogger(WayNodesConflictResolverCommand.class.getName());
+
+    /** the conflict to resolve */
+    private Conflict<Way> conflict;
+
     /** the list of merged nodes. This becomes the list of news of my way after the
      *  command is executed
      */
     private final List<Node> mergedNodeList;
+
 
     /**
@@ -40,6 +43,5 @@
      */
     public WayNodesConflictResolverCommand(Way my, Way their, List<Node> mergedNodeList) {
-        this.my = my;
-        this.their = their;
+        conflict = new Conflict<Way>(my,their);
         this.mergedNodeList = mergedNodeList;
     }
@@ -50,5 +52,5 @@
         return new DefaultMutableTreeNode(
                 new JLabel(
-                        tr("Resolve conflicts in node list of of way {0}", my.id),
+                        tr("Resolve conflicts in node list of of way {0}", conflict.getMy().id),
                         ImageProvider.get("data", "object"),
                         JLabel.HORIZONTAL
@@ -66,12 +68,13 @@
         // nodes
         //
-        my.nodes.clear();
+        conflict.getMy().nodes.clear();
         for (int i=0; i<mergedNodeList.size();i++) {
             Node n = mergedNodeList.get(i);
-            my.nodes.add(n);
-            if (! Main.ds.nodes.contains(n)) {
-                System.out.println("Main.ds doesn't include node " + n.toString());
+            conflict.getMy().nodes.add(n);
+            if (! getLayer().data.nodes.contains(n)) {
+                logger.warning(tr("Main.ds doesn't include node {0}", n.toString()));
             }
         }
+        rememberConflict(conflict);
         return true;
     }
@@ -80,18 +83,5 @@
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
             Collection<OsmPrimitive> added) {
-        modified.add(my);
-    }
-
-    @Override
-    public void undoCommand() {
-        // restore the former state
-        //
-        super.undoCommand();
-
-        // restore a conflict if necessary
-        //
-        if (!Main.map.conflictDialog.conflicts.containsKey(my)) {
-            Main.map.conflictDialog.addConflict(my, their);
-        }
+        modified.add(conflict.getMy());
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/conflict/Conflict.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/conflict/Conflict.java	(revision 1750)
+++ trunk/src/org/openstreetmap/josm/data/conflict/Conflict.java	(revision 1750)
@@ -0,0 +1,68 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.conflict;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+/**
+ * Represents a conflict between two {@see OsmPrimitive}s. It is represented as
+ * a pair if {@see OsmPrimitive} where one element of the pair has the role <em>my</em>
+ * and the other has the role <em>their</em>.
+ * <ul>
+ *   <li><code>my</code> is the {@see OsmPrimitive} in the local dataset</li>
+ *   <li><code>their</code> is the {@see OsmPrimitive} which caused the conflict when it
+ *   it was tried to merge it onto <code>my</code>. <code>their</code> is usually the
+ *   {@see OsmPrimitive} from the dataset in another layer or the one retrieved from the server.</li>
+ * </ul>
+ * 
+ *
+ */
+public class  Conflict<T extends OsmPrimitive> {
+    private T my;
+    private T their;
+
+    public Conflict(T my, T their) {
+        this.my = my;
+        this.their = their;
+    }
+
+    public T getMy() {
+        return my;
+    }
+
+    public T getTheir() {
+        return their;
+    }
+
+    public boolean isMatchingMy(OsmPrimitive my) {
+        return this.my == my;
+    }
+
+    public boolean isMatchingTheir(OsmPrimitive their) {
+        return this.their == their;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((my == null) ? 0 : my.hashCode());
+        result = prime * result + ((their == null) ? 0 : their.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Conflict<T> other = (Conflict) obj;
+        if (my != other.my)
+            return false;
+        if(their != other.their)
+            return false;
+        return true;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java	(revision 1750)
+++ trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java	(revision 1750)
@@ -0,0 +1,311 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.conflict;
+
+import java.util.ArrayList;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+/**
+ * This is a collection of {@see Conflict}s. This collection is {@see Iterable}, i.e.
+ * it can be used in <code>for</code>-loops as follows:
+ * <pre>
+ *    ConflictCollection conflictCollection = ....
+ * 
+ *    for(Conflict c : conflictCollection) {
+ *      // do something
+ *    }
+ * </pre>
+ *
+ * This collection emits an event when the content of the collection changes. You can register
+ * and unregister for these events using:
+ * <ul>
+ *   <li>{@see #addConflictListener(IConflictListener)}</li>
+ *   <li>{@see #removeConflictListener(IConflictListener)}</li>
+ * </ul>
+ */
+public class ConflictCollection implements Iterable<Conflict<?>>{
+    private ArrayList<Conflict<?>> conflicts;
+    private CopyOnWriteArrayList<IConflictListener> listeners;
+
+    public ConflictCollection() {
+        conflicts = new ArrayList<Conflict<?>>();
+        listeners = new CopyOnWriteArrayList<IConflictListener>();
+    }
+
+    public void addConflictListener(IConflictListener listener) {
+        if (listener != null && ! listeners.contains(listener)) {
+            listeners.add(listener);
+        }
+    }
+
+    public void removeConflictListener(IConflictListener listener) {
+        if (listener != null) {
+            listeners.remove(listener);
+        }
+    }
+
+    protected void fireConflictAdded() {
+        Iterator<IConflictListener> it = listeners.iterator();
+        while(it.hasNext()) {
+            it.next().onConflictsAdded(this);
+        }
+    }
+
+    protected void fireConflictRemoved() {
+        Iterator<IConflictListener> it = listeners.iterator();
+        while(it.hasNext()) {
+            it.next().onConflictsRemoved(this);
+        }
+    }
+
+    protected void addConflict(Conflict<?> conflict) {
+        if (hasConflictForMy(conflict.getMy()))
+            throw new IllegalStateException(tr("already registered a conflict for primitive ''{0}''", conflict.getMy().toString()));
+        if (!conflicts.contains(conflict)) {
+            conflicts.add(conflict);
+        }
+    }
+
+    /**
+     * Adds a conflict to the collection of conflicts.
+     * 
+     * @param conflict the conflict to to add. Must not be null.
+     * @throws IllegalArgumentException thrown, if conflict is null
+     * @throws IllegalStateException thrown if this collection already includes a conflict for conflict.getMy()
+     * 
+     */
+    public void add(Conflict<?> conflict) throws IllegalStateException, IllegalArgumentException {
+        if (conflict == null)
+            throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "conflict"));
+        addConflict(conflict);
+        fireConflictAdded();
+    }
+
+    /**
+     * Add the conflicts in <code>otherConflicts</code> to this collection of conflicts
+     * 
+     * @param otherConflicts the collection of conflicts. Does nothing is conflicts is null.
+     */
+    public void add(Collection<Conflict<?>> otherConflicts) {
+        if (otherConflicts == null) return;
+        for(Conflict<?> c : otherConflicts) {
+            addConflict(c);
+        }
+        fireConflictAdded();
+    }
+
+    /**
+     * Adds a conflict for the pair of {@see OsmPrimitive}s given by <code>my</code> and
+     * <code>their</code>.
+     * 
+     * @param my  my primitive
+     * @param their their primitive
+     */
+    public void add(OsmPrimitive my, OsmPrimitive their) {
+        addConflict(new Conflict<OsmPrimitive>(my, their));
+        fireConflictAdded();
+    }
+
+    /**
+     * removes a conflict from this collection
+     * 
+     * @param conflict the conflict
+     */
+    public void remove(Conflict<?> conflict) {
+        conflicts.remove(conflict);
+        fireConflictRemoved();
+    }
+
+    /**
+     * removes the conflict registered for {@see OsmPrimitive} <code>my</code> if any
+     * 
+     * @param my  the primitive
+     */
+    public void remove(OsmPrimitive my) {
+        Iterator<Conflict<?>> it = iterator();
+        while(it.hasNext()) {
+            if (it.next().isMatchingMy(my)) {
+                it.remove();
+            }
+        }
+        fireConflictRemoved();
+    }
+
+    /**
+     * Replies the conflict for the {@see OsmPrimitive} <code>my</code>, null
+     * if no such conflict exists.
+     * 
+     * @param my  my primitive
+     * @return the conflict for the {@see OsmPrimitive} <code>my</code>, null
+     * if no such conflict exists.
+     */
+    public Conflict<?> getConflictForMy(OsmPrimitive my) {
+        for(Conflict<?> c : conflicts) {
+            if (c.isMatchingMy(my))
+                return c;
+        }
+        return null;
+    }
+    /**
+     * Replies the conflict for the {@see OsmPrimitive} <code>their</code>, null
+     * if no such conflict exists.
+     * 
+     * @param my  my primitive
+     * @return the conflict for the {@see OsmPrimitive} <code>their</code>, null
+     * if no such conflict exists.
+     */
+    public Conflict<?> getConflictForTheir(OsmPrimitive their) {
+        for(Conflict<?> c : conflicts) {
+            if (c.isMatchingTheir(their))
+                return c;
+        }
+        return null;
+    }
+
+    /**
+     * Replies true, if this collection includes a conflict for <code>my</code>.
+     * 
+     * @param my my primitive
+     * @return true, if this collection includes a conflict for <code>my</code>; false, otherwise
+     */
+    public boolean hasConflictForMy(OsmPrimitive my) {
+        return getConflictForMy(my) != null;
+    }
+
+    /**
+     * Replies true, if this collection includes a given conflict
+     * 
+     * @param c the conflict
+     * @return true, if this collection includes the conflict; false, otherwise
+     */
+    public boolean hasConflict(Conflict<?> c) {
+        return hasConflictForMy(c.getMy());
+    }
+
+    /**
+     * Replies true, if this collection includes a conflict for <code>their</code>.
+     * 
+     * @param their their primitive
+     * @return true, if this collection includes a conflict for <code>their</code>; false, otherwise
+     */
+    public boolean hasConflictForTheir(OsmPrimitive their) {
+        return getConflictForTheir(their)  != null;
+    }
+
+    /**
+     * Removes any conflicts for the {@see OsmPrimitive} <code>my</code>.
+     * 
+     * @param my the primitive
+     */
+    public void removeForMy(OsmPrimitive my) {
+        Iterator<Conflict<?>> it = iterator();
+        while(it.hasNext()) {
+            if (it.next().isMatchingMy(my)) {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * Removes any conflicts for the {@see OsmPrimitive} <code>their</code>.
+     * 
+     * @param their the primitive
+     */
+    public void removeForTheir(OsmPrimitive their) {
+        Iterator<Conflict<?>> it = iterator();
+        while(it.hasNext()) {
+            if (it.next().isMatchingTheir(their)) {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * Replies the conflicts as list.
+     * 
+     * @return the list of conflicts
+     */
+    public List<Conflict<?>> get() {
+        return conflicts;
+    }
+
+    /**
+     * Replies the size of the collection
+     * 
+     * @return the size of the collection
+     */
+    public int size() {
+        return conflicts.size();
+    }
+
+    /**
+     * Replies the conflict at position <code>idx</code>
+     * 
+     * @param idx  the index
+     * @return the conflict at position <code>idx</code>
+     */
+    public Conflict<?> get(int idx) {
+        return conflicts.get(idx);
+    }
+
+    /**
+     * Replies the iterator for this collection.
+     * 
+     * @return the iterator
+     */
+    public Iterator<Conflict<?>> iterator() {
+        return conflicts.iterator();
+    }
+
+    public void add(ConflictCollection other) {
+        for (Conflict<?> c : other) {
+            add(c);
+        }
+    }
+
+    /**
+     * Replies the set of  {@see OsmPrimitive} which participate in the role
+     * of "my" in the conflicts managed by this collection.
+     * 
+     * @return the set of  {@see OsmPrimitive} which participate in the role
+     * of "my" in the conflicts managed by this collection.
+     */
+    public Set<OsmPrimitive> getMyConflictParties() {
+        HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>();
+        for (Conflict<?> c: conflicts) {
+            ret.add(c.getMy());
+        }
+        return ret;
+    }
+    /**
+     * Replies the set of  {@see OsmPrimitive} which participate in the role
+     * of "their" in the conflicts managed by this collection.
+     * 
+     * @return the set of  {@see OsmPrimitive} which participate in the role
+     * of "their" in the conflicts managed by this collection.
+     */
+    public Set<OsmPrimitive> getTheirConflictParties() {
+        HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>();
+        for (Conflict<?> c: conflicts) {
+            ret.add(c.getTheir());
+        }
+        return ret;
+    }
+
+    /**
+     * Replies true if this collection is empty
+     * 
+     * @return true, if this collection is empty; false, otherwise
+     */
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/conflict/IConflictListener.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/conflict/IConflictListener.java	(revision 1750)
+++ trunk/src/org/openstreetmap/josm/data/conflict/IConflictListener.java	(revision 1750)
@@ -0,0 +1,7 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.conflict;
+
+public interface IConflictListener {
+    public void onConflictsAdded(ConflictCollection conflicts);
+    public void onConflictsRemoved(ConflictCollection conflicts);
+}
Index: trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 1750)
@@ -5,11 +5,9 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.coor.LatLon.CoordinateFormat;
-import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
-import org.openstreetmap.josm.data.osm.Node;
 
 /**
@@ -25,8 +23,9 @@
         if(coor != null)
         {
-            if(this.coor == null)
+            if(this.coor == null) {
                 this.coor = new CachedLatLon(coor);
-            else
+            } else {
                 this.coor.setCoor(coor);
+            }
         }
     }
@@ -39,8 +38,9 @@
         if(eastNorth != null)
         {
-            if(coor != null)
+            if(coor != null) {
                 coor.setEastNorth(eastNorth);
-            else
+            } else {
                 coor = new CachedLatLon(eastNorth);
+            }
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 1750)
@@ -10,4 +10,5 @@
 import java.util.logging.Logger;
 
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -31,5 +32,6 @@
      * round than merged)
      */
-    private Map<OsmPrimitive, OsmPrimitive> conflicts;
+    private ConflictCollection conflicts;
+
 
     private final DataSet myDataSet;
@@ -68,5 +70,5 @@
             relshash.put(r.id, r);
         }
-        conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
+        conflicts = new ConflictCollection();
         merged = new HashMap<OsmPrimitive, OsmPrimitive>();
     }
@@ -113,5 +115,5 @@
                         // differences in deleted state have to be merged manually
                         //
-                        conflicts.put(my, other);
+                        conflicts.add(my, other);
                     } else {
                         // copy the technical attributes from other
@@ -158,5 +160,5 @@
             fixRelation(r);
         }
-        for (OsmPrimitive osm : conflicts.values())
+        for (OsmPrimitive osm : conflicts.getMyConflictParties())
             if (osm instanceof Way) {
                 fixWay((Way)osm);
@@ -235,5 +237,5 @@
                     // because it was deleted on the server.
                     //
-                    conflicts.put(my,other);
+                    conflicts.add(my,other);
                 } else if (my.incomplete) {
                     // my is incomplete, other completes it
@@ -250,5 +252,5 @@
                     // differences in deleted state have to be resolved manually
                     //
-                    conflicts.put(my,other);
+                    conflicts.add(my,other);
                 } else if (! my.modified && other.modified) {
                     // my not modified. We can assume that other is the most recent version.
@@ -278,5 +280,5 @@
                     // resolve the differences
                     // =>  create a conflict
-                    conflicts.put(my,other);
+                    conflicts.add(my,other);
                 } else {
                     // clone from other, but keep the modified flag. Clone will mainly copy
@@ -326,5 +328,5 @@
      * @return the map of conflicts
      */
-    public Map<OsmPrimitive, OsmPrimitive> getConflicts() {
+    public ConflictCollection getConflicts() {
         return conflicts;
     }
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 1750)
@@ -9,13 +9,13 @@
 import java.awt.Graphics2D;
 import java.awt.Point;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseMotionListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.LinkedList;
 
@@ -27,16 +27,12 @@
 import org.openstreetmap.josm.actions.AutoScaleAction;
 import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.actions.MoveAction;
 import org.openstreetmap.josm.actions.mapmode.MapMode;
-import org.openstreetmap.josm.actions.MoveAction;
-import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DataSource;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
-import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
@@ -61,4 +57,5 @@
 public class MapView extends NavigatableComponent {
 
+
     /**
      * A list of all layers currently loaded.
@@ -69,8 +66,5 @@
      */
     public PlayHeadMarker playHeadMarker = null;
-    /**
-     * Direct link to the edit layer (if any) in the layers list.
-     */
-    public OsmDataLayer editLayer;
+
     /**
      * The layer from the layers list that is currently active.
@@ -100,6 +94,7 @@
                 scaler.setLocation(10,30);
 
-                if (!zoomToEditLayerBoundingBox())
+                if (!zoomToEditLayerBoundingBox()) {
                     new AutoScaleAction("data").actionPerformed(null);
+                }
 
                 new MapMover(MapView.this, Main.contentPane);
@@ -152,28 +147,32 @@
     public void addLayer(Layer layer) {
         if (layer instanceof OsmDataLayer) {
-            editLayer = (OsmDataLayer)layer;
+            OsmDataLayer editLayer = (OsmDataLayer)layer;
             Main.ds = editLayer.data;
             editLayer.listenerModified.add(new ModifiedChangedListener(){
                 public void modifiedChanged(boolean value, OsmDataLayer source) {
                     JOptionPane.getFrameForComponent(Main.parent).setTitle((value?"*":"")
-                    +tr("Java OpenStreetMap Editor"));
+                            +tr("Java OpenStreetMap Editor"));
                 }
             });
         }
-        if (layer instanceof MarkerLayer && playHeadMarker == null)
+        if (layer instanceof MarkerLayer && playHeadMarker == null) {
             playHeadMarker = PlayHeadMarker.create();
+        }
         int pos = layers.size();
-        while(pos > 0 && layers.get(pos-1).background)
+        while(pos > 0 && layers.get(pos-1).background) {
             --pos;
+        }
         layers.add(pos, layer);
 
-        for (Layer.LayerChangeListener l : Layer.listeners)
+        for (Layer.LayerChangeListener l : Layer.listeners) {
             l.layerAdded(layer);
+        }
         if (layer instanceof OsmDataLayer || activeLayer == null) {
             // autoselect the new layer
             Layer old = activeLayer;
             setActiveLayer(layer);
-            for (Layer.LayerChangeListener l : Layer.listeners)
+            for (Layer.LayerChangeListener l : Layer.listeners) {
                 l.activeLayerChange(old, layer);
+            }
         }
         AudioPlayer.reset();
@@ -182,6 +181,5 @@
 
     @Override
-    protected DataSet getData()
-    {
+    protected DataSet getData() {
         if(activeLayer != null && activeLayer instanceof OsmDataLayer)
             return ((OsmDataLayer)activeLayer).data;
@@ -189,11 +187,20 @@
     }
 
-    public Boolean isDrawableLayer()
-    {
+    /**
+     * Replies true if the active layer is drawable.
+     * 
+     * @return true if the active layer is drawable, false otherwise
+     */
+    public boolean isActiveLayerDrawable() {
         return activeLayer != null && activeLayer instanceof OsmDataLayer;
     }
 
-    public Boolean isVisibleDrawableLayer() {
-        return isDrawableLayer() && activeLayer.visible;
+    /**
+     * Replies true if the active layer is visible.
+     * 
+     * @return true if the active layer is visible, false otherwise
+     */
+    public boolean isActiveLayerVisible() {
+        return isActiveLayerDrawable() && activeLayer.visible;
     }
 
@@ -204,10 +211,12 @@
     public void removeLayer(Layer layer) {
         if (layers.remove(layer)) {
-            for (Layer.LayerChangeListener l : Layer.listeners)
+            for (Layer.LayerChangeListener l : Layer.listeners) {
                 l.layerRemoved(layer);
-        }
-        if (layer == editLayer) {
-            editLayer = null;
-            Main.ds.setSelected();
+            }
+        }
+        if (layer == activeLayer) {
+            if (layer instanceof OsmDataLayer) {
+                Main.ds.setSelected();
+            }
         }
         layer.destroy();
@@ -215,16 +224,13 @@
     }
 
-    private Boolean virtualnodes = false;
-    public void enableVirtualNodes(Boolean state)
-    {
-        if(virtualnodes != state)
-        {
-            virtualnodes = state;
+    private boolean virtualNodesEnabled = false;
+    public void setVirtualNodesEnabled(boolean enabled) {
+        if(virtualNodesEnabled != enabled) {
+            virtualNodesEnabled = enabled;
             repaint();
         }
     }
-    public Boolean useVirtualNodes()
-    {
-        return virtualnodes;
+    public boolean isVirtualNodesEnabled() {
+        return virtualNodesEnabled;
     }
 
@@ -241,8 +247,9 @@
             return; // already in place.
         layers.remove(curLayerPos);
-        if (pos >= layers.size())
+        if (pos >= layers.size()) {
             layers.add(layer);
-        else
+        } else {
             layers.add(pos, layer);
+        }
         AudioPlayer.reset();
     }
@@ -266,7 +273,8 @@
         // just re-use it.
         if (null == offscreenBuffer || offscreenBuffer.getWidth() != getWidth()
-                || offscreenBuffer.getHeight() != getHeight())
+                || offscreenBuffer.getHeight() != getHeight()) {
             offscreenBuffer = new BufferedImage(getWidth(), getHeight(),
                     BufferedImage.TYPE_INT_ARGB);
+        }
 
         Graphics2D tempG = offscreenBuffer.createGraphics();
@@ -276,6 +284,7 @@
         for (int i = layers.size()-1; i >= 0; --i) {
             Layer l = layers.get(i);
-            if (l.visible/* && l != getActiveLayer()*/)
+            if (l.visible/* && l != getActiveLayer()*/) {
                 l.paint(tempG, this);
+            }
         }
 
@@ -296,9 +305,11 @@
         int x2 = Math.max(min.x, max.x);
         int y2 = Math.max(min.y, max.y);
-        if (x1 > 0 || y1 > 0 || x2 < getWidth() || y2 < getHeight())
+        if (x1 > 0 || y1 > 0 || x2 < getWidth() || y2 < getHeight()) {
             tempG.drawRect(x1, y1, x2-x1+1, y2-y1+1);
-
-        if (playHeadMarker != null)
+        }
+
+        if (playHeadMarker != null) {
             playHeadMarker.paint(tempG, this);
+        }
 
         g.drawImage(offscreenBuffer, 0, 0, null);
@@ -310,10 +321,13 @@
      */
     public void recalculateCenterScale(BoundingXYVisitor box) {
-        if(box == null)
+        if(box == null) {
             box = new BoundingXYVisitor();
-        if(box.getBounds() == null)
+        }
+        if(box.getBounds() == null) {
             box.visit(getProjection().getWorldBounds());
-        if(!box.hasExtend())
-             box.enlargeBoundingBox();
+        }
+        if(!box.hasExtend()) {
+            box.enlargeBoundingBox();
+        }
 
         zoomTo(box.getBounds());
@@ -321,5 +335,5 @@
 
     /**
-     * @return An unmodificable list of all layers
+     * @return An unmodifiable collection of all layers
      */
     public Collection<Layer> getAllLayers() {
@@ -328,21 +342,26 @@
 
     /**
-     * Set the active selection to the given value and raise an layerchange event.
+     * Sets the active layer to <code>layer</code>. If <code>layer</code> is an instance
+     * of {@see OsmDataLayer} also sets {@see #editLayer} to <code>layer</code>.
+     * 
+     * @param layer the layer to be activate; must be one of the layers in the list of layers
+     * @exception IllegalArgumentException thrown if layer is not in the lis of layers
      */
     public void setActiveLayer(Layer layer) {
         if (!layers.contains(layer))
-            throw new IllegalArgumentException("Layer must be in layerlist");
+            throw new IllegalArgumentException(tr("Layer {0} must be in list of layers", layer.toString()));
         if (layer instanceof OsmDataLayer) {
-            editLayer = (OsmDataLayer)layer;
+            OsmDataLayer editLayer = (OsmDataLayer)layer;
             Main.ds = editLayer.data;
-        }
-        else
+        } else {
             Main.ds.setSelected();
+        }
         DataSet.fireSelectionChanged(Main.ds.getSelected());
         Layer old = activeLayer;
         activeLayer = layer;
         if (old != layer) {
-            for (Layer.LayerChangeListener l : Layer.listeners)
+            for (Layer.LayerChangeListener l : Layer.listeners) {
                 l.activeLayerChange(old, layer);
+            }
         }
 
@@ -360,8 +379,31 @@
 
     /**
-     * @return The current active layer
+     * Replies the currently active layer
+     * 
+     * @return the currently active layer (may be null)
      */
     public Layer getActiveLayer() {
         return activeLayer;
+    }
+
+    /**
+     * Replies the current edit layer, if any
+     * 
+     * @return the current edit layer. May be null.
+     */
+    public OsmDataLayer getEditLayer() {
+        if (activeLayer instanceof OsmDataLayer)
+            return (OsmDataLayer)activeLayer;
+        return null;
+    }
+
+    /**
+     * replies true if the list of layers managed by this map view contain layer
+     * 
+     * @param layer the layer
+     * @return true if the list of layers managed by this map view contain layer
+     */
+    public boolean hasLayer(Layer layer) {
+        return layers.contains(layer);
     }
 
@@ -377,5 +419,5 @@
         // workaround for #1461 (zoom to download bounding box instead of all data)
         // In case we already have an existing data layer ...
-        Collection<DataSource> dataSources = Main.main.editLayer().data.dataSources;
+        Collection<DataSource> dataSources = Main.main.createOrGetEditLayer().data.dataSources;
         // ... with bounding box[es] of data loaded from OSM or a file...
         BoundingXYVisitor bbox = new BoundingXYVisitor();
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/CommandStackDialog.java	(revision 1750)
@@ -29,5 +29,5 @@
     public CommandStackDialog(final MapFrame mapFrame) {
         super(tr("Command Stack"), "commandstack", tr("Open a list of all commands (undo buffer)."),
-        Shortcut.registerShortcut("subwindow:commandstack", tr("Toggle: {0}", tr("Command Stack")), KeyEvent.VK_O, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 100);
+                Shortcut.registerShortcut("subwindow:commandstack", tr("Toggle: {0}", tr("Command Stack")), KeyEvent.VK_O, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 100);
         Main.main.undoRedo.listenerCommands.add(this);
 
@@ -52,8 +52,9 @@
 
     @Override public void setVisible(boolean v) {
-        if (v)
+        if (v) {
             buildList();
-        else if (tree != null)
+        } else if (tree != null) {
             treeModel.setRoot(new DefaultMutableTreeNode());
+        }
         super.setVisible(v);
     }
@@ -65,10 +66,11 @@
             setTitle(tr("Command Stack"), false);
         }
-        if (Main.map == null || Main.map.mapView == null || Main.map.mapView.editLayer == null)
+        if (Main.map == null || Main.map.mapView == null || Main.map.mapView.getEditLayer() == null)
             return;
         Collection<Command> commands = Main.main.undoRedo.commands;
         DefaultMutableTreeNode root = new DefaultMutableTreeNode();
-        for (Command c : commands)
+        for (Command c : commands) {
             root.add(c.description());
+        }
         treeModel.setRoot(root);
         tree.scrollRowToVisible(treeModel.getChildCount(root)-1);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 1750)
@@ -11,18 +11,21 @@
 import java.awt.Point;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.Map;
-
-import javax.swing.DefaultListModel;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
 import javax.swing.JList;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.ListModel;
 import javax.swing.ListSelectionModel;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
@@ -30,4 +33,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.conflict.Conflict;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
+import org.openstreetmap.josm.data.conflict.IConflictListener;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -40,36 +46,45 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
-import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Shortcut;
 
-public final class ConflictDialog extends ToggleDialog {
-
-    public final Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
-    private final DefaultListModel model = new DefaultListModel();
-    private final JList displaylist = new JList(model);
-
-    private final SideButton sbSelect = new SideButton(marktr("Select"), "select", "Conflict",
-            tr("Set the selected elements on the map to the selected items in the list above."), new ActionListener(){
-        public void actionPerformed(ActionEvent e) {
-            Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
-            for (Object o : displaylist.getSelectedValues()) {
-                sel.add((OsmPrimitive)o);
-            }
-            Main.ds.setSelected(sel);
-        }
-    });
-    private final SideButton sbResolve = new SideButton(marktr("Resolve"), "conflict", "Conflict",
-            tr("Open a merge dialog of all selected items in the list above."), new ActionListener(){
-        public void actionPerformed(ActionEvent e) {
-            resolve();
-        }
-    });
-
-    public ConflictDialog() {
-        super(tr("Conflict"), "conflict", tr("Merging conflicts."),
-                Shortcut.registerShortcut("subwindow:conflict", tr("Toggle: {0}", tr("Conflict")), KeyEvent.VK_C, Shortcut.GROUP_LAYER), 100);
-        displaylist.setCellRenderer(new OsmPrimitivRenderer());
-        displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-        displaylist.addMouseListener(new MouseAdapter(){
+/**
+ * This dialog displays the {@see ConflictCollection} of the active {@see OsmDataLayer} in a toggle
+ * dialog on the right of the main frame.
+ * 
+ */
+public final class ConflictDialog extends ToggleDialog implements LayerChangeListener, IConflictListener, SelectionChangedListener{
+
+    static public Color getColor() {
+        return Main.pref.getColor(marktr("conflict"), Color.gray);
+    }
+
+    /** the  collection of conflicts displayed by this conflict dialog*/
+    private ConflictCollection conflicts;
+
+    /** the model for the list of conflicts */
+    private ConflictListModel model;
+    /** the list widget for the list of conflicts */
+    private JList lstConflicts;
+
+    private ResolveAction actResolve;
+    private SelectAction actSelect;
+
+    private OsmDataLayer layer = null;
+
+
+    /**
+     * builds the GUI
+     */
+    protected void build() {
+        model = new ConflictListModel();
+
+        lstConflicts = new JList(model);
+        lstConflicts.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        lstConflicts.setCellRenderer(new OsmPrimitivRenderer());
+        lstConflicts.addMouseListener(new MouseAdapter(){
             @Override public void mouseClicked(MouseEvent e) {
                 if (e.getClickCount() >= 2) {
@@ -78,23 +93,5 @@
             }
         });
-        add(new JScrollPane(displaylist), BorderLayout.CENTER);
-
-        JPanel buttonPanel = new JPanel(new GridLayout(1,2));
-        buttonPanel.add(sbResolve);
-        buttonPanel.add(sbSelect);
-        add(buttonPanel, BorderLayout.SOUTH);
-
-        DataSet.selListeners.add(new SelectionChangedListener(){
-            public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-                displaylist.clearSelection();
-                for (OsmPrimitive osm : newSelection) {
-                    if (conflicts.containsKey(osm)) {
-                        int pos = model.indexOf(osm);
-                        displaylist.addSelectionInterval(pos, pos);
-                    }
-                }
-            }
-        });
-        displaylist.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
+        lstConflicts.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
             public void valueChanged(ListSelectionEvent e) {
                 Main.map.mapView.repaint();
@@ -102,21 +99,51 @@
         });
 
-        rebuildList();
-    }
-
+        add(new JScrollPane(lstConflicts), BorderLayout.CENTER);
+
+        JButton btnResolve = new JButton(actResolve = new ResolveAction());
+        lstConflicts.getSelectionModel().addListSelectionListener(actResolve);
+
+        JButton btnSelect = new JButton(actSelect = new SelectAction());
+        lstConflicts.getSelectionModel().addListSelectionListener(actSelect);
+
+        JPanel buttonPanel = new JPanel(new GridLayout(1,2));
+        buttonPanel.add(btnResolve);
+        buttonPanel.add(btnSelect);
+        add(buttonPanel, BorderLayout.SOUTH);
+    }
+
+    /**
+     * constructor
+     */
+    public ConflictDialog() {
+        super(tr("Conflict"), "conflict", tr("Merging conflicts."),
+                Shortcut.registerShortcut("subwindow:conflict", tr("Toggle: {0}", tr("Conflict")), KeyEvent.VK_C, Shortcut.GROUP_LAYER), 100);
+
+        build();
+        DataSet.selListeners.add(this);
+        Layer.listeners.add(this);
+        refreshView();
+    }
+
+    /**
+     * Launches a conflict resolution dialog for the first selected conflict
+     * 
+     */
     private final void resolve() {
-        if(model.size() == 1) {
-            displaylist.setSelectedIndex(0);
-        }
-
-        if (displaylist.getSelectedIndex() == -1)
+        if (conflicts == null) return;
+        if (conflicts.size() == 1) {
+            lstConflicts.setSelectedIndex(0);
+        }
+
+        if (lstConflicts.getSelectedIndex() == -1)
             return;
 
-        int [] selectedRows = displaylist.getSelectedIndices();
+        int [] selectedRows = lstConflicts.getSelectedIndices();
         if (selectedRows == null || selectedRows.length == 0)
             return;
         int row = selectedRows[0];
-        OsmPrimitive my = (OsmPrimitive)model.get(row);
-        OsmPrimitive their = conflicts.get(my);
+        Conflict c = conflicts.get(row);
+        OsmPrimitive my = c.getMy();
+        OsmPrimitive their = c.getTheir();
         ConflictResolutionDialog dialog = new ConflictResolutionDialog(Main.parent);
         dialog.getConflictResolver().populate(my, their);
@@ -125,57 +152,10 @@
     }
 
-    public final void rebuildList() {
-        model.removeAllElements();
-        for (OsmPrimitive osm : this.conflicts.keySet()) {
-            model.addElement(osm);
-        }
-
-        if(model.size() != 0) {
-            setTitle(tr("Conflicts: {0}", model.size()), true);
-        } else {
-            setTitle(tr("Conflicts"), false);
-        }
-
-        sbSelect.setEnabled(model.size() > 0);
-        sbResolve.setEnabled(model.size() > 0);
-    }
-
-    public final void add(Map<OsmPrimitive, OsmPrimitive> conflicts) {
-        this.conflicts.putAll(conflicts);
-        rebuildList();
-    }
-
-
-    /**
-     * removes a conflict registered for {@see OsmPrimitive} <code>my</code>
-     *
-     * @param my the {@see OsmPrimitive} for which a conflict is registered
-     *   with this dialog
-     */
-    public void removeConflictForPrimitive(OsmPrimitive my) {
-        if (! conflicts.keySet().contains(my))
-            return;
-        conflicts.remove(my);
-        rebuildList();
-        repaint();
-    }
-
-    /**
-     * registers a conflict with this dialog. The conflict is represented
-     * by a pair of {@see OsmPrimitive} with differences in their tag sets,
-     * their node lists (for {@see Way}s) or their member lists (for {@see Relation}s)
-     *
-     * @param my  my version of the {@see OsmPrimitive}
-     * @param their their version of the {@see OsmPrimitive}
-     */
-    public void addConflict(OsmPrimitive my, OsmPrimitive their) {
-        conflicts.put(my, their);
-        rebuildList();
-        repaint();
-    }
-
-    static public Color getColor()
-    {
-        return Main.pref.getColor(marktr("conflict"), Color.gray);
+
+    /**
+     * refreshes the view of this dialog
+     */
+    public final void refreshView() {
+        model.fireContentChanged();
     }
 
@@ -215,9 +195,170 @@
             }
         };
-        for (Object o : displaylist.getSelectedValues()) {
-            if (conflicts.get(o) == null) {
+        for (Object o : lstConflicts.getSelectedValues()) {
+            if (!conflicts.hasConflictForMy((OsmPrimitive)o)) {
                 continue;
             }
-            conflicts.get(o).visit(conflictPainter);
+            conflicts.getConflictForMy((OsmPrimitive)o).getTheir().visit(conflictPainter);
+        }
+    }
+
+
+    /**
+     * replies the conflict collection currently held by this dialog; may be null
+     * 
+     * @return the conflict collection currently held by this dialog; may be null
+     */
+    public ConflictCollection getConflicts() {
+        return conflicts;
+    }
+
+    /**
+     * invoked if the active {@see Layer} changes
+     */
+    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+        if (oldLayer instanceof OsmDataLayer) {
+            this.layer = (OsmDataLayer)oldLayer;
+            this.layer.getConflicts().removeConflictListener(this);
+        }
+        this.layer = null;
+        if (newLayer instanceof OsmDataLayer) {
+            this.layer = (OsmDataLayer)newLayer;
+            layer.getConflicts().addConflictListener(this);
+            this.conflicts = layer.getConflicts();
+        }
+        refreshView();
+    }
+
+    public void layerAdded(Layer newLayer) {
+        // ignore
+    }
+
+    public void layerRemoved(Layer oldLayer) {
+        if (this.layer == oldLayer) {
+            this.layer = null;
+            refreshView();
+        }
+    }
+
+    public void onConflictsAdded(ConflictCollection conflicts) {
+        refreshView();
+    }
+
+    public void onConflictsRemoved(ConflictCollection conflicts) {
+        refreshView();
+    }
+
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+        lstConflicts.clearSelection();
+        for (OsmPrimitive osm : newSelection) {
+            if (conflicts.hasConflictForMy(osm)) {
+                int pos = model.indexOf(osm);
+                if (pos >= 0) {
+                    lstConflicts.addSelectionInterval(pos, pos);
+                }
+            }
+        }
+    }
+
+    /**
+     * The {@see ListModel} for conflicts
+     *
+     */
+    class ConflictListModel implements ListModel {
+
+        private CopyOnWriteArrayList<ListDataListener> listeners;
+
+        public ConflictListModel() {
+            listeners = new CopyOnWriteArrayList<ListDataListener>();
+        }
+
+        public void addListDataListener(ListDataListener l) {
+            if (l != null && ! listeners.contains(l)) {
+                listeners.add(l);
+            }
+        }
+
+        public void removeListDataListener(ListDataListener l) {
+            listeners.remove(l);
+        }
+
+        protected void fireContentChanged() {
+            ListDataEvent evt = new ListDataEvent(
+                    this,
+                    ListDataEvent.CONTENTS_CHANGED,
+                    0,
+                    getSize()
+            );
+            Iterator<ListDataListener> it = listeners.iterator();
+            while(it.hasNext()) {
+                it.next().contentsChanged(evt);
+            }
+        }
+
+        public Object getElementAt(int index) {
+            if (index < 0) return null;
+            if (index >= getSize()) return null;
+            return conflicts.get(index).getMy();
+        }
+
+        public int getSize() {
+            if (conflicts == null) return 0;
+            return conflicts.size();
+        }
+
+        public int indexOf(OsmPrimitive my) {
+            if (conflicts == null) return -1;
+            for (int i=0; i < conflicts.size();i++) {
+                if (conflicts.get(i).isMatchingMy(my))
+                    return i;
+            }
+            return -1;
+        }
+
+        public OsmPrimitive get(int idx) {
+            if (conflicts == null) return null;
+            return conflicts.get(idx).getMy();
+        }
+    }
+
+    class ResolveAction extends AbstractAction implements ListSelectionListener {
+        public ResolveAction() {
+            putValue(NAME, tr("Resolve"));
+            putValue(SHORT_DESCRIPTION,  tr("Open a merge dialog of all selected items in the list above."));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "conflict"));
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            resolve();
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+            ListSelectionModel model = (ListSelectionModel)e.getSource();
+            boolean enabled = model.getMinSelectionIndex() >= 0
+            && model.getMaxSelectionIndex() >= model.getMinSelectionIndex();
+            setEnabled(enabled);
+        }
+    }
+
+    class SelectAction extends AbstractAction implements ListSelectionListener {
+        public SelectAction() {
+            putValue(NAME, tr("Select"));
+            putValue(SHORT_DESCRIPTION,  tr("Set the selected elements on the map to the selected items in the list above."));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "select"));
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+            for (Object o : lstConflicts.getSelectedValues()) {
+                sel.add((OsmPrimitive)o);
+            }
+            Main.ds.setSelected(sel);
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+            ListSelectionModel model = (ListSelectionModel)e.getSource();
+            boolean enabled = model.getMinSelectionIndex() >= 0
+            && model.getMaxSelectionIndex() >= model.getMinSelectionIndex();
+            setEnabled(enabled);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 1750)
@@ -48,4 +48,5 @@
 import org.openstreetmap.josm.gui.history.HistoryBrowserDialog;
 import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.io.OsmApiException;
 import org.openstreetmap.josm.io.OsmServerHistoryReader;
 import org.openstreetmap.josm.io.OsmTransferException;
@@ -233,5 +234,14 @@
         if (task.getLastException() != null) {
             task.getLastException().printStackTrace();
-            String msg = task.getLastException().getMessage();
+            String msg = null;
+            if (task.getLastException() instanceof OsmApiException) {
+                msg = ((OsmApiException)task.getLastException()).getErrorBody();
+                if (msg == null) {
+                    msg = ((OsmApiException)task.getLastException()).getErrorHeader();
+                }
+            }
+            if (msg == null) {
+                msg = task.getLastException().getMessage();
+            }
             if (msg == null) {
                 msg = task.getLastException().toString();
@@ -452,5 +462,5 @@
             } catch(OsmTransferException e) {
                 lastException = e;
-                throw e;
+                return;
             } finally {
                 setInterminateEnabled(false);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 1750)
@@ -53,12 +53,13 @@
 
         public void actionPerformed(ActionEvent e) {
-            if (e != null && !(e.getSource() instanceof AbstractButton))
+            if (e != null && !(e.getSource() instanceof AbstractButton)) {
                 button.setSelected(!button.isSelected());
+            }
             Boolean selected = button.isSelected();
             setVisible(selected);
             Main.pref.put(prefname+".visible", selected);
-            if(!selected && winadapter != null)
+            if(!selected && winadapter != null) {
                 winadapter.windowClosing(null);
-            else if (!Main.pref.getBoolean(action.prefname+".docked", true)) {
+            } else if (!Main.pref.getBoolean(action.prefname+".docked", true)) {
                 EventQueue.invokeLater(new Runnable(){
                     public void run() {
@@ -174,9 +175,11 @@
                         setVisible(false);
                         parent.add(ToggleDialog.this);
-                        if(Main.pref.getBoolean(action.prefname+".visible"))
+                        if(Main.pref.getBoolean(action.prefname+".visible")) {
                             setVisible(true);
+                        }
                         titleBar.setVisible(true);
-                        if(e != null)
+                        if(e != null) {
                             Main.pref.put(action.prefname+".docked", true);
+                        }
                     }
                 }));
@@ -190,6 +193,7 @@
                     String[] b = bounds.split(",");
                     f.setBounds(Integer.parseInt(b[0]),Integer.parseInt(b[1]),Integer.parseInt(b[2]),Integer.parseInt(b[3]));
-                } else
+                } else {
                     f.pack();
+                }
                 Main.pref.put(action.prefname+".docked", false);
                 f.setVisible(true);
@@ -241,6 +245,7 @@
     public void close()
     {
-        if(winadapter != null)
+        if(winadapter != null) {
             winadapter.windowClosing(null);
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 1750)
@@ -367,8 +367,6 @@
             RelationMember  m = clone.members.get(i);
             if (m.member.incomplete)
-            {
                 // TODO: emit some message that sorting failed
                 return;
-            }
             try
             {
@@ -765,18 +763,18 @@
                 DataSet dataSet = reader.parseOsm();
                 if (dataSet != null) {
-                    final MergeVisitor visitor = new MergeVisitor(Main.main
-                            .editLayer().data, dataSet);
+                    final MergeVisitor visitor = new MergeVisitor(Main.main.map.mapView.getEditLayer()
+                            .data, dataSet);
                     visitor.merge();
 
                     // copy the merged layer's data source info
                     for (DataSource src : dataSet.dataSources) {
-                        Main.main.editLayer().data.dataSources.add(src);
-                    }
-                    Main.main.editLayer().fireDataChange();
+                        Main.main.map.mapView.getEditLayer().data.dataSources.add(src);
+                    }
+                    Main.main.map.mapView.getEditLayer().fireDataChange();
 
                     if (visitor.getConflicts().isEmpty())
                         return;
                     final ConflictDialog dlg = Main.map.conflictDialog;
-                    dlg.add(visitor.getConflicts());
+                    dlg.getConflicts().add(visitor.getConflicts());
                     JOptionPane.showMessageDialog(Main.parent,
                             tr("There were conflicts during import."));
Index: trunk/src/org/openstreetmap/josm/gui/history/PointInTimeType.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/PointInTimeType.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/history/PointInTimeType.java	(revision 1750)
@@ -2,5 +2,4 @@
 package org.openstreetmap.josm.gui.history;
 
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
 /**
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1750)
@@ -19,5 +19,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.File;
@@ -42,4 +41,6 @@
 import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.actions.SaveAsAction;
+import org.openstreetmap.josm.data.conflict.Conflict;
+import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -60,5 +61,4 @@
 import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
 import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
@@ -74,4 +74,17 @@
  */
 public class OsmDataLayer extends Layer {
+
+    /** the global counter for created data layers */
+    static private int dataLayerCounter = 0;
+
+    /**
+     * Replies a new unique name for a data layer
+     * 
+     * @return a new unique name for a data layer
+     */
+    static public String createNewName() {
+        dataLayerCounter++;
+        return tr("Data Layer {0}", dataLayerCounter);
+    }
 
     public final static class DataCountVisitor extends AbstractVisitor {
@@ -114,4 +127,9 @@
      */
     public final DataSet data;
+
+    /**
+     * the collection of conflicts detected in this layer
+     */
+    private ConflictCollection conflicts;
 
     /**
@@ -159,4 +177,5 @@
         this.data = data;
         this.setAssociatedFile(associatedFile);
+        conflicts = new ConflictCollection();
     }
 
@@ -177,5 +196,5 @@
         boolean active = Main.map.mapView.getActiveLayer() == this;
         boolean inactive = !active && Main.pref.getBoolean("draw.data.inactive_color", true);
-        boolean virtual = !inactive && Main.map.mapView.useVirtualNodes();
+        boolean virtual = !inactive && Main.map.mapView.isVirtualNodesEnabled();
 
         // draw the hatched area for non-downloaded region. only draw if we're the active
@@ -271,11 +290,13 @@
         Main.map.mapView.repaint();
 
-        if (visitor.getConflicts().isEmpty())
-            return;
-        final ConflictDialog dlg = Main.map.conflictDialog;
-        dlg.add(visitor.getConflicts());
-        JOptionPane.showMessageDialog(Main.parent,tr("There were {0} conflicts during import.", visitor.getConflicts().size()));
-        if (!dlg.isVisible()) {
-            dlg.action.actionPerformed(new ActionEvent(this, 0, ""));
+        int numNewConflicts = 0;
+        for (Conflict c : visitor.getConflicts()) {
+            if (!conflicts.hasConflict(c)) {
+                numNewConflicts++;
+                conflicts.add(c);
+            }
+        }
+        if (numNewConflicts > 0) {
+            JOptionPane.showMessageDialog(Main.parent,tr("There were {0} conflicts during import.", numNewConflicts));
         }
     }
@@ -510,3 +531,12 @@
         return layer_bounds_point;
     }
+
+    /**
+     * replies the set of conflicts currently managed in this layer
+     * 
+     * @return the set of conflicts currently managed in this layer
+     */
+    public ConflictCollection getConflicts() {
+        return conflicts;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 1750)
@@ -330,4 +330,6 @@
             String diffresult = sendRequest("POST", "changeset/" + changeset.id + "/upload", diff);
             DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
+        } catch(OsmTransferException e) {
+            throw e;
         } catch(Exception e) {
             throw new OsmTransferException(e);
@@ -443,5 +445,5 @@
 
                 if (retCode != 200)
-                    throw new OsmApiException(retCode,errorHeader,responseBody.toString());
+                    throw new OsmApiException(retCode,errorHeader.trim(),responseBody.toString().trim());
 
                 return responseBody.toString();
Index: trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1749)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1750)
@@ -94,5 +94,5 @@
         boolean useChangeset = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0);
         if (useChangeset && ! canUseChangeset) {
-            System.out.println(tr("WARNING: preference ''{0}'' or api version ''{1}'' of dataset requires to use changesets, but API is not handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion));
+            System.out.println(tr("WARNING: preference ''{0}'' or api version ''{1}'' of dataset requires to use changesets, but API is not able to handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion));
             useChangeset = false;
         }
