Index: /trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(revision 5799)
@@ -16,5 +16,5 @@
 public abstract class AbstractRelationAction extends AbstractAction {
     protected Collection<Relation> relations = Collections.<Relation>emptySet();
-    
+
     /**
      * Specifies the working set of relations.
Index: /trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 5799)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 5799)
@@ -0,0 +1,60 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.relation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.event.ActionEvent;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor;
+import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+
+public class AddSelectionToRelations extends AbstractRelationAction implements SelectionChangedListener {
+    /**
+    * Constructs a new <code>AddSelectionToRelation</code>.
+    */
+    public AddSelectionToRelations() {
+        putValue(SMALL_ICON, ImageProvider.get("dialogs/conflict", "copyendright"));
+        putValue(SHORT_DESCRIPTION, tr("Add all objects selected in the current dataset after the last member"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Collection<Command> cmds = new LinkedList<Command>();
+        for (Relation orig : relations) {
+            Command c = GenericRelationEditor.addPrimitivesToRelation(orig, Main.main.getCurrentDataSet().getSelected());
+            if (c != null) {
+                cmds.add(c);
+            }
+        }
+        if (!cmds.isEmpty()) {
+            Main.main.undoRedo.add(new SequenceCommand(tr("Add selection to relation"), cmds));
+        }
+    }
+
+    @Override
+    public void updateEnabledState() {
+        putValue(NAME, trn("Add selection to {0} relation", "Add selection to {0} relations",
+                relations.size(), relations.size()));
+    }
+
+    @Override
+    public void selectionChanged(final Collection<? extends OsmPrimitive> newSelection) {
+        GuiHelper.runInEDT(new Runnable() {
+            @Override
+            public void run() {
+                setEnabled(newSelection != null && !newSelection.isEmpty());
+            }
+        });
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 5799)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 5799)
@@ -0,0 +1,48 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.relation;
+
+import java.awt.event.ActionEvent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+
+/**
+ * Action that delete relations
+ * @since 5799
+ */
+public class DeleteRelationsAction extends AbstractRelationAction {
+    class AbortException extends Exception {}
+
+    /**
+     * Constructs a new <code>DeleteRelationsAction</code>.
+     */
+    public DeleteRelationsAction() {
+        putValue(SHORT_DESCRIPTION,tr("Delete the selected relation"));
+        putValue(NAME, tr("Delete"));
+        putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
+    }
+
+    protected void deleteRelation(Relation toDelete) {
+        if (toDelete == null)
+            return;
+        org.openstreetmap.josm.actions.mapmode.DeleteAction
+                .deleteRelation( Main.main.getEditLayer(), toDelete );
+        // clear selection after deletion
+        if (Main.map.relationListDialog!=null)
+                Main.map.relationListDialog.selectRelations(null);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (!isEnabled() || Main.main.getEditLayer() == null)
+            return;
+        for (Relation r : relations) {
+            deleteRelation(r);
+        }
+    }
+}
+
Index: /trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/DownloadMembersAction.java	(revision 5799)
@@ -13,5 +13,5 @@
 /**
  * The action for downloading members of relations
- * @since 5793
+
  */
 public class DownloadMembersAction extends AbstractRelationAction {
@@ -27,4 +27,5 @@
     }
     
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty() || Main.map==null || Main.map.mapView==null) return;
Index: /trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/DownloadSelectedIncompleteMembersAction.java	(revision 5799)
@@ -43,4 +43,5 @@
     }
 
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty() || Main.map==null || Main.map.mapView==null) return;
Index: /trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 5799)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 5799)
@@ -0,0 +1,49 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.relation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+
+/**
+ * Creates a new relation with a copy of the current editor state
+ * @since 5799
+ */
+public class DuplicateRelationAction extends AbstractRelationAction {
+    public DuplicateRelationAction() {
+        putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window"));
+        putValue(SMALL_ICON, ImageProvider.get("duplicate"));
+        putValue(NAME, tr("Duplicate"));
+    }
+
+    public static void duplicateRelationAndLaunchEditor(Relation original) {
+        Relation copy = new Relation(original, true);
+        copy.setModified(true);
+        RelationEditor editor = RelationEditor.getEditor(
+                Main.main.getEditLayer(),
+                copy,
+                null /* no selected members */
+                );
+        editor.setVisible(true);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (!isEnabled() || relations.size()==0)
+            return;
+        Relation r = relations.iterator().next();
+        duplicateRelationAndLaunchEditor(r);
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        // only one selected relation can be edited
+        setEnabled( relations.size()==1 );
+    }        
+}
Index: /trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 5799)
@@ -63,4 +63,5 @@
     }
 
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.size()!=1) return;
Index: /trunk/src/org/openstreetmap/josm/actions/relation/SelectInRelationListAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/SelectInRelationListAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/SelectInRelationListAction.java	(revision 5799)
@@ -24,7 +24,9 @@
     }
 
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty() || Main.map==null || Main.map.relationListDialog==null) return;
         Main.map.relationListDialog.selectRelations(relations);
+        Main.map.relationListDialog.unfurlDialog();
     }
 }
Index: /trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 5799)
@@ -29,4 +29,5 @@
     }
 
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty() || Main.map==null || Main.map.mapView==null) return;
Index: /trunk/src/org/openstreetmap/josm/gui/SideButton.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 5799)
@@ -20,9 +20,10 @@
 import javax.swing.plaf.basic.BasicArrowButton;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.Destroyable;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.Shortcut;
 
+/**
+ * Button that is usually used in toggle dialogs
+ */
 public class SideButton extends JButton implements Destroyable {
     private final static int iconHeight = 20;
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 5799)
@@ -2,7 +2,5 @@
 package org.openstreetmap.josm.gui.dialogs;
 
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
 
 import java.awt.BorderLayout;
@@ -19,5 +17,4 @@
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -45,13 +42,13 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.relation.AddSelectionToRelations;
+import org.openstreetmap.josm.actions.relation.DeleteRelationsAction;
 import org.openstreetmap.josm.actions.relation.DownloadMembersAction;
 import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction;
