Index: /trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java	(revision 5297)
@@ -82,9 +82,14 @@
     @Override
     protected void updateEnabledState() {
-        if (getEditLayer() == null) {
-            setEnabled(false);
-            return;
-        }
-        setEnabled(!LayerListDialog.getInstance().getModel().getPossibleMergeTargets(getEditLayer()).isEmpty());
+        GuiHelper.runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                if (getEditLayer() == null) {
+                    setEnabled(false);
+                    return;
+                }
+                setEnabled(!LayerListDialog.getInstance().getModel().getPossibleMergeTargets(getEditLayer()).isEmpty());
+            }
+        });
     }
     
Index: /trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java	(revision 5297)
+++ /trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java	(revision 5297)
@@ -0,0 +1,107 @@
+package org.openstreetmap.josm.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListTable;
+import org.openstreetmap.josm.gui.conflict.pair.relation.RelationMemberTable;
+import org.openstreetmap.josm.gui.dialogs.relation.MemberTable;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+public class ZoomToAction extends AbstractAction implements LayerChangeListener, ListSelectionListener {
+
+    private final OsmPrimitivesTable table;
+    
+    private final String descriptionNominal;
+    private final String descriptionInactiveLayer;
+    private final String descriptionNoSelection;
+    
+    public ZoomToAction(OsmPrimitivesTable table, String descriptionNominal, String descriptionInactiveLayer, String descriptionNoSelection) {
+        CheckParameterUtil.ensureParameterNotNull(table);
+        this.table = table;
+        this.descriptionNominal = descriptionNominal;
+        this.descriptionInactiveLayer = descriptionInactiveLayer;
+        this.descriptionNoSelection = descriptionNoSelection;
+        putValue(NAME, tr("Zoom to"));
+        putValue(SHORT_DESCRIPTION, descriptionNominal);
+        updateEnabledState();
+    }
+    
+    public ZoomToAction(MemberTable table) {
+        this(table, 
+                tr("Zoom to the object the first selected member refers to"),
+                tr("Zooming disabled because layer of this relation is not active"),
+                tr("Zooming disabled because there is no selected member"));
+    }
+    
+    public ZoomToAction(RelationMemberTable table) {
+        this(table, 
+                tr("Zoom to the object the first selected member refers to"),
+                tr("Zooming disabled because layer of this relation is not active"),
+                tr("Zooming disabled because there is no selected member"));
+    }
+    
+    public ZoomToAction(NodeListTable table) {
+        this(table, 
+                tr("Zoom to the first selected node"),
+                tr("Zooming disabled because layer of this way is not active"),
+                tr("Zooming disabled because there is no selected node"));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        if (! isEnabled())
+            return;
+        int rows[] = this.table.getSelectedRows();
+        if (rows == null || rows.length == 0)
+            return;
+        int row = rows[0];
+        PrimitiveId primitive = this.table.getOsmPrimitivesTableModel().getReferredPrimitive(row);
+        OsmDataLayer layer = this.table.getLayer();
+        if (layer != null && primitive != null) {
+            layer.data.setSelected(primitive);
+            AutoScaleAction.autoScale("selection");
+        }
+    }
+
+    protected void updateEnabledState() {
+        if (Main.main == null || Main.main.getEditLayer() != this.table.getLayer()) {
+            setEnabled(false);
+            putValue(SHORT_DESCRIPTION, descriptionInactiveLayer);
+            return;
+        }
+        if (this.table.getSelectedRowCount() == 0) {
+            setEnabled(false);
+            putValue(SHORT_DESCRIPTION, descriptionNoSelection);
+            return;
+        }
+        setEnabled(true);
+        putValue(SHORT_DESCRIPTION, descriptionNominal);
+    }
+
+    public void valueChanged(ListSelectionEvent e) {
+        updateEnabledState();
+    }
+
+    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+        updateEnabledState();
+    }
+
+    public void layerAdded(Layer newLayer) {
+        updateEnabledState();
+    }
+
+    public void layerRemoved(Layer oldLayer) {
+        updateEnabledState();
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 5297)
@@ -47,4 +47,5 @@
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor.ProgressMonitorDialog;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -757,5 +758,5 @@
         setHelpText(null, t);
     }
