Index: josm/plugins/conflation/.checkstyle
===================================================================
--- josm/plugins/conflation/.checkstyle	(nonexistent)
+++ josm/plugins/conflation/.checkstyle	(copie de travail)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <local-check-config name="JOSM" location="/JOSM/tools/checkstyle/josm_checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="JOSM" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="DerivedFiles" enabled="true"/>
+  <filter name="FilesFromPackage" enabled="true">
+    <filter-data value="src/com"/>
+  </filter>
+</fileset-config>
Index: josm/plugins/conflation/.project
===================================================================
--- josm/plugins/conflation/.project	(révision 130)
+++ josm/plugins/conflation/.project	(copie de travail)
@@ -15,8 +15,14 @@
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
 	</natures>
 </projectDescription>
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateMatchCommand.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateMatchCommand.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateMatchCommand.java	(copie de travail)
@@ -1,29 +1,39 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
-import java.util.ArrayList;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.stream.Collectors;
+
 import javax.swing.Icon;
+
 import org.openstreetmap.josm.command.AddPrimitivesCommand;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.PseudoCommand;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.PrimitiveData;
+import org.openstreetmap.josm.plugins.utilsplugin2.replacegeometry.ReplaceGeometryException;
 import org.openstreetmap.josm.plugins.utilsplugin2.replacegeometry.ReplaceGeometryUtils;
-import static org.openstreetmap.josm.tools.I18n.tr;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.UserCancelException;
 
+
 /**
  * Command to conflate one object with another.
  */
 public class ConflateMatchCommand extends Command {
+
+    private final DataSet sourceDataSet;
+    private final DataSet targetDataSet;
     private final SimpleMatch match;
     private final SimpleMatchList matches;
-    private final Command replaceCommand;
+    private Command replaceCommand = null;
     private AddPrimitivesCommand addPrimitivesCommand = null;
 
     public ConflateMatchCommand(SimpleMatch match,
@@ -31,53 +41,67 @@
         super(settings.getSubjectLayer());
         this.match = match;
         this.matches = matches;
-        
-        DataSet sourceDataSet = settings.getReferenceDataSet();
-        DataSet targetDataSet = settings.getSubjectDataSet();
-        // copy objects from reference dataset
-        if (targetDataSet != sourceDataSet) {
-            // TODO: use MergeCommand instead?
-            List<PrimitiveData> newObjects = ConflationUtils.copyObjects(sourceDataSet, match.getReferenceObject());
-
-            // FIXME: bad form to execute command in constructor, how to fix?
-            addPrimitivesCommand = new AddPrimitivesCommand(newObjects, newObjects, settings.getSubjectLayer());
-            if (!addPrimitivesCommand.executeCommand())
-                throw new AssertionError();
-        }
-
-        // need to copy from other layer before this?
-        replaceCommand = ReplaceGeometryUtils.buildReplaceCommand(
-                            match.getSubjectObject(),
-                            targetDataSet.getPrimitiveById(match.getReferenceObject().getPrimitiveId()));
-
-        if (addPrimitivesCommand != null)
-            addPrimitivesCommand.undoCommand();
-        if (replaceCommand == null) {
-            throw new UserCancelException();
-        }
+        this.sourceDataSet = settings.getReferenceDataSet();
+        this.targetDataSet = settings.getSubjectDataSet();
     }
 
     @Override
     public boolean executeCommand() {
-        if (addPrimitivesCommand != null) {
-            if (!addPrimitivesCommand.executeCommand())
-                return false;
+        boolean ok = true;
+        try {
+            if (targetDataSet != sourceDataSet) {
+                if (addPrimitivesCommand == null) {
+                    List<PrimitiveData> newObjects = ConflationUtils.copyObjects(sourceDataSet, match.getReferenceObject(), targetDataSet);
+                    addPrimitivesCommand = new AddPrimitivesCommand(newObjects, newObjects, getLayer());
+                }
+                if (!addPrimitivesCommand.executeCommand()) {
+                    ok = false;
+                    addPrimitivesCommand = null;
+                }
+            }
+            if (ok) {
+                if (replaceCommand == null) {
+                    replaceCommand = ReplaceGeometryUtils.buildReplaceCommand(
+                                        match.getSubjectObject(),
+                                        targetDataSet.getPrimitiveById(match.getReferenceObject().getPrimitiveId()));
+                    if (replaceCommand == null) {
+                        // Throwing an exception is the only way I found to be sure
+                        // the command is not added to the undo list.
+                        throw new ReplaceGeometryException(tr("Canceled"));
+                    }
+                }
+                if (replaceCommand.executeCommand()) {
+                    matches.remove(match);
+                } else {
+                    ok = false;
+                }
+            }
+        } catch (RuntimeException e) {
+            ok = false;
+            throw e;
+        } finally {
+            if (!ok) {
+                replaceCommand = null;
+                if (addPrimitivesCommand != null) {
+                    addPrimitivesCommand.undoCommand();
+                    addPrimitivesCommand = null;
+                }
+            }
         }
-        if (!replaceCommand.executeCommand())
-            return false;
-        matches.remove(match);
-
-        return true;
+        return ok;
     }
-    
+
     @Override
     public void undoCommand() {
-        replaceCommand.undoCommand();
-        if (addPrimitivesCommand != null)
+        if (replaceCommand != null) {
+            replaceCommand.undoCommand();
+            matches.add(match);
+        }
+        if (addPrimitivesCommand != null) {
             addPrimitivesCommand.undoCommand();
-        matches.add(match);
+        }
     }
-    
+
     @Override
     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
         throw new UnsupportedOperationException("Not supported yet.");
@@ -88,26 +112,26 @@
         //TODO: make more descriptive
         return tr("Conflate object pair");
     }
-    
+
     @Override
     public Icon getDescriptionIcon() {
         return ImageProvider.get("dialogs", "conflation");
     }
-    
+
     @Override
     public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
-        return Collections.singleton(match.getSubjectObject());
+        Collection<OsmPrimitive> prims = new HashSet<>();
+        if (addPrimitivesCommand != null)
+            prims.addAll(addPrimitivesCommand.getParticipatingPrimitives());
+        if (replaceCommand != null)
+            prims.addAll(replaceCommand.getParticipatingPrimitives());
+        return prims;
     }