+import org.openstreetmap.josm.actions.relation.DuplicateRelationAction;
 import org.openstreetmap.josm.actions.relation.EditRelationAction;
 import org.openstreetmap.josm.actions.relation.SelectMembersAction;
 import org.openstreetmap.josm.actions.relation.SelectRelationAction;
 import org.openstreetmap.josm.actions.search.SearchCompiler;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -73,9 +70,7 @@
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor;
 import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -98,9 +93,5 @@
     private final RelationListModel model;
 
-    /** the delete action */
-    private final DeleteAction deleteAction;
     private final NewAction newAction;
-    private final AddToRelation addToRelation;
-    private final DuplicateAction duplicateAction;
     
     /** the popup menu */
@@ -111,5 +102,9 @@
     // Actions
     /** the edit action */
-    private final EditRelationAction editAction;
+    private final EditRelationAction editAction = new EditRelationAction();
+    /** the delete action */
+    private final DeleteRelationsAction deleteRelationsAction = new DeleteRelationsAction();
+    /** the duplicate action */
+    private final DuplicateRelationAction duplicateAction = new DuplicateRelationAction();
     private final DownloadMembersAction downloadMembersAction = new DownloadMembersAction();
     private final DownloadSelectedIncompleteMembersAction downloadSelectedIncompleteMembersAction = new DownloadSelectedIncompleteMembersAction();
@@ -118,7 +113,9 @@
     private final SelectRelationAction selectRelationAction = new SelectRelationAction(false);
     private final SelectRelationAction addRelationToSelectionAction = new SelectRelationAction(true);
-
+    /** add all selected primitives to the given realtions */
+    private final AddSelectionToRelations addSelectionToRelations = new AddSelectionToRelations();
+    
     /**
-     * constructor
+     * Constructs <code>RelationListDialog</code>
      */
     public RelationListDialog() {
@@ -149,20 +146,4 @@
         newAction = new NewAction();
 
-        // the edit action
-        //
-        editAction = new EditRelationAction();
-        
-        // the duplicate action
-        //
-        duplicateAction = new DuplicateAction();
-        
-        // the delete action
-        //
-        deleteAction = new DeleteAction();
-
-        // Add to realaion action
-        //
-        addToRelation = new AddToRelation();
-
         filter = setupFilter();
 
@@ -170,20 +151,5 @@
             @Override
             public void valueChanged(ListSelectionEvent e) {
-                duplicateAction.valueChanged(e);
-                deleteAction.valueChanged(e);
-                addToRelation.valueChanged(e);
-
-                List<Relation> rels;
-                rels = model.getSelectedNonNewRelations();
-                downloadMembersAction.setRelations(rels);
-
-                rels = model.getSelectedRelationsWithIncompleteMembers();
-                downloadSelectedIncompleteMembersAction.setRelations(rels); 
-
-                rels = model.getSelectedRelations();
-                selectMemebersAction.setRelations(rels);
-                addMembersToSelectionAction.setRelations(rels);
-                selectRelationAction.setRelations(rels);
-                addRelationToSelectionAction.setRelations(rels);
+                updateActionsRelationLists();
             }
         });
@@ -196,5 +162,5 @@
                 new SideButton(editAction, false),
                 new SideButton(duplicateAction, false),
-                new SideButton(deleteAction, false),
+                new SideButton(deleteRelationsAction, false),
                 new SideButton(selectRelationAction, false)
         }));
@@ -214,4 +180,26 @@
         displaylist.getActionMap().put("edit", editAction);
         displaylist.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK), "edit");
+        
+        updateActionsRelationLists();
+    }
+    
+    // inform all actions about list of relations they need
+    private void updateActionsRelationLists() {
+        List<Relation> rels;
+        rels = model.getSelectedNonNewRelations();
+        downloadMembersAction.setRelations(rels);
+
+        rels = model.getSelectedRelationsWithIncompleteMembers();
+        downloadSelectedIncompleteMembersAction.setRelations(rels); 
+
+        rels = model.getSelectedRelations();
+        editAction.setRelations(rels);
+        deleteRelationsAction.setRelations(rels);
+        addSelectionToRelations.setRelations(rels);
+        selectMemebersAction.setRelations(rels);
+        addMembersToSelectionAction.setRelations(rels);
+        selectRelationAction.setRelations(rels);
+        addRelationToSelectionAction.setRelations(rels);
+        duplicateAction.setRelations(rels);
     }
     
@@ -220,5 +208,5 @@
         newAction.updateEnabledState();
         DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT);
-        DataSet.addSelectionListener(addToRelation);
+        DataSet.addSelectionListener(addSelectionToRelations);
         dataChanged(null);
     }
@@ -227,5 +215,5 @@
         MapView.removeLayerChangeListener(newAction);
         DatasetEventManager.getInstance().removeDatasetListener(this);
-        DataSet.removeSelectionListener(addToRelation);
+        DataSet.removeSelectionListener(addSelectionToRelations);
     }
     
@@ -250,4 +238,5 @@
         model.setRelations(l.data.getRelations());
         model.updateTitle();
+        updateActionsRelationLists();
     }
 