-    public void setHelpText(Object id, String text)  {
+    public void setHelpText(Object id, final String text)  {
 
         StatusTextHistory entry = new StatusTextHistory(id, text);
@@ -764,6 +765,11 @@
         statusText.add(entry);
 
-        helpText.setText(text);
-        helpText.setToolTipText(text);
+        GuiHelper.runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                helpText.setText(text);
+                helpText.setToolTipText(text);
+            }
+        });
     }
     public void resetHelpText(Object id) {
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ConflictResolver.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ConflictResolver.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ConflictResolver.java	(revision 5297)
@@ -338,3 +338,8 @@
         return resolvedCompletely;
     }
+
+    public void unregisterListeners() {
+        nodeListMerger.unlinkAsListener();
+        relationMemberMerger.unlinkAsListener();
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java	(revision 5297)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
 
 /**
@@ -69,7 +70,7 @@
     protected HashMap<ListRole, ArrayList<T>> entries;
 
-    protected DefaultTableModel myEntriesTableModel;
-    protected DefaultTableModel theirEntriesTableModel;
-    protected DefaultTableModel mergedEntriesTableModel;
+    protected EntriesTableModel myEntriesTableModel;
+    protected EntriesTableModel theirEntriesTableModel;
+    protected EntriesTableModel mergedEntriesTableModel;
 
     protected EntriesSelectionModel myEntriesSelectionModel;
@@ -210,13 +211,13 @@
     }
 
-    public TableModel getMyTableModel() {
+    public OsmPrimitivesTableModel getMyTableModel() {
         return myEntriesTableModel;
     }
 
-    public TableModel getTheirTableModel() {
+    public OsmPrimitivesTableModel getTheirTableModel() {
         return theirEntriesTableModel;
     }
 
-    public TableModel getMergedTableModel() {
+    public OsmPrimitivesTableModel getMergedTableModel() {
         return mergedEntriesTableModel;
     }
@@ -535,7 +536,7 @@
     protected boolean myAndTheirEntriesEqual() {
 
-        if (getMyEntries().size() != getTheirEntries().size())
+        if (getMyEntriesSize() != getTheirEntriesSize())
             return false;
-        for (int i=0; i < getMyEntries().size(); i++) {
+        for (int i=0; i < getMyEntriesSize(); i++) {
             if (! isEqualEntry(getMyEntries().get(i), getTheirEntries().get(i)))
                 return false;
@@ -555,5 +556,5 @@
      * @see ListMergeModel#getMergedTableModel()
      */
-    public class EntriesTableModel extends DefaultTableModel {
+    public class EntriesTableModel extends DefaultTableModel implements OsmPrimitivesTableModel {
         private final ListRole role;
 
@@ -675,4 +676,9 @@
             return role;
         }
+
+        @Override
+        public OsmPrimitive getReferredPrimitive(int idx) {
+            return (OsmPrimitive) getValueAt(idx, 1);
+        }
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMerger.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMerger.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMerger.java	(revision 5297)
@@ -36,4 +36,5 @@
 import javax.swing.event.ListSelectionListener;
 
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -46,7 +47,7 @@
  */
 public abstract class ListMerger<T> extends JPanel implements PropertyChangeListener, Observer {
-    protected JTable myEntriesTable;
-    protected JTable mergedEntriesTable;
-    protected JTable theirEntriesTable;
+    protected OsmPrimitivesTable myEntriesTable;
+    protected OsmPrimitivesTable mergedEntriesTable;
+    protected OsmPrimitivesTable theirEntriesTable;
 
     protected ListMergeModel<T> model;
@@ -878,4 +879,10 @@
                 trn("Their version ({0} entry)", "Their version ({0} entries)", model.getTheirEntriesSize(), model.getTheirEntriesSize())
         );
+    }
+    
+    public void unlinkAsListener() {
+        myEntriesTable.unlinkAsListener();
+        mergedEntriesTable.unlinkAsListener();
+        theirEntriesTable.unlinkAsListener();
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListMerger.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListMerger.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListMerger.java	(revision 5297)
@@ -2,7 +2,9 @@
 package org.openstreetmap.josm.gui.conflict.pair.nodes;
 
+import java.util.List;
+
 import javax.swing.JScrollPane;
-import javax.swing.JTable;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.Node;
@@ -11,4 +13,5 @@
 import org.openstreetmap.josm.gui.conflict.pair.IConflictResolver;
 import org.openstreetmap.josm.gui.conflict.pair.ListMerger;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 
 /**
@@ -23,13 +26,9 @@
     @Override
     protected JScrollPane buildMyElementsTable() {
-        myEntriesTable  = new JTable(
+        myEntriesTable  = new NodeListTable(
+                "table.mynodes",
                 model.getMyTableModel(),
-                new NodeListColumnModel(
-                        new NodeListTableCellRenderer()
-                ),
                 model.getMySelectionModel()
         );
-        myEntriesTable.setName("table.mynodes");
-        myEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(myEntriesTable);
     }
@@ -37,13 +36,9 @@
     @Override
     protected JScrollPane buildMergedElementsTable() {
-        mergedEntriesTable  = new JTable(
+        mergedEntriesTable  = new NodeListTable(
+                "table.mergednodes",
                 model.getMergedTableModel(),
-                new NodeListColumnModel(
-                        new NodeListTableCellRenderer()
-                ),
                 model.getMergedSelectionModel()
         );
-        mergedEntriesTable.setName("table.mergednodes");
-        mergedEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(mergedEntriesTable);
     }
@@ -51,18 +46,37 @@
     @Override
     protected JScrollPane buildTheirElementsTable() {
-        theirEntriesTable  = new JTable(
+        theirEntriesTable  = new NodeListTable(
+                "table.theirnodes",
                 model.getTheirTableModel(),
-                new NodeListColumnModel(
-                        new NodeListTableCellRenderer()
-                ),
                 model.getTheirSelectionModel()
         );
-        theirEntriesTable.setName("table.theirnodes");
-        theirEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(theirEntriesTable);
     }
 
     public void populate(Conflict<? extends OsmPrimitive> conflict) {
-        ((NodeListMergeModel)model).populate((Way)conflict.getMy(), (Way)conflict.getTheir());
+        Way myWay = (Way)conflict.getMy();
+        Way theirWay = (Way)conflict.getTheir();
+        ((NodeListMergeModel)model).populate(myWay, theirWay);
+        myEntriesTable.setLayer(findLayerFor(myWay));
+        theirEntriesTable.setLayer(findLayerFor(theirWay));
+    }
+    
+    protected OsmDataLayer findLayerFor(Way w) {
+        List<OsmDataLayer> layers = Main.map.mapView.getLayersOfType(OsmDataLayer.class);
+        // Find layer with same dataset
+        for (OsmDataLayer layer : layers) {
+            if (layer.data == w.getDataSet()) {
+                return layer;
+            }
+        }
+        // Conflict after merging layers: a dataset could be no more in any layer, try to find another layer with same primitive
+        for (OsmDataLayer layer : layers) {
+            for (Way way : layer.data.getWays()) {
+                if (way.getPrimitiveId().equals(w.getPrimitiveId())) {
+                    return layer;
+                }
+            }
+        }
+        return null;
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListTable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListTable.java	(revision 5297)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListTable.java	(revision 5297)
@@ -0,0 +1,23 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.conflict.pair.nodes;
+
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+
+import org.openstreetmap.josm.actions.ZoomToAction;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
+
+public class NodeListTable extends OsmPrimitivesTable {
+
+    public NodeListTable(String name, OsmPrimitivesTableModel dm, ListSelectionModel sm) {
+        super(dm, new NodeListColumnModel(new NodeListTableCellRenderer()), sm);
+        setName(name);
+        setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    }
+
+    @Override
+    protected ZoomToAction buildZoomToAction() {
+        return new ZoomToAction(this);
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberMerger.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberMerger.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberMerger.java	(revision 5297)
@@ -3,5 +3,4 @@
 
 import javax.swing.JScrollPane;
-import javax.swing.JTable;
 
 import org.openstreetmap.josm.data.conflict.Conflict;
@@ -18,11 +17,9 @@
     @Override
     protected JScrollPane buildMyElementsTable() {
-        myEntriesTable  = new JTable(
+        myEntriesTable  = new RelationMemberTable(
+                "table.mymembers",
                 model.getMyTableModel(),
-                new RelationMemberListColumnModel(),
                 model.getMySelectionModel()
         );
-        myEntriesTable.setName("table.mynodes");
-        myEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(myEntriesTable);
     }
@@ -30,12 +27,10 @@
     @Override
     protected JScrollPane buildMergedElementsTable() {
-        mergedEntriesTable  = new JTable(
+        mergedEntriesTable  = new RelationMemberTable(
+                "table.mergedmembers",
                 model.getMergedTableModel(),
-                new RelationMemberListColumnModel(),
                 model.getMergedSelectionModel()
         );
         mergedEntriesTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
-        mergedEntriesTable.setName("table.mergednodes");
-        mergedEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(mergedEntriesTable);
     }
@@ -43,11 +38,9 @@
     @Override
     protected JScrollPane buildTheirElementsTable() {
-        theirEntriesTable  = new JTable(
+        theirEntriesTable  = new RelationMemberTable(
+                "table.theirmembers",
                 model.getTheirTableModel(),
-                new RelationMemberListColumnModel(),
                 model.getTheirSelectionModel()
         );
-        theirEntriesTable.setName("table.theirnodes");
-        theirEntriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
         return embeddInScrollPane(theirEntriesTable);
     }
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberTable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberTable.java	(revision 5297)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberTable.java	(revision 5297)
@@ -0,0 +1,22 @@
+package org.openstreetmap.josm.gui.conflict.pair.relation;
+
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+
+import org.openstreetmap.josm.actions.ZoomToAction;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
+
+public class RelationMemberTable extends OsmPrimitivesTable {
+
+    public RelationMemberTable(String name, OsmPrimitivesTableModel dm, ListSelectionModel sm) {
+        super(dm, new RelationMemberListColumnModel(), sm);
+        setName(name);
+        setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    }
+
+    @Override
+    protected ZoomToAction buildZoomToAction() {
+        return new ZoomToAction(this);
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 5297)
@@ -46,4 +46,5 @@
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -156,7 +157,12 @@
     public final void refreshView() {
         OsmDataLayer editLayer =  Main.main.getEditLayer();
-        conflicts = editLayer == null?new ConflictCollection():editLayer.getConflicts();
-        model.fireContentChanged();
-        updateTitle(conflicts.size());
+        conflicts = (editLayer == null ? new ConflictCollection() : editLayer.getConflicts());
+        GuiHelper.runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                model.fireContentChanged();
+                updateTitle(conflicts.size());
+            }
+        });
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java	(revision 5297)
@@ -9,5 +9,4 @@
 import java.awt.Dimension;
 import java.awt.FlowLayout;
-import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.beans.PropertyChangeEvent;
@@ -100,4 +99,5 @@
     private void unregisterListeners() {
         resolver.removePropertyChangeListener(applyResolutionAction);
+        resolver.unregisterListeners();
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 5297)
@@ -63,4 +63,5 @@
 import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -704,14 +705,19 @@
         @Override
         public void updateEnabledState() {
-            if (layer == null) {
-                if (getModel().getSelectedLayers().size() != 1) {
-                    setEnabled(false);
-                    return;
-                }
-                Layer selectedLayer = getModel().getSelectedLayers().get(0);
-                setEnabled(!isActiveLayer(selectedLayer));
-            } else {
-                setEnabled(!isActiveLayer(layer));
-            }
+            GuiHelper.runInEDT(new Runnable() {
+                @Override
+                public void run() {
+                    if (layer == null) {
+                        if (getModel().getSelectedLayers().size() != 1) {
+                            setEnabled(false);
+                            return;
+                        }
+                        Layer selectedLayer = getModel().getSelectedLayers().get(0);
+                        setEnabled(!isActiveLayer(selectedLayer));
+                    } else {
+                        setEnabled(!isActiveLayer(layer));
+                    }
+                }
+            });
         }
 
@@ -1255,12 +1261,17 @@
                 return;
             layer.removePropertyChangeListener(this);
-            int size = getRowCount();
-            List<Integer> rows = getSelectedRows();
-            if (rows.isEmpty() && size > 0) {
-                selectionModel.setSelectionInterval(size-1, size-1);
-            }
-            fireTableDataChanged();
-            fireRefresh();
-            ensureActiveSelected();
+            final int size = getRowCount();
+            final List<Integer> rows = getSelectedRows();
+            GuiHelper.runInEDTAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    if (rows.isEmpty() && size > 0) {
+                        selectionModel.setSelectionInterval(size-1, size-1);
+                    }
+                    fireTableDataChanged();
+                    fireRefresh();
+                    ensureActiveSelected();
+                }
+            });
         }
 
@@ -1426,8 +1437,9 @@
             if (getLayers().isEmpty())
                 return;
-            if (getActiveLayer() != null) {
+            final Layer activeLayer = getActiveLayer();
+            if (activeLayer != null) {
                 // there's an active layer - select it and make it
                 // visible
-                int idx = getLayers().indexOf(getActiveLayer());
+                int idx = getLayers().indexOf(activeLayer);
                 selectionModel.setSelectionInterval(idx, idx);
                 ensureSelectedIsVisible();
@@ -1506,19 +1518,24 @@
         /* ------------------------------------------------------------------------------ */
         @Override
-        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
-            if (oldLayer != null) {
-                int idx = getLayers().indexOf(oldLayer);
-                if (idx >= 0) {
-                    fireTableRowsUpdated(idx,idx);
-                }
-            }
-
-            if (newLayer != null) {
-                int idx = getLayers().indexOf(newLayer);
-                if (idx >= 0) {
-                    fireTableRowsUpdated(idx,idx);
-                }
-            }
-            ensureActiveSelected();
+        public void activeLayerChange(final Layer oldLayer, final Layer newLayer) {
+            GuiHelper.runInEDTAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    if (oldLayer != null) {
+                        int idx = getLayers().indexOf(oldLayer);
+                        if (idx >= 0) {
+                            fireTableRowsUpdated(idx,idx);
+                        }
+                    }
+
+                    if (newLayer != null) {
+                        int idx = getLayers().indexOf(newLayer);
+                        if (idx >= 0) {
+                            fireTableRowsUpdated(idx,idx);
+                        }
+                    }
+                    ensureActiveSelected();
+                }
+            });
         }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 5297)