-    
+
     @Override
     public Collection<PseudoCommand> getChildren() {
-        if (replaceCommand == null)
-            return null;
-
-        Collection<PseudoCommand> children = new ArrayList<>();
-        if (addPrimitivesCommand != null)
-            children.add(addPrimitivesCommand);
-        children.addAll(replaceCommand.getChildren());
-        return children;
+        return Arrays.asList(addPrimitivesCommand, replaceCommand).stream()
+            .filter(c -> c != null)
+            .collect(Collectors.toList());
     }
 }
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateUnmatchedObjectCommand.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateUnmatchedObjectCommand.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflateUnmatchedObjectCommand.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import java.util.ArrayList;
@@ -29,7 +30,7 @@
         this.unmatchedObjects = unmatchedObjects;
         this.listModel = listModel;
 
-        List<PrimitiveData> newObjects = ConflationUtils.copyObjects(sourceDataLayer.data, unmatchedObjects);
+        List<PrimitiveData> newObjects = ConflationUtils.copyObjects(sourceDataLayer.data, unmatchedObjects, targetDataLayer.data);
 
         addPrimitivesCommand = new AddPrimitivesCommand(newObjects, newObjects, targetDataLayer);
     }
@@ -69,7 +70,6 @@
         return unmatchedObjects;
     }
 
-
     @Override
     public Collection<PseudoCommand> getChildren() {
         Collection<PseudoCommand> children = new ArrayList<>();
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationLayer.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationLayer.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationLayer.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
@@ -31,12 +32,12 @@
  */
 public class ConflationLayer extends Layer {
     protected SimpleMatchList matches;
-    
+
     public ConflationLayer(SimpleMatchList matches) {
         super(tr("Conflation"));
         this.matches = matches;
     }
-    
+
     public ConflationLayer() {
         this(null);
     }
@@ -88,11 +89,8 @@
                 g2.draw(path);
             }
         }
-
-        
     }
 
-    
     @Override
     public Icon getIcon() {
         // TODO: change icon
@@ -121,9 +119,9 @@
             OsmPrimitive reference = match.getReferenceObject();
             OsmPrimitive subject = match.getSubjectObject();
             if (reference != null && reference instanceof Node)
-                v.visit((Node)reference);
+                v.visit((Node) reference);
             if (subject != null && subject instanceof Node)
-                v.visit((Node)subject);
+                v.visit((Node) subject);
         }
     }
 
@@ -142,7 +140,7 @@
                     SeparatorLayerAction.INSTANCE,
                     new LayerListPopup.InfoAction(this)};
     }