@@ -367,45 +356,4 @@
     
     /**
-     * The delete action
-     *
-     */
-    class DeleteAction extends AbstractAction implements ListSelectionListener {
-        class AbortException extends Exception {}
-
-        public DeleteAction() {
-            putValue(SHORT_DESCRIPTION,tr("Delete the selected relation"));
-            putValue(NAME, tr("Delete"));
-            putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
-            setEnabled(false);
-        }
-
-        protected void deleteRelation(Relation toDelete) {
-            if (toDelete == null)
-                return;
-            org.openstreetmap.josm.actions.mapmode.DeleteAction.deleteRelation(
-                    Main.main.getEditLayer(),
-                    toDelete
-                    );
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled())
-                return;
-            List<Relation> toDelete = new LinkedList<Relation>();
-            for (int i : displaylist.getSelectedIndices()) {
-                toDelete.add(model.getVisibleRelation(i));
-            }
-            for (Relation r : toDelete) {
-                deleteRelation(r);
-            }
-            displaylist.clearSelection();
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-            setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length > 0);
-        }
-    }
-
-    /**
      * The action for creating a new relation
      *
@@ -423,4 +371,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             run();
@@ -431,91 +380,17 @@
         }
 
+        @Override
         public void activeLayerChange(Layer oldLayer, Layer newLayer) {
             updateEnabledState();
-        }
-
+    }
+
+        @Override
         public void layerAdded(Layer newLayer) {
             updateEnabledState();
         }
 
+        @Override
         public void layerRemoved(Layer oldLayer) {
             updateEnabledState();
-        }
-    }
-
-    /**
-     * Creates a new relation with a copy of the current editor state
-     *
-     */
-    class DuplicateAction extends AbstractAction implements ListSelectionListener {
-        public DuplicateAction() {
-            putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window"));
-            putValue(SMALL_ICON, ImageProvider.get("duplicate"));
-            putValue(NAME, tr("Duplicate"));
-            updateEnabledState();
-        }
-
-        public void launchEditorForDuplicate(Relation original) {
-            Relation copy = new Relation(original, true);
-            copy.setModified(true);
-            RelationEditor editor = RelationEditor.getEditor(
-                    Main.main.getEditLayer(),
-                    copy,
-                    null /* no selected members */
-                    );
-            editor.setVisible(true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled())
-                return;
-            launchEditorForDuplicate(getSelected());
-        }
-
-        protected void updateEnabledState() {
-            setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length == 1);
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-            updateEnabledState();
-        }
-    }
-
-    class AddToRelation extends AbstractAction implements ListSelectionListener, SelectionChangedListener {
-
-        public AddToRelation() {
-            super("", ImageProvider.get("dialogs/conflict", "copyendright"));
-            putValue(SHORT_DESCRIPTION, tr("Add all objects selected in the current dataset after the last member"));
-            setEnabled(false);
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            Collection<Command> cmds = new LinkedList<Command>();
-            for (Relation orig : getSelectedRelations()) {
-                Command c = GenericRelationEditor.addPrimitivesToRelation(orig, Main.main.getCurrentDataSet().getSelected());
-                if (c != null) {
-                    cmds.add(c);
-                }
-            }
-            if (!cmds.isEmpty()) {
-                Main.main.undoRedo.add(new SequenceCommand(tr("Add selection to relation"), cmds));
-            }
-        }
-
-        @Override
-        public void valueChanged(ListSelectionEvent e) {
-            putValue(NAME, trn("Add selection to {0} relation", "Add selection to {0} relations",
-                    getSelectedRelations().size(), getSelectedRelations().size()));
-        }
-
-        @Override
-        public void selectionChanged(final Collection<? extends OsmPrimitive> newSelection) {
-            GuiHelper.runInEDT(new Runnable() {
-                @Override
-                public void run() {
-                    setEnabled(newSelection != null && !newSelection.isEmpty());
-                }
-            });
         }
     }
@@ -802,7 +677,11 @@
             addSeparator();
 