@@ -8,6 +8,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
 import java.util.Arrays;
 import java.util.Collection;
@@ -20,5 +18,4 @@
 import javax.swing.KeyStroke;
 import javax.swing.ListSelectionModel;
-import javax.swing.SwingUtilities;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
@@ -26,5 +23,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AutoScaleAction;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.actions.ZoomToAction;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MapView;
@@ -33,15 +30,9 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-
-public class MemberTable extends JTable implements IMemberModelListener {
-
-    /**
-     * the data layer in whose context relation members are edited in this table
-     */
-    protected OsmDataLayer layer;
-
-    /** the popup menu */
-    protected JPopupMenu popupMenu;
-    private ZoomToAction zoomToAction;
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable;
+
+public class MemberTable extends OsmPrimitivesTable implements IMemberModelListener {
+
+    /** the additional actions in popup menu */
     private ZoomToGapAction zoomToGap;
 
@@ -54,8 +45,7 @@
     public MemberTable(OsmDataLayer layer, MemberTableModel model) {
         super(model, new MemberTableColumnModel(layer.data), model.getSelectionModel());
-        this.layer = layer;
+        setLayer(layer);
         model.addMemberModelListener(this);
         init();
-
     }
 
@@ -79,7 +69,22 @@
         getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
         getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
-
-        addMouseListener(new PopupListener());
-        addMouseListener(new DblClickHandler());
+    }
+    
+    @Override
+    protected ZoomToAction buildZoomToAction() {
+        return new ZoomToAction(this);
+    }
+    
+    @Override
+    protected JPopupMenu buildPopupMenu() {
+        JPopupMenu menu = super.buildPopupMenu();
+        zoomToGap = new ZoomToGapAction();
+        MapView.addLayerChangeListener(zoomToGap);
+        getSelectionModel().addListSelectionListener(zoomToGap);
+        menu.add(zoomToGap);
+        menu.addSeparator();
+        menu.add(new SelectPreviousGapAction());
+        menu.add(new SelectNextGapAction());
+        return menu;
     }
 
@@ -156,99 +161,8 @@
     }
 