-    
+
     public void setMatches(SimpleMatchList matches) {
         this.matches = matches;
         // TODO: does repaint automatically occur?
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationPlugin.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationPlugin.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationPlugin.java	(copie de travail)
@@ -1,16 +1,13 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
-import java.awt.GraphicsEnvironment;
-
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
 
 public class ConflationPlugin extends Plugin {
 
-    private ConflationToggleDialog dialog = null;
-
     /**
      * constructor
      */
@@ -21,11 +18,8 @@
     // add dialog the first time the mapframe is loaded
     @Override
     public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
-        if (oldFrame == null && newFrame != null && !GraphicsEnvironment.isHeadless()) {
-            if (dialog == null) {
-                dialog = new ConflationToggleDialog(this);
-            }
-            newFrame.addToggleDialog(dialog);
+        if (oldFrame == null && newFrame != null) {
+            newFrame.addToggleDialog(new ConflationToggleDialog(this));
         }
     }
 }
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import static org.openstreetmap.josm.tools.I18n.marktr;
@@ -18,7 +19,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -48,6 +48,7 @@
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
@@ -62,6 +63,10 @@
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.plugins.jts.JTSConverter;
@@ -81,10 +86,10 @@
 import com.vividsolutions.jump.task.TaskMonitor;
 
 public class ConflationToggleDialog extends ToggleDialog
-implements SelectionChangedListener, DataSetListener, SimpleMatchListListener {
+implements SelectionChangedListener, DataSetListener, SimpleMatchListListener, LayerChangeListener {
 
-    public final static String TITLE_PREFIX = tr("Conflation");
-    public final static String PREF_PREFIX = "conflation";
+    public static final String TITLE_PREFIX = tr("Conflation");
+    public static final String PREF_PREFIX = "conflation";
     JTabbedPane tabbedPane;
     JTable matchTable;
     JList<OsmPrimitive> referenceOnlyList;
@@ -116,6 +121,7 @@
             public void windowClosed(WindowEvent e) {
                 // "Generate matches" was clicked
                 if (settingsDialog.getValue() == 1) {
+                    clear(true, true, false);
                     settings = settingsDialog.getSettings();
                     performMatching();
                 }
@@ -139,6 +145,7 @@
 
         matchTable.setRowSelectionAllowed(true);
         matchTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        matchTable.setAutoCreateRowSorter(true);
 
         referenceOnlyListModel = new UnmatchedObjectListModel();
         referenceOnlyList = new JList<>(referenceOnlyListModel);
@@ -326,16 +333,127 @@
     }
 
     @Override
+    public void showNotify() {
+        super.showNotify();
+        DataSet.addSelectionListener(this);
+        Main.getLayerManager().addLayerChangeListener(this);
+    }
+
+    @Override
+    public void hideNotify() {
+        super.hideNotify();
+        DataSet.removeSelectionListener(this);
+        Main.getLayerManager().removeLayerChangeListener(this);
+        clear(true, true, true);
+        settingsDialog.clear(true, true);
+    }
+
+    private void clear(boolean shouldClearReference, boolean shouldClearSubject, boolean shouldRemoveConflationLayer) {
+        if (shouldRemoveConflationLayer && (conflationLayer != null)) {
+            if (Main.getLayerManager().containsLayer(conflationLayer)) {
+                Main.getLayerManager().removeLayer(conflationLayer);
+            }
+            conflationLayer = null;
+        }
+        if (settings != null) {
+            if (shouldClearReference) {
+                DataSet dataSet = settings.getReferenceDataSet();
+                if (dataSet != null) {
+                    dataSet.removeDataSetListener(this);
+                    settings.setReferenceDataSet(null);
+                }
+                settings.setReferenceLayer(null);
+                settings.setReferenceSelection(null);
+            }
+            if (shouldClearSubject) {
+                DataSet dataSet = settings.getSubjectDataSet();
+                if (dataSet != null) {
+                    dataSet.removeDataSetListener(this);
+                    settings.setSubjectDataSet(null);
+                }
+                settings.setSubjectLayer(null);
+                settings.setSubjectSelection(null);
+            }
+        }
+        referenceOnlyListModel.clear();
+        subjectOnlyListModel.clear();
+        setMatches(new SimpleMatchList());
+    }
+    
+    private void setMatches(SimpleMatchList matchList) {
+        matches.clear();
+        matches.removeAllConflationListChangedListener();
+        matches = matchList;
+        matchTableModel.setMatches(matches);
+        matches.addConflationListChangedListener(conflateAction);
+        matches.addConflationListChangedListener(removeAction);
+        matches.addConflationListChangedListener(this);
+        if (conflationLayer != null) {
+            conflationLayer.setMatches(matches);
+        }
+    }
+
+    @Override
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        // TODO
+        if (newSelection.size() > 0) {
+            referenceOnlyList.getSelectionModel().clearSelection();
+            subjectOnlyList.getSelectionModel().clearSelection();
+            matchTable.getSelectionModel().clearSelection();
+            boolean ensureVisible = true;
+            for (OsmPrimitive item: newSelection) {
+                addObjectToSelection(item, ensureVisible);
+                ensureVisible = false;
+            }
+        }
+    }
+
+    private boolean addObjectToSelection(OsmPrimitive object, boolean ensureVisible) {
+        int index = referenceOnlyListModel.indexOf(object);
+        if (index >= 0) {
+            referenceOnlyList.getSelectionModel().addSelectionInterval(index, index);
+            if (ensureVisible) {
+                tabbedPane.setSelectedIndex(1);
+                referenceOnlyList.ensureIndexIsVisible(index);
+            }
+            return true;
+        }
+        index = subjectOnlyListModel.indexOf(object);
+        if (index >= 0) {
+            subjectOnlyList.getSelectionModel().addSelectionInterval(index, index);
+            if (ensureVisible) {
+                tabbedPane.setSelectedIndex(2);
+                subjectOnlyList.ensureIndexIsVisible(index);
+            }
+            return true;
+        }
+        index = 0;
+        for (SimpleMatch c : matches) {
+            if ((c.getSubjectObject() == object) || (c.getReferenceObject() == object)) {
+                break;
+            }
+            index++;
+        }
+        if (index < matches.size()) {
+            index = matchTable.convertRowIndexToView(index);
+            matchTable.getSelectionModel().addSelectionInterval(index, index);
+            if (ensureVisible) {
+                tabbedPane.setSelectedIndex(0);
+                matchTable.scrollRectToVisible(new Rectangle(matchTable.getCellRect(index, 0, true)));
+            }
+            return true;
+        }
+        return false;
     }
 
     private Collection<SimpleMatch> getSelectedFromTable() {
         ListSelectionModel lsm = matchTable.getSelectionModel();
         Collection<SimpleMatch> selMatches = new HashSet<>();
         for (int i = lsm.getMinSelectionIndex(); i <= lsm.getMaxSelectionIndex(); i++) {
-            if (lsm.isSelectedIndex(i) && i < matches.size()) {
-                selMatches.add(matches.get(i));
+            if (lsm.isSelectedIndex(i) && (i < matches.size())) {
+                int modelIndex = matchTable.convertRowIndexToModel(i);
+                if (modelIndex < matches.size()) {
+                    selMatches.add(matches.get(modelIndex));
+                }
             }
         }
         return selMatches;
@@ -352,9 +470,10 @@
             //TODO: do something!
         }
     }
+
     protected static class ConflatePopupMenu extends JPopupMenu {
 
-        static public void launch(Component parent) {
+        public static void launch(Component parent) {
             JPopupMenu menu = new ConflatePopupMenu();
             Rectangle r = parent.getBounds();
             menu.show(parent, r.x, r.y + r.height);
@@ -380,7 +499,7 @@
 
         private final String columnName;
 
-        public ColorTableCellRenderer(String column) {
+        ColorTableCellRenderer(String column) {
             this.columnName = column;
             setOpaque(true);
         }
@@ -409,7 +528,7 @@
         }
     }
 
-    static public class LayerListCellRenderer extends DefaultListCellRenderer {
+    public static class LayerListCellRenderer extends DefaultListCellRenderer {
 
         @Override
         public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
@@ -429,7 +548,7 @@
      */
     class RemoveMatchCommand extends Command {
         private final Collection<SimpleMatch> toRemove;
-        public RemoveMatchCommand(Collection<SimpleMatch> toRemove) {
+        RemoveMatchCommand(Collection<SimpleMatch> toRemove) {
             this.toRemove = toRemove;
         }
 
@@ -462,7 +581,7 @@
         private final UnmatchedObjectListModel model;
         private final Collection<OsmPrimitive> objects;
 
-        public RemoveUnmatchedObjectCommand(UnmatchedObjectListModel model,
+        RemoveUnmatchedObjectCommand(UnmatchedObjectListModel model,
                 Collection<OsmPrimitive> objects) {
             this.model = model;
             this.objects = objects;
@@ -500,10 +619,11 @@
 
     class RemoveAction extends JosmAction implements SimpleMatchListListener, ChangeListener, ListSelectionListener {
 
-        public RemoveAction() {
+        RemoveAction() {
             super(tr("Remove"), "dialogs/delete", tr("Remove selected matches"),
                     null, false);
         }
+        
         @Override
         public void actionPerformed(ActionEvent e) {
             Component selComponent = getSelectedTabComponent();
@@ -540,6 +660,7 @@
             }
 
         }
+        
         @Override
         public void simpleMatchListChanged(SimpleMatchList list) {
         }
@@ -562,7 +683,7 @@
 
     class ConflateAction extends JosmAction implements SimpleMatchListListener, ChangeListener, ListSelectionListener {
 
-        public ConflateAction() {
+        ConflateAction() {
             // TODO: make sure shortcuts make sense
             super(tr("Conflate"), "dialogs/conflation", tr("Conflate selected objects"),
                     Shortcut.registerShortcut("conflation:replace", tr("Conflation: {0}", tr("Replace")),
@@ -571,10 +692,15 @@
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            if (getSelectedTabComponent().equals(matchTable))
-                conflateMatchActionPerformed();
-            else if (getSelectedTabComponent().equals(referenceOnlyList))
-                conflateUnmatchedObjectActionPerformed();
+            try {
+                DataSet.removeSelectionListener(ConflationToggleDialog.this);
+                if (getSelectedTabComponent().equals(matchTable))
+                    conflateMatchActionPerformed();
+                else if (getSelectedTabComponent().equals(referenceOnlyList))
+                    conflateUnmatchedObjectActionPerformed();
+            } finally {
+                DataSet.addSelectionListener(ConflationToggleDialog.this);
+            }
         }
 
         private void conflateUnmatchedObjectActionPerformed() {
@@ -587,21 +713,19 @@
 
         private void conflateMatchActionPerformed() {
             SimpleMatch nextSelection = matches.findNextSelection();
-            List<Command> cmds = new LinkedList<>();
+            //List<Command> cmds = new LinkedList<>();
             try {
                 // iterate over selected matches in reverse order since they will be removed as we go
                 List<SimpleMatch> selMatches = new ArrayList<>(matches.getSelected());
                 for (SimpleMatch c : selMatches) {
-
                     ConflateMatchCommand conflateCommand;
                     try {
                         conflateCommand = new ConflateMatchCommand(c, matches, settings);
                     } catch (UserCancelException ex) {
                         break;
                     }
-                    cmds.add(conflateCommand);
-
                     // FIXME: how to chain commands which change relations? (see below)
+                    //cmds.add(conflateCommand);
                     Main.main.undoRedo.add(conflateCommand);
                 }
             } catch (ReplaceGeometryException ex) {
@@ -659,8 +783,8 @@
      * the list (either matches or single primitives).
      *
      */
-    class ZoomToListSelectionAction extends JosmAction implements ListSelectionListener{
-        public ZoomToListSelectionAction() {
+    class ZoomToListSelectionAction extends JosmAction implements ListSelectionListener {
+        ZoomToListSelectionAction() {
             super(tr("Zoom to selected primitive(s)"), "dialogs/autoscale/selection", tr("Zoom to selected primitive(s)"),
                     null, false);
         }
@@ -692,8 +816,8 @@
      * the list (either matches or single primitives).
      *
      */
-    class SelectListSelectionAction extends JosmAction implements ListSelectionListener{
-        public SelectListSelectionAction() {
+    class SelectListSelectionAction extends JosmAction implements ListSelectionListener {
+        SelectListSelectionAction() {
             super(tr("Select selected primitive(s)"), "dialogs/select", tr("Select the primitives currently selected in the list"),
                     null, false);
         }
@@ -730,12 +854,11 @@
                     //FIXME: this doesn't seem to be working
                     int row = matchTable.rowAtPoint(evt.getPoint());
                     matchTable.getSelectionModel().addSelectionInterval(row, row);
-                }
-                else if (c == subjectOnlyList || c == referenceOnlyList) {
-                    int idx = ((JList<?>)c).locationToIndex(evt.getPoint());
+                } else if (c == subjectOnlyList || c == referenceOnlyList) {
+                    int idx = ((JList<?>) c).locationToIndex(evt.getPoint());
                     if (idx < 0)
                         return;
-                    ((JList<?>)c).setSelectedIndex(idx);
+                    ((JList<?>) c).setSelectedIndex(idx);
                 }
             }
 
@@ -747,7 +870,7 @@
      * The popup menu for the selection list
      */
     class SelectionPopup extends JPopupMenu {
-        public SelectionPopup() {
+        SelectionPopup() {
             matchTable.getSelectionModel().addListSelectionListener(zoomToListSelectionAction);
             subjectOnlyList.addListSelectionListener(zoomToListSelectionAction);
             referenceOnlyList.addListSelectionListener(zoomToListSelectionAction);
@@ -767,18 +890,31 @@
 
     @Override
     public void primitivesRemoved(PrimitivesRemovedEvent event) {
-        List<? extends OsmPrimitive> prims = event.getPrimitives();
-        for (OsmPrimitive p : prims) {
-            // TODO: use hashmap
-            for (SimpleMatch c : matches) {
-                if (c.getReferenceObject().equals(p) || c.getSubjectObject().equals(p)) {
-                    matches.remove(c);
-                    break;
+        if (settings != null) {
+            DataSet dataSet = event.getDataset();
+            if (dataSet == settings.getReferenceDataSet()) {
+                for (OsmPrimitive p : event.getPrimitives()) {
+                    // TODO: use hashmap
+                    for (SimpleMatch c : matches) {
+                        if (c.getReferenceObject().equals(p)) {
+                            matches.remove(c);
+                            break;
+                        }
+                    }
+                    referenceOnlyListModel.removeElement(p);
+                }
+            } else if (dataSet == settings.getSubjectDataSet()) {
+                for (OsmPrimitive p : event.getPrimitives()) {
+                    // TODO: use hashmap
+                    for (SimpleMatch c : matches) {
+                        if (c.getSubjectObject().equals(p)) {
+                            matches.remove(c);
+                            break;
+                        }
+                    }
+                    subjectOnlyListModel.removeElement(p);
                 }
             }
-
-            referenceOnlyListModel.removeElement(p);
-            subjectOnlyListModel.removeElement(p);
         }
     }
 
@@ -808,8 +944,6 @@
 
     /**
      * Create FeatureSchema using union of all keys from all selected primitives
-     * @param prims
-     * @return
      */
     private FeatureSchema createSchema(Collection<OsmPrimitive> prims) {
         Set<String> keys = new HashSet<>();
@@ -878,7 +1012,7 @@
         FeatureCollection refColl = new FeatureDataset(allFeatures.getFeatureSchema());
         FeatureCollection subColl = new FeatureDataset(allFeatures.getFeatureSchema());
         for (Feature f : allFeatures.getFeatures()) {
-            OsmFeature osmFeature = (OsmFeature)f;
+            OsmFeature osmFeature = (OsmFeature) f;
             if (settings.getReferenceSelection().contains(osmFeature.getPrimitive()))
                 refColl.add(osmFeature);
             if (settings.getSubjectSelection().contains(osmFeature.getPrimitive()))
@@ -909,7 +1043,7 @@
         SimpleMatchList list = new SimpleMatchList();
         for (Map.Entry<Feature, Matches> entry: map.entrySet()) {
             OsmFeature target = (OsmFeature) entry.getKey();
-            OsmFeature subject = (OsmFeature)entry.getValue().getTopMatch();
+            OsmFeature subject = (OsmFeature) entry.getValue().getTopMatch();
             if (target != null && subject != null)
                 list.add(new SimpleMatch(target.getPrimitive(), subject.getPrimitive(),
                         entry.getValue().getTopScore()));
@@ -921,7 +1055,7 @@
     }
 
     private void performMatching() {
-        matches = generateMatches(settings);
+        setMatches(generateMatches(settings));
 
         // populate unmatched objects
         List<OsmPrimitive> referenceOnly = new ArrayList<>(settings.getReferenceSelection());
@@ -938,17 +1072,14 @@
 
         updateTabTitles();
 
-        matchTableModel.setMatches(matches);
-        matches.addConflationListChangedListener(matchTableModel);
-        matches.addConflationListChangedListener(conflateAction);
-        matches.addConflationListChangedListener(removeAction);
-        matches.addConflationListChangedListener(this);
         settings.getSubjectDataSet().addDataSetListener(this);
         settings.getReferenceDataSet().addDataSetListener(this);
         // add conflation layer
         try {
             if (conflationLayer == null) {
                 conflationLayer = new ConflationLayer(matches);
+            }
+            if (!Main.getLayerManager().containsLayer(conflationLayer)) {
                 Main.getLayerManager().addLayer(conflationLayer);
             }
         } catch (Exception ex) {
@@ -974,4 +1105,27 @@
             updateTabTitles();
         }
     }
+
+    @Override
+    public void layerAdded(LayerAddEvent e) {
+        // Nothing to do
+    }
+
+    @Override
+    public void layerRemoving(LayerRemoveEvent e) {
+        Layer removedLayer = e.getRemovedLayer();
+        if (settings != null) {
+            boolean shouldclearReferenceSettings = removedLayer == settings.getReferenceLayer();
+            boolean shouldclearSubjectSettings = removedLayer == settings.getSubjectLayer();
+            if (shouldclearReferenceSettings || shouldclearSubjectSettings) {
+                clear(shouldclearReferenceSettings, shouldclearSubjectSettings, true);
+            }
+        }
+        this.settingsDialog.layerRemoving(e);
+    }
+
+    @Override
+    public void layerOrderChanged(LayerOrderChangeEvent e) {
+        // Nothing to do
+    }
 }
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationUtils.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationUtils.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationUtils.java	(copie de travail)
@@ -1,10 +1,13 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -15,16 +18,18 @@
 
 public final class ConflationUtils {
 
+    private ConflationUtils() {}
+
     public static EastNorth getCenter(OsmPrimitive prim) {
         LatLon center = prim.getBBox().getTopLeft().getCenter(prim.getBBox().getBottomRight());
         return Main.map.mapView.getProjection().latlon2eastNorth(center);
     }
 
-    public static List<PrimitiveData> copyObjects(DataSet sourceDataSet, OsmPrimitive primitive) {
-        return copyObjects(sourceDataSet, Collections.singleton(primitive));
+    public static List<PrimitiveData> copyObjects(DataSet sourceDataSet, OsmPrimitive primitive, DataSet destDataSet) {
+        return copyObjects(sourceDataSet, Collections.singleton(primitive), destDataSet);
     }
 
-    public static List<PrimitiveData> copyObjects(DataSet sourceDataSet, Collection<OsmPrimitive> primitives) {
+    public static List<PrimitiveData> copyObjects(DataSet sourceDataSet, Collection<OsmPrimitive> primitives, DataSet destDataSet) {
 
         Collection<OsmPrimitive> origSelection = sourceDataSet.getSelected();
         sourceDataSet.setSelected(primitives);
@@ -34,10 +39,9 @@
         //restore selection
         sourceDataSet.setSelected(origSelection);
 
-        List<PrimitiveData> newObjects = new ArrayList<>();
-        for (OsmPrimitive p : newDataSet.allPrimitives()) {
-            newObjects.add(p.save());
-        }
-        return newObjects;
+        return newDataSet.allPrimitives().stream()
+                .filter(p -> destDataSet.getPrimitiveById(p.getPrimitiveId()) == null)
+                .map(p -> p.save())
+                .collect(Collectors.toCollection(ArrayList::new));
     }
 }
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/MatchFinderPanel.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/MatchFinderPanel.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/MatchFinderPanel.java	(copie de travail)
@@ -1,3 +1,4 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.conflation;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
@@ -26,7 +27,6 @@
 import com.vividsolutions.jcs.conflate.polygonmatch.IdenticalFeatureFilter;
 import com.vividsolutions.jcs.conflate.polygonmatch.OneToOneFCMatchFinder;
 
-
 public class MatchFinderPanel extends JPanel {
     private final JComboBox<String> matchFinderComboBox;
     private final CentroidDistanceComponent centroidDistanceComponent;
@@ -35,7 +35,7 @@
         setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
         setBorder(new CompoundBorder(
                 BorderFactory.createTitledBorder(tr("Match finder settings")),
-                BorderFactory.createEmptyBorder(5,5,5,5)));
+                BorderFactory.createEmptyBorder(5, 5, 5, 5)));
 
         String[] matchFinderStrings = {"DisambiguatingFCMatchFinder", "OneToOneFCMatchFinder" };
         matchFinderComboBox = new JComboBox<>(matchFinderStrings);
@@ -72,10 +72,10 @@
     abstract class DistanceComponent extends AbstractScoreComponent {
         SpinnerNumberModel threshDistanceSpinnerModel;
 
-        public DistanceComponent(String title) {
+        DistanceComponent(String title) {
             setBorder(new CompoundBorder(
                     BorderFactory.createTitledBorder(tr(title)),
-                    BorderFactory.createEmptyBorder(5,5,5,5)));
+                    BorderFactory.createEmptyBorder(5, 5, 5, 5)));
 
             JPanel panel = new JPanel();
             panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
@@ -99,7 +99,7 @@
     }
 
     class CentroidDistanceComponent extends DistanceComponent {
-        public CentroidDistanceComponent() {
+        CentroidDistanceComponent() {
             super(tr("Centroid distance"));
         }
 
@@ -112,7 +112,7 @@
     }
 
     class HausdorffDistanceComponent extends DistanceComponent {
-        public HausdorffDistanceComponent() {
+        HausdorffDistanceComponent() {
             super(tr("Hausdorff distance"));
         }
 
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/OsmFeature.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/OsmFeature.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/OsmFeature.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import com.vividsolutions.jump.feature.AbstractBasicFeature;
@@ -16,7 +17,6 @@
     /**
      * Create a copy of the OSM geometry
      * TODO: update from underlying primitive
-     * @param prim 
      */
     public OsmFeature(OsmPrimitive prim, JTSConverter jtsConverter) {
         super(new FeatureSchema());
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SettingsDialog.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SettingsDialog.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SettingsDialog.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
@@ -26,7 +27,9 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
 import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -92,7 +95,7 @@
 
         referencePanel.setBorder(new CompoundBorder(
                 BorderFactory.createTitledBorder(tr("Reference")),
-                BorderFactory.createEmptyBorder(5,5,5,5)));
+                BorderFactory.createEmptyBorder(5, 5, 5, 5)));
         referencePanel.setAlignmentX(LEFT_ALIGNMENT);
         referencePanel.setLayout(new BoxLayout(referencePanel,
                 BoxLayout.PAGE_AXIS));
@@ -129,7 +132,7 @@
 
         subjectPanel.setBorder(new CompoundBorder(
                 BorderFactory.createTitledBorder(tr("Subject")),
-                BorderFactory.createEmptyBorder(5,5,5,5)));
+                BorderFactory.createEmptyBorder(5, 5, 5, 5)));
         subjectPanel.setAlignmentX(LEFT_ALIGNMENT);
         subjectPanel.setLayout(new BoxLayout(subjectPanel, BoxLayout.PAGE_AXIS));
 
@@ -172,16 +175,15 @@
 
     /**
      * Matches are actually generated in windowClosed event in ConflationToggleDialog
-     *
-     * @param buttonIndex
-     * @param evt
      */
     @Override
     protected void buttonAction(int buttonIndex, ActionEvent evt) {
         // "Generate matches" as clicked
         if (buttonIndex == 0) {
             if (referenceSelection.isEmpty() || subjectSelection.isEmpty()) {
-                JOptionPane.showMessageDialog(Main.parent, tr("Selections must be made for both reference and subject."), tr("Incomplete selections"), JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(Main.parent, 
+                        tr("Selections must be made for both reference and subject."), tr("Incomplete selections"),
+                        JOptionPane.ERROR_MESSAGE);
                 return;
             }
         }
@@ -220,7 +222,7 @@
 
     class RestoreSubjectAction extends JosmAction {
 
-        public RestoreSubjectAction() {
+        RestoreSubjectAction() {
             super(tr("Restore"), null, tr("Restore subject selection"), null, false);
         }
 
@@ -236,7 +238,7 @@
 
     class RestoreReferenceAction extends JosmAction {
 
-        public RestoreReferenceAction() {
+        RestoreReferenceAction() {
             super(tr("Restore"), null, tr("Restore reference selection"), null, false);
         }
 
@@ -252,7 +254,7 @@
 
     class FreezeSubjectAction extends JosmAction {
 
-        public FreezeSubjectAction() {
+        FreezeSubjectAction() {
             super(tr("Freeze"), null, tr("Freeze subject selection"), null, false);
         }
 
@@ -267,13 +269,17 @@
             //            subjectDataSet.addDataSetListener(tableModel); FIXME:
             subjectLayer = Main.getLayerManager().getEditLayer();
             if (subjectDataSet == null || subjectLayer == null) {
-                JOptionPane.showMessageDialog(Main.parent, tr("No valid OSM data layer present."), tr("Error freezing selection"), JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(Main.parent,
+                    tr("No valid OSM data layer present."), tr("Error freezing selection"),
+                    JOptionPane.ERROR_MESSAGE);
                 return;
             }
             subjectSelection.clear();
             subjectSelection.addAll(subjectDataSet.getSelected());
             if (subjectSelection.isEmpty()) {
-                JOptionPane.showMessageDialog(Main.parent, tr("Nothing is selected, please try again."), tr("Empty selection"), JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(Main.parent, 
+                        tr("Nothing is selected, please try again."), tr("Empty selection"),
+                        JOptionPane.ERROR_MESSAGE);
                 return;
             }
             update();
@@ -282,7 +288,7 @@
 
     class FreezeReferenceAction extends JosmAction {
 
-        public FreezeReferenceAction() {
+        FreezeReferenceAction() {
             super(tr("Freeze"), null, tr("Freeze reference selection"), null, false);
         }
 
@@ -297,13 +303,17 @@
             //            referenceDataSet.addDataSetListener(this); FIXME:
             referenceLayer = Main.getLayerManager().getEditLayer();
             if (referenceDataSet == null || referenceLayer == null) {
-                JOptionPane.showMessageDialog(Main.parent, tr("No valid OSM data layer present."), tr("Error freezing selection"), JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(Main.parent, 
+                        tr("No valid OSM data layer present."), tr("Error freezing selection"),
+                        JOptionPane.ERROR_MESSAGE);
                 return;
             }
             referenceSelection.clear();
             referenceSelection.addAll(referenceDataSet.getSelected());
             if (referenceSelection.isEmpty()) {
-                JOptionPane.showMessageDialog(Main.parent, tr("Nothing is selected, please try again."), tr("Empty selection"), JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(Main.parent,
+                        tr("Nothing is selected, please try again."), tr("Empty selection"), 
+                        JOptionPane.ERROR_MESSAGE);
                 return;
             }
             update();
@@ -331,6 +341,10 @@
             subjectLayerLabel.setText(subjectLayer.getName());
             subjectSelectionLabel.setText(tr("{0}: {1} / {2}: {3} / {4}: {5}",
                     "Relations", numRelations, "Ways", numWays, "Nodes", numNodes));
+        } else {
+            subjectLayerLabel.setText("(none)");
+            subjectSelectionLabel.setText(tr("{0}: 0 / {1}: 0 / {2}: 0",
+                    "Relations", "Ways", "Nodes"));            
         }
         numNodes = 0;
         numWays = 0;
@@ -348,8 +362,44 @@
             referenceLayerLabel.setText(referenceLayer.getName());
             referenceSelectionLabel.setText(tr("{0}: {1} / {2}: {3} / {4}: {5}",
                     "Relations", numRelations, "Ways", numWays, "Nodes", numNodes));
+        } else {
+            referenceLayerLabel.setText("(none)");
+            referenceSelectionLabel.setText(tr("{0}: 0 / {1}: 0 / {2}: 0",
+                    "Relations", "Ways", "Nodes"));            
         }
 
         //FIXME: properly update match finder settings
     }
+    
+    /**
+     * To be called when a layer is removed.
+     * Clear any reference to the removed layer.
+     * @param e the layer remove event.
+     */
+    public void layerRemoving(LayerRemoveEvent e) {
+        Layer removedLayer = e.getRemovedLayer();
+        this.clear(removedLayer == referenceLayer, removedLayer == subjectLayer);
+    }
+    
+    /**
+     * Clear some settings.
+     * @param shouldClearReference if "Reference" settings should be cleared. 
+     * @param shouldClearSubject if "Subject" settings should be cleared.
+     */
+    public void clear(boolean shouldClearReference, boolean shouldClearSubject) {
+        if (shouldClearReference || shouldClearSubject) {
+            if (shouldClearReference) {
+                referenceLayer = null;
+                referenceDataSet = null;
+                referenceSelection.clear();
+            }
+            if (shouldClearSubject) {
+                subjectLayer = null;
+                subjectDataSet = null;
+                subjectSelection.clear();
+            }
+            update();
+        }
+    }
+
 }
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatch.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatch.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatch.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -42,4 +43,4 @@
     public Object getDistance() {
         return distance;
     }
-}
\ Pas de fin de ligne à la fin du fichier
+}
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchList.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchList.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchList.java	(copie de travail)
@@ -1,7 +1,13 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 
@@ -148,14 +154,22 @@
     public void addConflationListChangedListener(SimpleMatchListListener listener) {
         listeners.addIfAbsent(listener);
     }
+    
+    public void removeConflationListChangedListener(SimpleMatchListListener listener) {
+        listeners.remove(listener);
+    }
+    
+    public void removeAllConflationListChangedListener() {
+        listeners.clear();
+    }
 
-    public void fireListChanged(){
+    public void fireListChanged() {
         for (SimpleMatchListListener l : listeners) {
             l.simpleMatchListChanged(this);
         }
     }
     
-    public void fireSelectionChanged(){
+    public void fireSelectionChanged() {
         for (SimpleMatchListListener l : listeners) {
             l.simpleMatchSelectionChanged(selected);
         }
@@ -167,7 +181,6 @@
     
     /**
      * Set which {@see SimpleMatch} is currently selected. Set to null to clear selection.
-     * @param match 
      */
     public void setSelected(SimpleMatch match) {
         if (match != null)
@@ -184,4 +197,4 @@
         selected.addAll(matches);
         fireSelectionChanged();
     }
-}
\ Pas de fin de ligne à la fin du fichier
+}
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchListListener.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchListListener.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchListListener.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import java.util.Collection;
@@ -10,12 +11,12 @@
      *
      * @param list The new list.
      */
-    public void simpleMatchListChanged(SimpleMatchList list);
+    void simpleMatchListChanged(SimpleMatchList list);
     
     /**
      * Informs the listener that the conflation list selection has changed.
      * 
      * @param selected The newly selected conflation match.
      */
-    public void simpleMatchSelectionChanged(Collection<SimpleMatch> selected);
-}
\ Pas de fin de ligne à la fin du fichier
+    void simpleMatchSelectionChanged(Collection<SimpleMatch> selected);
+}
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchSettings.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchSettings.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchSettings.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import com.vividsolutions.jcs.conflate.polygonmatch.FCMatchFinder;
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchesTableModel.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchesTableModel.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/SimpleMatchesTableModel.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import java.util.Collection;
@@ -16,7 +17,7 @@
 
     private SimpleMatchList matches = null;
     // TODO: make columns dynamic
-    private final static String[] columnNames = {tr("Reference"), tr("Subject"), "Distance (m)", "Score", "Tags"};
+    private static final String[] columnNames = {tr("Reference"), tr("Subject"), "Distance (m)", "Score", "Tags"};
 
     @Override
     public int getColumnCount() {
@@ -70,7 +71,12 @@
 
     @Override
     public Class<?> getColumnClass(int c) {
-        return getValueAt(0, c).getClass();
+        Object value = getValueAt(0, c);
+        if (value != null) {
+            return value.getClass();
+        } else {
+            return Object.class;
+        }
     }
 
     /**
@@ -84,8 +90,16 @@
      * @param matches the matches to set
      */
     public void setMatches(SimpleMatchList matches) {
-        this.matches = matches;
-        fireTableDataChanged();
+        if (matches != this.matches) {
+            if (this.matches != null) {
+                this.matches.removeConflationListChangedListener(this);
+            }
+            this.matches = matches;
+            if (matches != null) {
+                matches.addConflationListChangedListener(this);
+            }
+            fireTableDataChanged();
+        }
     }
 
     @Override
Index: josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/UnmatchedObjectListModel.java
===================================================================
--- josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/UnmatchedObjectListModel.java	(révision 130)
+++ josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/UnmatchedObjectListModel.java	(copie de travail)
@@ -1,4 +1,5 @@
-// License: GPL. See LICENSE file for details. Copyright 2012 by Josh Doe and others.
+// License: GPL. For details, see LICENSE file.
+// Copyright 2012 by Josh Doe and others.
 package org.openstreetmap.josm.plugins.conflation;
 
 import java.util.Collection;