-            add(addToRelation);
-        }
-    }
+            add(addSelectionToRelations);
+        }
+    }
+
+    /* ---------------------------------------------------------------------------------- */
+    /* Methods that can be called from plugins                                                                    */
+    /* ---------------------------------------------------------------------------------- */
 
     public void addPopupMenuSeparator() {
@@ -830,8 +709,11 @@
     /* ---------------------------------------------------------------------------------- */
 
+    @Override
     public void nodeMoved(NodeMovedEvent event) {/* irrelevant in this context */}
 
+    @Override
     public void wayNodesChanged(WayNodesChangedEvent event) {/* irrelevant in this context */}
 
+    @Override
     public void primitivesAdded(final PrimitivesAddedEvent event) {
         model.addRelations(event.getPrimitives());
@@ -839,4 +721,5 @@
     }
 
+    @Override
     public void primitivesRemoved(final PrimitivesRemovedEvent event) {
         model.removeRelations(event.getPrimitives());
@@ -844,4 +727,5 @@
     }
 
+    @Override
     public void relationMembersChanged(final RelationMembersChangedEvent event) {
         List<Relation> sel = model.getSelectedRelations();
@@ -851,4 +735,5 @@
     }
 
+    @Override
     public void tagsChanged(TagsChangedEvent event) {
         OsmPrimitive prim = event.getPrimitive();
@@ -864,8 +749,10 @@
     }
 
+    @Override
     public void dataChanged(DataChangedEvent event) {
         initFromLayer(Main.main.getEditLayer());
     }
 
+    @Override
     public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */}
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 5799)
@@ -110,4 +110,5 @@
         lstPrimitives.getSelectionModel().addListSelectionListener(actSelect);
         selectButton.createArrow(new ActionListener() {
+            @Override
             public void actionPerformed(ActionEvent e) {
                 SelectionHistoryPopup.launch(selectButton, model.getSelectionHistory());
@@ -118,4 +119,5 @@
         final SideButton searchButton = new SideButton(actSearch = new SearchAction());
         searchButton.createArrow(new ActionListener() {
+            @Override
             public void actionPerformed(ActionEvent e) {
                 SearchPopupMenu.launch(searchButton);
@@ -318,4 +320,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             Collection<OsmPrimitive> sel = model.getSelected();
@@ -329,4 +332,5 @@
         }
 
+        @Override
         public void valueChanged(ListSelectionEvent e) {
             updateEnabledState();
@@ -487,8 +491,10 @@
         }
 
+        @Override
         public Object getElementAt(int index) {
             return selection.get(index);
         }
 
+        @Override
         public int getSize() {
             return selection.size();
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 5798)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 5799)
@@ -23,5 +23,4 @@
 import java.util.EnumSet;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -81,5 +80,4 @@
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
 import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel.PresetHandler;
-import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask;
 import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
@@ -113,61 +111,35 @@
  */
 public class PropertiesDialog extends ToggleDialog implements SelectionChangedListener, MapView.EditLayerChangeListener, DataSetListenerAdapter.Listener {
-    /**
-     * Watches for mouse clicks
-     * @author imi
-     */
-    public class MouseClickWatch extends MouseAdapter {
-        @Override public void mouseClicked(MouseEvent e) {
-            if (e.getClickCount() < 2)
-            {
-                // single click, clear selection in other table not clicked in
-                if (e.getSource() == propertyTable) {
-                    membershipTable.clearSelection();
-                } else if (e.getSource() == membershipTable) {
-                    propertyTable.clearSelection();
-                }
-            }
-            // double click, edit or add property
-            else if (e.getSource() == propertyTable)
-            {
-                int row = propertyTable.rowAtPoint(e.getPoint());
-                if (row > -1) {
-                    boolean focusOnKey = (propertyTable.columnAtPoint(e.getPoint()) == 0);
-                    editHelper.editProperty(row, focusOnKey);
-                } else {
-                    editHelper.addProperty();
-                    btnAdd.requestFocusInWindow();
-                }
-            } else if (e.getSource() == membershipTable) {
-                int row = membershipTable.rowAtPoint(e.getPoint());
-                if (row > -1) {
-                    editMembership(row);
-                }
-            }
-            else
-            {
-                editHelper.addProperty();
-                btnAdd.requestFocusInWindow();
-            }
-        }
-        @Override public void mousePressed(MouseEvent e) {
-            if (e.getSource() == propertyTable) {
-                membershipTable.clearSelection();
-            } else if (e.getSource() == membershipTable) {
-                propertyTable.clearSelection();
-            }
-        }
-
-    }
-
     // hook for roadsigns plugin to display a small
     // button in the upper right corner of this dialog
     public static final JPanel pluginHook = new JPanel();
 
+    /**
+     * The property data of selected objects.
+     */
+    private final DefaultTableModel propertyData = new ReadOnlyTableModel();
+
+    /**
+     * The membership data of selected objects.
+     */
+    private final DefaultTableModel membershipData = new ReadOnlyTableModel();
+
+    /**
+     * The properties table.
+     */
+    private final JTable propertyTable = new JTable(propertyData);
+    /**
+     * The membership table.
+     */
+    private final JTable membershipTable = new JTable(membershipData);
+
     private JPopupMenu propertyMenu;
     private JPopupMenu membershipMenu;
 
     private final Map<String, Map<String, Integer>> valueCount = new TreeMap<String, Map<String, Integer>>();
-
+    /**
+     * This sub-object is responsible for all adding and editing of properties
+     */
+    private final TagEditHelper editHelper = new TagEditHelper(propertyData, valueCount);
     
     private final DataSetListenerAdapter dataChangedAdapter = new DataSetListenerAdapter(this);
@@ -190,95 +162,21 @@
     private final SelectRelationAction selectRelationAction = new SelectRelationAction(false);
     
-    @Override
-    public void showNotify() {
-        DatasetEventManager.getInstance().addDatasetListener(dataChangedAdapter, FireMode.IN_EDT_CONSOLIDATED);
-        SelectionEventManager.getInstance().addSelectionListener(this, FireMode.IN_EDT_CONSOLIDATED);
-        MapView.addEditLayerChangeListener(this);
-        for (JosmAction action : josmActions) {
-            Main.registerActionShortcut(action);
-        }
-        updateSelection();
-    }
-
-    @Override
-    public void hideNotify() {
-        DatasetEventManager.getInstance().removeDatasetListener(dataChangedAdapter);
-        SelectionEventManager.getInstance().removeSelectionListener(this);
-        MapView.removeEditLayerChangeListener(this);
-        for (JosmAction action : josmActions) {
-            Main.unregisterActionShortcut(action);
-        }
-    }
-
-    /**
-     * This simply fires up an {@link RelationEditor} for the relation shown; everything else
-     * is the editor's business.
-     *
-     * @param row
-     */
-    private void editMembership(int row) {
-        Relation relation = (Relation)membershipData.getValueAt(row, 0);
-        Main.map.relationListDialog.selectRelation(relation);
-        RelationEditor.getEditor(
-                Main.map.mapView.getEditLayer(),
-                relation,
-                ((MemberInfo) membershipData.getValueAt(row, 1)).role).setVisible(true);
-    }
-
-    /**
-     * The property data of selected objects.
-     */
-    private final DefaultTableModel propertyData = new DefaultTableModel() {
-        @Override public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-        @Override public Class<?> getColumnClass(int columnIndex) {
-            return String.class;
-        }
-    };
-
-    /**
-     * The membership data of selected objects.
-     */
-    private final DefaultTableModel membershipData = new DefaultTableModel() {
-        @Override public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-        @Override public Class<?> getColumnClass(int columnIndex) {
-            return String.class;
-        }
-    };
-
-    /**
-     * The properties table.
-     */
-    private final JTable propertyTable = new JTable(propertyData);
-    /**
-     * The membership table.
-     */
-    private final JTable membershipTable = new JTable(membershipData);
-
-    /**
-     * This sub-object is responsible for all adding and editing of properties
-     */
-    private final TagEditHelper editHelper = new TagEditHelper(propertyData, valueCount);
-    
     /**
      * The Add button (needed to be able to disable it)
      */
-    private final SideButton btnAdd;
+    private final SideButton btnAdd = new SideButton(addAction);
     /**
      * The Edit button (needed to be able to disable it)
      */
-    private final SideButton btnEdit;
+    private final SideButton btnEdit = new SideButton(editAction);
     /**
      * The Delete button (needed to be able to disable it)
      */
-    private final SideButton btnDel;
+    private final SideButton btnDel = new SideButton(deleteAction);
     /**
      * Matching preset display class
      */
     private final PresetListPanel presets = new PresetListPanel();
-
+    
     /**
      * Text to display when nothing selected.
@@ -287,42 +185,19 @@
             + tr("Select objects for which to change properties.") + "</p></html>");
 
-    static class MemberInfo {
-        List<RelationMember> role = new ArrayList<RelationMember>();
-        List<Integer> position = new ArrayList<Integer>();
-        private String positionString = null;
-        void add(RelationMember r, Integer p) {
-            role.add(r);
-            position.add(p);
-        }
-        String getPositionString() {
-            if (positionString == null) {
-                Collections.sort(position);
-                positionString = String.valueOf(position.get(0));
-                int cnt = 0;
-                int last = position.get(0);
-                for (int i = 1; i < position.size(); ++i) {
-                    int cur = position.get(i);
-                    if (cur == last + 1) {
-                        ++cnt;
-                    } else if (cnt == 0) {
-                        positionString += "," + String.valueOf(cur);
-                    } else {
-                        positionString += "-" + String.valueOf(last);
-                        positionString += "," + String.valueOf(cur);
-                        cnt = 0;
-                    }
-                    last = cur;
-                }
-                if (cnt >= 1) {
-                    positionString += "-" + String.valueOf(last);
-                }
-            }
-            if (positionString.length() > 20) {
-                positionString = positionString.substring(0, 17) + "...";
-            }
-            return positionString;
-        }
-    }
-
+    private PresetHandler presetHandler = new PresetHandler() {
+        @Override public void updateTags(List<Tag> tags) {
+            Command command = TaggingPreset.createCommand(getSelection(), tags);
+            if (command != null) Main.main.undoRedo.add(command);
+        }
+
+        @Override public Collection<OsmPrimitive> getSelection() {
+            if (Main.main == null) return null;
+            if (Main.main.getCurrentDataSet() == null) return null;
+            return Main.main.getCurrentDataSet().getSelected();
+        }
+    };
+    
+    // <editor-fold defaultstate="collapsed" desc="Dialog construction and helper methods">
+    
     /**
      * Create a new PropertiesDialog
@@ -333,31 +208,59 @@
                         Shortcut.ALT_SHIFT), 150, true);
 
+        setupPropertiesMenu();
+        buildPropertiesTable();
+
+        setupMembershipMenu();
+        buildMembershipTable();
+        
+        // combine both tables and wrap them in a scrollPane
+        JPanel bothTables = new JPanel();
+        boolean top = Main.pref.getBoolean("properties.presets.top", true);
+        bothTables.setLayout(new GridBagLayout());
+        if(top) {
+            bothTables.add(presets, GBC.std().fill(GBC.HORIZONTAL).insets(5, 2, 5, 2).anchor(GBC.NORTHWEST));
+            double epsilon = Double.MIN_VALUE; // need to set a weight or else anchor value is ignored
+            bothTables.add(pluginHook, GBC.eol().insets(0,1,1,1).anchor(GBC.NORTHEAST).weight(epsilon, epsilon));
+        }
+        bothTables.add(selectSth, GBC.eol().fill().insets(10, 10, 10, 10));
+        bothTables.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
+        bothTables.add(propertyTable, GBC.eol().fill(GBC.BOTH));
+        bothTables.add(membershipTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
+        bothTables.add(membershipTable, GBC.eol().fill(GBC.BOTH));
+        if(!top) {
+            bothTables.add(presets, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 2, 5, 2));
+        }
+        
+        setupKeyboardShortcuts();
+
+        // Let the action know when selection in the tables change
+        propertyTable.getSelectionModel().addListSelectionListener(editAction);
+        membershipTable.getSelectionModel().addListSelectionListener(editAction);
+        propertyTable.getSelectionModel().addListSelectionListener(deleteAction);
+        membershipTable.getSelectionModel().addListSelectionListener(deleteAction);
+        
+
+        JScrollPane scrollPane = (JScrollPane) createLayout(bothTables, true, Arrays.asList(new SideButton[] {
+                this.btnAdd, this.btnEdit, this.btnDel
+        }));
+
+        MouseClickWatch mouseClickWatch = new MouseClickWatch();
+        propertyTable.addMouseListener(mouseClickWatch);
+        membershipTable.addMouseListener(mouseClickWatch);
+        scrollPane.addMouseListener(mouseClickWatch);
+
+        selectSth.setPreferredSize(scrollPane.getSize());
+        presets.setSize(scrollPane.getSize());
+
+        editHelper.loadTagsIfNeeded();
+    }
+        
+    private void buildPropertiesTable() {
         // setting up the properties table
-        propertyMenu = new JPopupMenu();
-        propertyMenu.add(pasteValueAction);
-        propertyMenu.add(copyValueAction);
-        propertyMenu.add(copyKeyValueAction);
-        propertyMenu.add(copyAllKeyValueAction);
-        propertyMenu.addSeparator();
-        propertyMenu.add(searchActionAny);
-        propertyMenu.add(searchActionSame);
-        propertyMenu.addSeparator();
-        propertyMenu.add(helpAction);
 
         propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
         propertyTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
         propertyTable.getTableHeader().setReorderingAllowed(false);
-        propertyTable.addMouseListener(new PopupMenuLauncher() {
-            @Override
-            public void launch(MouseEvent evt) {
-                Point p = evt.getPoint();
-                int row = propertyTable.rowAtPoint(p);
-                if (row > -1) {
-                    propertyTable.changeSelection(row, 0, false, false);
-                    propertyMenu.show(propertyTable, p.x, p.y-3);
-                }
-            }
-        });
-
+        
         propertyTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer(){
             @Override public Component getTableCellRendererComponent(JTable table, Object value,
@@ -385,37 +288,9 @@
             }
         });
-
-        // setting up the membership table
-        membershipMenu = new JPopupMenu();
-        membershipMenu.add(addRelationToSelectionAction);
-        membershipMenu.add(selectRelationAction);
-        membershipMenu.add(addMembersToSelectionAction);
-        membershipMenu.add(downloadSelectedIncompleteMembersAction);
-        membershipMenu.addSeparator();
-        membershipMenu.add(helpAction);
-
+    }
+
+    private void buildMembershipTable() {
         membershipData.setColumnIdentifiers(new String[]{tr("Member Of"),tr("Role"),tr("Position")});
         membershipTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-        membershipTable.addMouseListener(new PopupMenuLauncher() {
-            @Override
-            public void launch(MouseEvent evt) {
-                Point p = evt.getPoint();
-                int row = membershipTable.rowAtPoint(p);
-                membershipTable.changeSelection(row, 0, false, false);
-                int idx[] = membershipTable.getSelectedRows();
-                List<Relation> rels =  new ArrayList<Relation>(10);
-                if (idx!=null) {
-                    for (int i: idx) {
-                        Relation r = (Relation) (membershipData.getValueAt(i, 0));
-                        rels.add(r);
-                    }
-                }
-                selectRelationAction.setRelations(rels);
-                addMembersToSelectionAction.setRelations(rels);
-                addMembersToSelectionAction.setRelations(rels);
-                downloadSelectedIncompleteMembersAction.setRelations(rels);
-                membershipMenu.show(membershipTable, p.x, p.y-3);
-            }
-        });
 
         TableColumnModel mod = membershipTable.getColumnModel();
@@ -488,24 +363,77 @@
         mod.getColumn(1).setPreferredWidth(40);
         mod.getColumn(0).setPreferredWidth(200);
-
-        // combine both tables and wrap them in a scrollPane
-        JPanel bothTables = new JPanel();
-        boolean top = Main.pref.getBoolean("properties.presets.top", true);
-        bothTables.setLayout(new GridBagLayout());
-        if(top) {
-            bothTables.add(presets, GBC.std().fill(GBC.HORIZONTAL).insets(5, 2, 5, 2).anchor(GBC.NORTHWEST));
-            double epsilon = Double.MIN_VALUE; // need to set a weight or else anchor value is ignored
-            bothTables.add(pluginHook, GBC.eol().insets(0,1,1,1).anchor(GBC.NORTHEAST).weight(epsilon, epsilon));
-        }
-        bothTables.add(selectSth, GBC.eol().fill().insets(10, 10, 10, 10));
-        bothTables.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
-        bothTables.add(propertyTable, GBC.eol().fill(GBC.BOTH));
-        bothTables.add(membershipTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
-        bothTables.add(membershipTable, GBC.eol().fill(GBC.BOTH));
-        if(!top) {
-            bothTables.add(presets, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 2, 5, 2));
-        }
+    }
+    
+    /**
+     * creates the popup menu @field membershipMenu and its launcher on membership table
+     */
+    private void setupMembershipMenu() {
+        // setting up the membership table
+        membershipMenu = new JPopupMenu();
+        membershipMenu.add(addRelationToSelectionAction);
+        membershipMenu.add(selectRelationAction);
+        membershipMenu.add(addMembersToSelectionAction);
+        membershipMenu.add(downloadSelectedIncompleteMembersAction);
+        membershipMenu.addSeparator();
+        membershipMenu.add(helpAction);
+
+        membershipTable.addMouseListener(new PopupMenuLauncher() {
+            @Override
+            public void launch(MouseEvent evt) {
+                Point p = evt.getPoint();
+                int row = membershipTable.rowAtPoint(p);
+                int idx[] = membershipTable.getSelectedRows();
+                // if nothing or one row is selected, select row under mouse instead
+                if (idx.length<2 && row>-1) { 
+                    membershipTable.changeSelection(row, 0, false, false);
+                    idx = new int[]{row};
+                }
+                List<Relation> rels =  new ArrayList<Relation>(10);
+                for (int i: idx) {
+                    Relation r = (Relation) (membershipData.getValueAt(i, 0));
+                    rels.add(r);
+                }
+                selectRelationAction.setRelations(rels);
+                addMembersToSelectionAction.setRelations(rels);
+                addMembersToSelectionAction.setRelations(rels);
+                downloadSelectedIncompleteMembersAction.setRelations(rels);
+                membershipMenu.show(membershipTable, p.x, p.y-3);
+            }
+        });
+    }
+    
+    /**
+     * creates the popup menu @field propertyMenu and its launcher on property table 
+     */
+    private void setupPropertiesMenu() {
+        propertyMenu = new JPopupMenu();
+        propertyMenu.add(pasteValueAction);
+        propertyMenu.add(copyValueAction);
+        propertyMenu.add(copyKeyValueAction);
+        propertyMenu.add(copyAllKeyValueAction);
+        propertyMenu.addSeparator();
+        propertyMenu.add(searchActionAny);
+        propertyMenu.add(searchActionSame);
+        propertyMenu.addSeparator();
+        propertyMenu.add(helpAction);
+        propertyTable.addMouseListener(new PopupMenuLauncher() {
+            @Override
+            public void launch(MouseEvent evt) {
+                Point p = evt.getPoint();
+                int row = propertyTable.rowAtPoint(p);
+                if (row > -1) {
+                    propertyTable.changeSelection(row, 0, false, false);
+                    propertyMenu.show(propertyTable, p.x, p.y-3);
+                }
+            }
+        });
+    }
+    
+    /**
+     * Assignas all needed keys like Enter and Spacebar to most important actions
+     */
+    private void setupKeyboardShortcuts() {
         
-        // Open edit dialog whe enter pressed in tables
+        // ENTER = editAction, open "edit" dialog
         propertyTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"onTableEnter");
@@ -515,50 +443,83 @@
         membershipTable.getActionMap().put("onTableEnter",editAction);
         
-        // Open add property dialog when INS is pressed in tables
+        // INSERT button = addAction, open "add property" dialog 
         propertyTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0),"onTableInsert");
         propertyTable.getActionMap().put("onTableInsert",addAction);
         
-        //  unassign some standard shortcuts for JTable to allow upload / download
+        // unassign some standard shortcuts for JTable to allow upload / download
         InputMapUtils.unassignCtrlShiftUpDown(propertyTable, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+        // allow using enter to add tags for all look&feel configurations
+        InputMapUtils.enableEnter(this.btnAdd);
         
-        // -- add action and shortcut
-        this.btnAdd = new SideButton(addAction);
-        InputMapUtils.enableEnter(this.btnAdd);
-
-        // -- edit action
-        //
-        propertyTable.getSelectionModel().addListSelectionListener(editAction);
-        membershipTable.getSelectionModel().addListSelectionListener(editAction);
-        this.btnEdit = new SideButton(editAction);
-
-        // -- delete action
-        //
-        this.btnDel = new SideButton(deleteAction);
-        membershipTable.getSelectionModel().addListSelectionListener(deleteAction);
-        propertyTable.getSelectionModel().addListSelectionListener(deleteAction);
+        // DEL button = deleteAction
         getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                 KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),"delete"
                 );
         getActionMap().put("delete", deleteAction);
-
-        JScrollPane scrollPane = (JScrollPane) createLayout(bothTables, true, Arrays.asList(new SideButton[] {
-                this.btnAdd, this.btnEdit, this.btnDel
-        }));
-
-        MouseClickWatch mouseClickWatch = new MouseClickWatch();
-        propertyTable.addMouseListener(mouseClickWatch);
-        membershipTable.addMouseListener(mouseClickWatch);
-        scrollPane.addMouseListener(mouseClickWatch);
-
-        selectSth.setPreferredSize(scrollPane.getSize());
-        presets.setSize(scrollPane.getSize());
-
-        editHelper.loadTagsIfNeeded();
-        // -- help action
-        //
+        
+        // F1 button = custom help action
         getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                 KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), "onHelp");
         getActionMap().put("onHelp", helpAction);