-    /**
-     * Replies the popup menu for this table
-     *
-     * @return the popup menu
-     */
-    protected JPopupMenu getPopUpMenu() {
-        if (popupMenu == null) {
-            popupMenu = new JPopupMenu();
-            zoomToAction = new ZoomToAction();
-            MapView.addLayerChangeListener(zoomToAction);
-            getSelectionModel().addListSelectionListener(zoomToAction);
-            popupMenu.add(zoomToAction);
-            zoomToGap = new ZoomToGapAction();
-            MapView.addLayerChangeListener(zoomToGap);
-            getSelectionModel().addListSelectionListener(zoomToGap);
-            popupMenu.add(zoomToGap);
-            popupMenu.addSeparator();
-            popupMenu.add(new SelectPreviousGapAction());
-            popupMenu.add(new SelectNextGapAction());
-        }
-        return popupMenu;
-    }
-
+    @Override
     public void unlinkAsListener() {
-        MapView.removeLayerChangeListener(zoomToAction);
+        super.unlinkAsListener();
         MapView.removeLayerChangeListener(zoomToGap);
-    }
-
-    class PopupListener extends MouseAdapter {
-        @Override
-        public void mousePressed(MouseEvent e) {
-            showPopup(e);
-        }
-
-        @Override
-        public void mouseReleased(MouseEvent e) {
-            showPopup(e);
-        }
-
-        private void showPopup(MouseEvent e) {
-            if (e.isPopupTrigger()) {
-                getPopUpMenu().show(e.getComponent(), e.getX(), e.getY());
-            }
-        }
-    }
-
-    private class ZoomToAction extends AbstractAction implements LayerChangeListener, ListSelectionListener {
-        public ZoomToAction() {
-            putValue(NAME, tr("Zoom to"));
-            putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to"));
-            updateEnabledState();
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (! isEnabled())
-                return;
-            int rows[] = getSelectedRows();
-            if (rows == null || rows.length == 0)
-                return;
-            int row = rows[0];
-            OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
-            layer.data.setSelected(primitive);
-            AutoScaleAction.autoScale("selection");
-        }
-
-        protected void updateEnabledState() {
-            if (Main.main == null || Main.main.getEditLayer() != layer) {
-                setEnabled(false);
-                putValue(SHORT_DESCRIPTION, tr("Zooming disabled because layer of this relation is not active"));
-                return;
-            }
-            if (getSelectedRowCount() == 0) {
-                setEnabled(false);
-                putValue(SHORT_DESCRIPTION, tr("Zooming disabled because there is no selected member"));
-                return;
-            }
-            setEnabled(true);
-            putValue(SHORT_DESCRIPTION, tr("Zoom to the object the first selected member refers to"));
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-            updateEnabledState();
-        }
-
-        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
-            updateEnabledState();
-        }
-
-        public void layerAdded(Layer newLayer) {
-            updateEnabledState();
-        }
-
-        public void layerRemoved(Layer oldLayer) {
-            updateEnabledState();
-        }
     }
 
@@ -316,9 +230,9 @@
             Way way = (Way) getMemberTableModel().getReferredPrimitive(getSelectedRows()[0]);
             if (!connectionType.linkPrev) {
-                layer.data.setSelected(WayConnectionType.Direction.FORWARD.equals(connectionType.direction)
+                getLayer().data.setSelected(WayConnectionType.Direction.FORWARD.equals(connectionType.direction)
                         ? way.firstNode() : way.lastNode());
                 AutoScaleAction.autoScale("selection");
             } else if (!connectionType.linkNext) {
-                layer.data.setSelected(WayConnectionType.Direction.FORWARD.equals(connectionType.direction)
+                getLayer().data.setSelected(WayConnectionType.Direction.FORWARD.equals(connectionType.direction)
                         ? way.lastNode() : way.firstNode());
                 AutoScaleAction.autoScale("selection");
@@ -328,5 +242,5 @@
         private void updateEnabledState() {
             setEnabled(Main.main != null
-                    && Main.main.getEditLayer() == layer
+                    && Main.main.getEditLayer() == getLayer()
                     && getSelectedRowCount() == 1
                     && hasGap());
@@ -357,33 +271,3 @@
         return (MemberTableModel) getModel();
     }
-
-    private class DblClickHandler extends MouseAdapter {
-
-        protected void setSelection(MouseEvent e) {
-            int row = rowAtPoint(e.getPoint());
-            if (row < 0) return;
-            OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
-            getMemberTableModel().getLayer().data.setSelected(primitive.getPrimitiveId());
-        }
-
-        protected void addSelection(MouseEvent e) {
-            int row = rowAtPoint(e.getPoint());
-            if (row < 0) return;
-            OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
-            getMemberTableModel().getSelectionModel().addSelectionInterval(row, row);
-            getMemberTableModel().getLayer().data.addSelected(primitive.getPrimitiveId());
-
-        }
-
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
-                if (e.isControlDown()) {
-                    addSelection(e);
-                } else {
-                    setSelection(e);
-                }
-            }
-        }
-    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 5297)
@@ -45,6 +45,7 @@
 import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-
-public class MemberTableModel extends AbstractTableModel implements TableModelListener, SelectionChangedListener, DataSetListener {
+import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
+
+public class MemberTableModel extends AbstractTableModel implements TableModelListener, SelectionChangedListener, DataSetListener, OsmPrimitivesTableModel {
 
     /**
@@ -198,4 +199,5 @@
     }
 
+    @Override
     public OsmPrimitive getReferredPrimitive(int idx) {
         return members.get(idx).getMember();
@@ -650,5 +652,5 @@
      * @return the unlinked node if element is a way, the node itself if element is a node, null otherwise
      */
-    private static Node getUnusedNode(RelationMember element, RelationMember linked_element)
+    /*private static Node getUnusedNode(RelationMember element, RelationMember linked_element)
     {
         Node result = null;
@@ -677,5 +679,5 @@
 
         return result;
-    }
+    }*/
 
     /*
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 5297)
@@ -78,4 +78,5 @@
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.DateUtils;
 import org.openstreetmap.josm.tools.FilteredCollection;
@@ -386,8 +387,8 @@
         );
 
-        StringBuffer sb = new StringBuffer();
+        final StringBuffer sb = new StringBuffer();
         sb.append("<html>").append(msg1).append("</html>");
         if (numNewConflicts > 0) {
-            ButtonSpec[] options = new ButtonSpec[] {
+            final ButtonSpec[] options = new ButtonSpec[] {
                     new ButtonSpec(
                             tr("OK"),
@@ -397,16 +398,21 @@
                     )
             };
-            HelpAwareOptionPane.showOptionDialog(
-                    Main.parent,
-                    sb.toString(),
-                    tr("Conflicts detected"),
-                    JOptionPane.WARNING_MESSAGE,
-                    null, /* no icon */
-                    options,
-                    options[0],
-                    ht("/Concepts/Conflict#WarningAboutDetectedConflicts")
-            );
-            Main.map.conflictDialog.unfurlDialog();
-            Main.map.repaint();
+            GuiHelper.runInEDT(new Runnable() {
+                @Override
+                public void run() {
+                    HelpAwareOptionPane.showOptionDialog(
+                            Main.parent,
+                            sb.toString(),
+                            tr("Conflicts detected"),
+                            JOptionPane.WARNING_MESSAGE,
+                            null, /* no icon */
+                            options,
+                            options[0],
+                            ht("/Concepts/Conflict#WarningAboutDetectedConflicts")
+                    );
+                    Main.map.conflictDialog.unfurlDialog();
+                    Main.map.repaint();
+                }
+            });
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java	(revision 5296)
+++ /trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java	(revision 5297)
@@ -7,4 +7,5 @@
 import java.awt.Container;
 import java.awt.Image;
+import java.lang.reflect.InvocationTargetException;
 
 import javax.swing.Icon;
@@ -43,4 +44,18 @@
         }
     }