+    }
+    
+         /**
+     * This simply fires up an {@link RelationEditor} for the relation shown; everything else
+     * is the editor's business.
+     *
+     * @param row
+     */
+    private void editMembership(int row) {
+        Relation relation = (Relation)membershipData.getValueAt(row, 0);
+        Main.map.relationListDialog.selectRelation(relation);
+        RelationEditor.getEditor(
+                Main.map.mapView.getEditLayer(),
+                relation,
+                ((MemberInfo) membershipData.getValueAt(row, 1)).role).setVisible(true);
+    }
+    
+    private int findRow(TableModel model, Object value) {
+        for (int i=0; i<model.getRowCount(); i++) {
+            if (model.getValueAt(i, 0).equals(value))
+                return i;
+        }
+        return -1;
+    }
+    
+    /**
+     * Update selection status, call @{link #selectionChanged} function.
+     */
+    private void updateSelection() {
+        if (Main.main.getCurrentDataSet() == null) {
+            selectionChanged(Collections.<OsmPrimitive>emptyList());
+        } else {
+            selectionChanged(Main.main.getCurrentDataSet().getSelected());
+        }
+    }
+    
+   // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Event listeners methods">
+    
+    @Override
+    public void showNotify() {
+        DatasetEventManager.getInstance().addDatasetListener(dataChangedAdapter, FireMode.IN_EDT_CONSOLIDATED);
+        SelectionEventManager.getInstance().addSelectionListener(this, FireMode.IN_EDT_CONSOLIDATED);
+        MapView.addEditLayerChangeListener(this);
+        for (JosmAction action : josmActions) {
+            Main.registerActionShortcut(action);
+        }
+        updateSelection();
+    }
+
+    @Override
+    public void hideNotify() {
+        DatasetEventManager.getInstance().removeDatasetListener(dataChangedAdapter);
+        SelectionEventManager.getInstance().removeSelectionListener(this);
+        MapView.removeEditLayerChangeListener(this);
+        for (JosmAction action : josmActions) {
+            Main.unregisterActionShortcut(action);
+        }
     }
 