+
+    public static void runInEDTAndWait(Runnable task) {
+        if (SwingUtilities.isEventDispatchThread()) {
+            task.run();
+        } else {
+            try {
+                SwingUtilities.invokeAndWait(task);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (InvocationTargetException e) {
+                e.printStackTrace();
+            }
+        }
+    }
     
     /**
Index: /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTable.java	(revision 5297)
+++ /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTable.java	(revision 5297)
@@ -0,0 +1,124 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.widgets;
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JPopupMenu;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.table.TableColumnModel;
+
+import org.openstreetmap.josm.actions.ZoomToAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+public abstract class OsmPrimitivesTable extends JTable {
+    
+    /**
+     * the data layer in whose context primitives are edited in this table
+     */
+    private OsmDataLayer layer;
+
+    /** the popup menu */
+    private JPopupMenu popupMenu;
+    private ZoomToAction zoomToAction;
+
+    public final OsmDataLayer getLayer() {
+        return layer;
+    }
+
+    public final void setLayer(OsmDataLayer layer) {
+        this.layer = layer;
+    }
+
+    public OsmPrimitivesTable(OsmPrimitivesTableModel dm, TableColumnModel cm, ListSelectionModel sm) {
+        super(dm, cm, sm);
+        addMouseListener(new PopupListener());
+        addMouseListener(new DblClickHandler());
+    }
+    
+    public OsmPrimitivesTableModel getOsmPrimitivesTableModel() {
+        return (OsmPrimitivesTableModel) getModel();
+    }
+
+    /**
+     * Replies the popup menu for this table
+     *
+     * @return the popup menu
+     */
+    protected final JPopupMenu getPopUpMenu() {
+        if (popupMenu == null) {
+            popupMenu = buildPopupMenu();
+        }
+        return popupMenu;
+    }
+    
+    protected abstract ZoomToAction buildZoomToAction();
+
+    protected JPopupMenu buildPopupMenu() {
+        JPopupMenu menu = new JPopupMenu();
+        zoomToAction = buildZoomToAction();
+        MapView.addLayerChangeListener(zoomToAction);
+        getSelectionModel().addListSelectionListener(zoomToAction);
+        menu.add(zoomToAction);
+        return menu;
+    }
+    
+    public void unlinkAsListener() {
+        MapView.removeLayerChangeListener(zoomToAction);
+    }
+
+    protected class PopupListener extends MouseAdapter {
+        @Override
+        public void mousePressed(MouseEvent e) {
+            showPopup(e);
+        }
+
+        @Override
+        public void mouseReleased(MouseEvent e) {
+            showPopup(e);
+        }
+
+        private void showPopup(MouseEvent e) {
+            if (e.isPopupTrigger()) {
+                getPopUpMenu().show(e.getComponent(), e.getX(), e.getY());
+            }
+        }
+    }
+    
+    protected class DblClickHandler extends MouseAdapter {
+
+        protected void setSelection(MouseEvent e) {
+            int row = rowAtPoint(e.getPoint());
+            if (row < 0) return;
+            OsmPrimitive primitive = getOsmPrimitivesTableModel().getReferredPrimitive(row);
+            if (layer != null && primitive != null) {
+                layer.data.setSelected(primitive.getPrimitiveId());
+            }
+        }
+
+        protected void addSelection(MouseEvent e) {
+            int row = rowAtPoint(e.getPoint());
+            if (row < 0) return;
+            OsmPrimitive primitive = getOsmPrimitivesTableModel().getReferredPrimitive(row);
+            getSelectionModel().addSelectionInterval(row, row);
+            if (layer != null && primitive != null) {
+                layer.data.addSelected(primitive.getPrimitiveId());
+            }
+        }
+
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
+                if (e.isControlDown()) {
+                    addSelection(e);
+                } else {
+                    setSelection(e);
+                }
+            }
+        }
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTableModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTableModel.java	(revision 5297)
+++ /trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitivesTableModel.java	(revision 5297)
@@ -0,0 +1,11 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.widgets;
+
+import javax.swing.table.TableModel;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public interface OsmPrimitivesTableModel extends TableModel {
+    
+    public abstract OsmPrimitive getReferredPrimitive(int idx);
+}