@@ -570,31 +531,16 @@
         }
     }
-
-    private int findRow(TableModel model, Object value) {
-        for (int i=0; i<model.getRowCount(); i++) {
-            if (model.getValueAt(i, 0).equals(value))
-                return i;
-        }
-        return -1;
-    }
-
-    private PresetHandler presetHandler = new PresetHandler() {
-
-        @Override
-        public void updateTags(List<Tag> tags) {
-            Command command = TaggingPreset.createCommand(getSelection(), tags);
-            if (command != null) {
-                Main.main.undoRedo.add(command);
-            }
-        }
-
-        @Override
-        public Collection<OsmPrimitive> getSelection() {
-            if (Main.main == null) return null;
-            if (Main.main.getCurrentDataSet() == null) return null;
-
-            return Main.main.getCurrentDataSet().getSelected();
-        }
-    };
+    
+    @Override
+    public void destroy() {
+        super.destroy();
+        for (JosmAction action : josmActions) {
+            action.destroy();
+        }
+        Container parent = pluginHook.getParent();
+        if (parent != null) {
+            parent.remove(pluginHook);
+        }
+    }
 
     @Override
@@ -725,16 +671,5 @@
         }
     }
-
-    /**
-     * Update selection status, call @{link #selectionChanged} function.
-     */
-    private void updateSelection() {
-        if (Main.main.getCurrentDataSet() == null) {
-            selectionChanged(Collections.<OsmPrimitive>emptyList());
-        } else {
-            selectionChanged(Main.main.getCurrentDataSet().getSelected());
-        }
-    }
-
+    
     /* ---------------------------------------------------------------------------------- */
     /* EditLayerChangeListener                                                            */
@@ -753,4 +688,154 @@
     }
 
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Methods that are called by plugins to extend fuctionalty ">
+    public void addPropertyPopupMenuSeparator() {
+        propertyMenu.addSeparator();
+    }
+
+    public JMenuItem addPropertyPopupMenuAction(Action a) {
+        return propertyMenu.add(a);
+    }
+
+    public void addPropertyPopupMenuListener(PopupMenuListener l) {
+        propertyMenu.addPopupMenuListener(l);
+    }
+
+    public void removePropertyPopupMenuListener(PopupMenuListener l) {
+        propertyMenu.addPopupMenuListener(l);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Tag getSelectedProperty() {
+        int row = propertyTable.getSelectedRow();
+        if (row == -1) return null;
+        TreeMap<String, Integer> map = (TreeMap<String, Integer>) propertyData.getValueAt(row, 1);
+        return new Tag(
+                propertyData.getValueAt(row, 0).toString(),
+                map.size() > 1 ? "" : map.keySet().iterator().next());
+    }
+
+    public void addMembershipPopupMenuSeparator() {
+        membershipMenu.addSeparator();
+    }
+
+    public JMenuItem addMembershipPopupMenuAction(Action a) {
+        return membershipMenu.add(a);
+    }
+
+    public void addMembershipPopupMenuListener(PopupMenuListener l) {
+        membershipMenu.addPopupMenuListener(l);
+    }
+
+    public void removeMembershipPopupMenuListener(PopupMenuListener l) {
+        membershipMenu.addPopupMenuListener(l);
+    }
+
+    public IRelation getSelectedMembershipRelation() {
+        int row = membershipTable.getSelectedRow();
+        return row > -1 ? (IRelation) membershipData.getValueAt(row, 0) : null;
+    }
+        
+    // </editor-fold>
+    
+     /**
+     * Class that watches for mouse clicks
+     * @author imi
+     */
+    public class MouseClickWatch extends MouseAdapter {
+        @Override public void mouseClicked(MouseEvent e) {
+            if (e.getClickCount() < 2)
+            {
+                // single click, clear selection in other table not clicked in
+                if (e.getSource() == propertyTable) {
+                    membershipTable.clearSelection();
+                } else if (e.getSource() == membershipTable) {
+                    propertyTable.clearSelection();
+                }
+            }
+            // double click, edit or add property
+            else if (e.getSource() == propertyTable)
+            {
+                int row = propertyTable.rowAtPoint(e.getPoint());
+                if (row > -1) {
+                    boolean focusOnKey = (propertyTable.columnAtPoint(e.getPoint()) == 0);
+                    editHelper.editProperty(row, focusOnKey);
+                } else {
+                    editHelper.addProperty();
+                    btnAdd.requestFocusInWindow();
+                }
+            } else if (e.getSource() == membershipTable) {
+                int row = membershipTable.rowAtPoint(e.getPoint());
+                if (row > -1) {
+                    editMembership(row);
+                }
+            }
+            else
+            {
+                editHelper.addProperty();
+                btnAdd.requestFocusInWindow();
+            }
+        }
+        @Override public void mousePressed(MouseEvent e) {
+            if (e.getSource() == propertyTable) {
+                membershipTable.clearSelection();
+            } else if (e.getSource() == membershipTable) {
+                propertyTable.clearSelection();
+            }
+        }
+
+    }
+
+    static class MemberInfo {
+        List<RelationMember> role = new ArrayList<RelationMember>();
+        List<Integer> position = new ArrayList<Integer>();
+        private String positionString = null;
+        void add(RelationMember r, Integer p) {
+            role.add(r);
+            position.add(p);
+        }
+        String getPositionString() {
+            if (positionString == null) {
+                Collections.sort(position);
+                positionString = String.valueOf(position.get(0));
+                int cnt = 0;
+                int last = position.get(0);
+                for (int i = 1; i < position.size(); ++i) {
+                    int cur = position.get(i);
+                    if (cur == last + 1) {
+                        ++cnt;
+                    } else if (cnt == 0) {
+                        positionString += "," + String.valueOf(cur);
+                    } else {
+                        positionString += "-" + String.valueOf(last);
+                        positionString += "," + String.valueOf(cur);
+                        cnt = 0;
+                    }
+                    last = cur;
+                }
+                if (cnt >= 1) {
+                    positionString += "-" + String.valueOf(last);
+                }
+            }
+            if (positionString.length() > 20) {
+                positionString = positionString.substring(0, 17) + "...";
+            }
+            return positionString;
+        }
+    }
+
+    /**
+     * Class that allows fast creation of read-only table model with String columns
+     */
+    public static class ReadOnlyTableModel extends DefaultTableModel {
+        @Override public boolean isCellEditable(int row, int column) {
+            return false;
+        }
+        @Override public Class<?> getColumnClass(int columnIndex) {
+            return String.class;
+        }
+    };
+    
     /**
      * Action handling delete button press in properties dialog.
@@ -839,6 +924,9 @@
                 deleteProperties(rows);
             } else if (membershipTable.getSelectedRowCount() > 0) {
-                int row = membershipTable.getSelectedRow();
-                deleteFromRelation(row);
+                int[] rows = membershipTable.getSelectedRows();
+                // delete from last relation to convserve row numbers in the table 
+                for (int i=rows.length-1; i>=0; i--) {
+                    deleteFromRelation(rows[i]);
+                }
             }
         }
@@ -848,5 +936,5 @@
             setEnabled(
                     (propertyTable != null && propertyTable.getSelectedRowCount() >= 1)
-                    || (membershipTable != null && membershipTable.getSelectedRowCount() == 1)
+                    || (membershipTable != null && membershipTable.getSelectedRowCount() > 0)
                     );
         }
@@ -920,4 +1008,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             try {
@@ -959,5 +1048,5 @@
 
                 Main.worker.execute(new Runnable(){
-                    public void run() {
+                    @Override public void run() {
                         try {
                             // find a page that actually exists in the wiki
@@ -1007,51 +1096,4 @@
     }
 
-    public void addPropertyPopupMenuSeparator() {
-        propertyMenu.addSeparator();
-    }
-
-    public JMenuItem addPropertyPopupMenuAction(Action a) {
-        return propertyMenu.add(a);
-    }
-
-    public void addPropertyPopupMenuListener(PopupMenuListener l) {
-        propertyMenu.addPopupMenuListener(l);
-    }
-
-    public void removePropertyPopupMenuListener(PopupMenuListener l) {
-        propertyMenu.addPopupMenuListener(l);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Tag getSelectedProperty() {
-        int row = propertyTable.getSelectedRow();
-        if (row == -1) return null;
-        TreeMap<String, Integer> map = (TreeMap<String, Integer>) propertyData.getValueAt(row, 1);
-        return new Tag(
-                propertyData.getValueAt(row, 0).toString(),
-                map.size() > 1 ? "" : map.keySet().iterator().next());
-    }
-
-    public void addMembershipPopupMenuSeparator() {
-        membershipMenu.addSeparator();
-    }
-
-    public JMenuItem addMembershipPopupMenuAction(Action a) {
-        return membershipMenu.add(a);
-    }
-
-    public void addMembershipPopupMenuListener(PopupMenuListener l) {
-        membershipMenu.addPopupMenuListener(l);
-    }
-
-    public void removeMembershipPopupMenuListener(PopupMenuListener l) {
-        membershipMenu.addPopupMenuListener(l);
-    }
-
-    public IRelation getSelectedMembershipRelation() {
-        int row = membershipTable.getSelectedRow();
-        return row > -1 ? (IRelation) membershipData.getValueAt(row, 0) : null;
-    }
-
     class PasteValueAction extends AbstractAction {
         public PasteValueAction() {
@@ -1155,4 +1197,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             if (propertyTable.getSelectedRowCount() != 1)
@@ -1189,15 +1232,3 @@
         }
     }
-
-    @Override
-    public void destroy() {
-        super.destroy();
-        for (JosmAction action : josmActions) {
-            action.destroy();
-        }
-        Container parent = pluginHook.getParent();
-        if (parent != null) {
-            parent.remove(pluginHook);
-        }
-    }
 }
