Index: core/src/org/openstreetmap/josm/actions/data/NodeAction.java
===================================================================
--- core/src/org/openstreetmap/josm/actions/data/NodeAction.java	(revision 0)
+++ core/src/org/openstreetmap/josm/actions/data/NodeAction.java	(working copy)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.data;
+
+import java.util.Collection;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.data.osm.Node;
+
+/**
+ * Interface used to enable/disable all node-related actions, even those registered by plugins.
+ * @since 5805
+ */
+public interface NodeAction extends Action {
+
+    /**
+     * Specifies the working set of nodes.
+     * @param nodes The new working set of nodes. Can be null or empty
+     */
+    public abstract void setNodes(Collection<Node> nodes);
+}
Index: core/src/org/openstreetmap/josm/actions/data/RelationAction.java
===================================================================
--- core/src/org/openstreetmap/josm/actions/data/RelationAction.java	(revision 0)
+++ core/src/org/openstreetmap/josm/actions/data/RelationAction.java	(working copy)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.data;
+
+import java.util.Collection;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.data.osm.Relation;
+
+/**
+ * Interface used to enable/disable all relation-related actions, even those registered by plugins.
+ * @since 5805
+ */
+public interface RelationAction extends Action {
+
+    /**
+     * Specifies the working set of relations.
+     * @param relations The new working set of relations. Can be null or empty
+     */
+    public abstract void setRelations(Collection<Relation> relations);
+}
Index: core/src/org/openstreetmap/josm/actions/data/WayAction.java
===================================================================
--- core/src/org/openstreetmap/josm/actions/data/WayAction.java	(revision 0)
+++ core/src/org/openstreetmap/josm/actions/data/WayAction.java	(working copy)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.data;
+
+import java.util.Collection;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.data.osm.Way;
+
+/**
+ * Interface used to enable/disable all way-related actions, even those registered by plugins.
+ * @since 5805
+ */
+public interface WayAction extends Action {
+
+    /**
+     * Specifies the working set of ways.
+     * @param ways The new working set of ways. Can be null or empty
+     */
+    public abstract void setWays(Collection<Way> ways);
+}
Index: core/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java
===================================================================
--- core/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(revision 5801)
+++ core/src/org/openstreetmap/josm/actions/relation/AbstractRelationAction.java	(working copy)
@@ -6,6 +6,7 @@
 
 import javax.swing.AbstractAction;
 
+import org.openstreetmap.josm.actions.data.RelationAction;
 import org.openstreetmap.josm.data.osm.Relation;
 
 /**
@@ -13,13 +14,13 @@
  * to be disabled is the collection is empty
  * @since 5793
  */
-public abstract class AbstractRelationAction extends AbstractAction {
+public abstract class AbstractRelationAction extends AbstractAction implements RelationAction {
     protected Collection<Relation> relations = Collections.<Relation>emptySet();
 
-    /**
-     * Specifies the working set of relations.
-     * @param relations The new working set of relations. Can be null or empty
+    /* (non-Javadoc)
+     * @see org.openstreetmap.josm.actions.relation.RelationAction#setRelations(java.util.Collection)
      */
+    @Override
     public void setRelations(Collection<Relation> relations) {
         if (relations==null) {
             this.relations = Collections.<Relation>emptySet();
Index: core/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java
===================================================================
--- core/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 5801)
+++ core/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(working copy)
@@ -16,6 +16,10 @@
  * @since 5799
  */
 public class DuplicateRelationAction extends AbstractRelationAction {
+    
+    /**
+     * Constructs a new {@code DuplicateRelationAction}. 
+     */
     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"));
Index: core/src/org/openstreetmap/josm/gui/DataActionPopupMenuHandler.java
===================================================================
--- core/src/org/openstreetmap/josm/gui/DataActionPopupMenuHandler.java	(revision 0)
+++ core/src/org/openstreetmap/josm/gui/DataActionPopupMenuHandler.java	(working copy)
@@ -0,0 +1,358 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.Action;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+import javax.swing.event.PopupMenuListener;
+
+import org.openstreetmap.josm.actions.data.NodeAction;
+import org.openstreetmap.josm.actions.data.RelationAction;
+import org.openstreetmap.josm.actions.data.WayAction;
+import org.openstreetmap.josm.actions.relation.DownloadMembersAction;
+import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction;
+import org.openstreetmap.josm.actions.relation.EditRelationAction;
+import org.openstreetmap.josm.actions.relation.SelectInRelationListAction;
+import org.openstreetmap.josm.actions.relation.SelectMembersAction;
+import org.openstreetmap.josm.actions.relation.SelectRelationAction;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
+
+/**
+ * Handler to ease management of osm primitives related actions in all different popup menus.
+ * @since 5805
+ */
+public class DataActionPopupMenuHandler {
+
+    // Pre-defined relation actions
+    private SelectRelationAction selectRelationAction;
+    private SelectRelationAction addRelationToSelectionAction;
+    private SelectMembersAction selectMembersAction;
+    private SelectMembersAction addMembersToSelectionAction;
+    private SelectInRelationListAction selectInRelationListAction;
+    private EditRelationAction editRelationAction;
+    private DownloadMembersAction downloadMembersAction;
+    private DownloadSelectedIncompleteMembersAction downloadIncompleteMembersAction;
+
+    // Set of enabled node, way and relation actions
+    private final Set<NodeAction> nodeActions = new HashSet<NodeAction>();
+    private final Set<WayAction> wayActions = new HashSet<WayAction>();
+    private final Set<RelationAction> relationActions = new HashSet<RelationAction>();
+    // Managed menu
+    private final JPopupMenu menu;
+    
+    /**
+     * Constructs a new {@code RelationActionMenuHandler} for the specified popup menu.
+     * 
+     * @param menu The menu to be managed
+     */
+    public DataActionPopupMenuHandler(JPopupMenu menu) {
+        this.menu = menu;
+    }
+    
+    /**
+     * Enables the action "Select relation" which can be then accessed with the method {@code #getSelectRelationAction()}
+     * @see #getSelectRelationAction
+     */
+    public void enableSelectRelationAction() {
+        if (selectRelationAction == null) {
+            addAction(selectRelationAction = new SelectRelationAction(false));
+        }
+    }
+    
+    /**
+     * Enables the action "Select relation (add)" which can be then accessed with the method {@code #getAddRelationToSelectionAction()}
+     * @see #getAddRelationToSelectionAction
+     */
+    public void enableAddRelationToSelectionAction() {
+        if (addRelationToSelectionAction == null) {
+            addAction(addRelationToSelectionAction = new SelectRelationAction(true));
+        }
+    }
+    
+    /**
+     * Enables the action "Select members" which can be then accessed with the method {@code #getSelectMembersAction()}
+     * @see #getSelectMembersAction
+     */
+    public void enableSelectMembersAction() {
+        if (selectMembersAction == null) {
+            addAction(selectMembersAction = new SelectMembersAction(false));
+        }
+    }
+    
+    /**
+     * Enables the action "Select members (add)" which can be then accessed with the method {@code #getAddMembersToSelectionAction()}
+     * @see #getAddMembersToSelectionAction
+     */
+    public void enableAddMembersToSelectionAction() {
+        if (addMembersToSelectionAction == null) {
+            addAction(addMembersToSelectionAction = new SelectMembersAction(true));
+        }
+    }
+    
+    /**
+     * Enables the action "Select in relation list" which can be then accessed with the method {@code #getSelectInRelationListAction()}
+     * @see #getSelectInRelationListAction
+     */
+    public void enableSelectInRelationListAction() {
+        if (selectInRelationListAction == null) {
+            addAction(selectInRelationListAction = new SelectInRelationListAction());
+        }
+    }
+    
+    /**
+     * Enables the action "Edit relation" which can be then accessed with the method {@code #getEditRelationAction()}
+     * @see #getEditRelationAction
+     */
+    public void enableEditRelationAction() {
+        if (editRelationAction == null) {
+            addAction(editRelationAction = new EditRelationAction());
+        }
+    }
+    
+    /**
+     * Enables the action "Download members" which can be then accessed with the method {@code #getDownloadMembersAction()}
+     * @see #getDownloadMembersAction
+     */
+    public void enableDownloadMembersAction() {
+        if (downloadMembersAction == null) {
+            addAction(downloadMembersAction = new DownloadMembersAction());
+        }
+    }
+    
+    /**
+     * Enables the action "Download incomplete members" which can be then accessed with the method {@code #getDownloadSelectedIncompleteMembersAction()}
+     * @see #getDownloadSelectedIncompleteMembersAction
+     */
+    public void enableDownloadIncompleteMembersAction() {
+        if (downloadIncompleteMembersAction == null) {
+            addAction(downloadIncompleteMembersAction = new DownloadSelectedIncompleteMembersAction());
+        }
+    }
+
+    /**
+     * Appends a new separator at the end of the menu.
+     * @see JPopupMenu#addSeparator
+     */
+    public void addSeparator() {
+        menu.addSeparator();
+    }
+
+    /**
+     * Appends a new menu item to the end of the menu which dispatches the specified <code>Action</code> object.
+     * 
+     * @param a the <code>Action</code> to add to the menu
+     * @return the new menu item
+     * @see JPopupMenu#add(Action)
+     */
+    public JMenuItem addAction(Action a) {
+        if (a != null) {
+            if (a instanceof NodeAction) {
+                nodeActions.add((NodeAction) a);
+            }
+            if (a instanceof WayAction) {
+                wayActions.add((WayAction) a);
+            }
+            if (a instanceof RelationAction) {
+                relationActions.add((RelationAction) a);
+            }
+            return menu.add(a);
+        }
+        return null;
+    }
+
+    /**
+     * Removes the menu item which dispatches the specified <code>Action</code> object.
+     * 
+     * @param a the <code>Action</code> to remove from the menu
+     * @see JPopupMenu#remove(int)
+     */
+    public void removeAction(Action a) {
+        if (a != null) {
+            if (a instanceof NodeAction) {
+                nodeActions.remove(a);
+            }
+            if (a instanceof WayAction) {
+                wayActions.remove(a);
+            }
+            if (a instanceof RelationAction) {
+                relationActions.remove(a);
+            }
+            MenuElement[] elements = menu.getSubElements();
+            for (int i=0; i<elements.length; i++) {
+                if (elements[i] instanceof JMenuItem) {
+                    if (((JMenuItem) elements[i]).getAction() == a) {
+                        menu.remove(i);
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     *  Adds a <code>PopupMenu</code> listener.
+     *
+     *  @param l the <code>PopupMenuListener</code> to add
+     *  @see JPopupMenu#addPopupMenuListener
+     */
+    public void addListener(PopupMenuListener l) {
+        menu.addPopupMenuListener(l);
+    }
+
+    /**
+     * Removes a <code>PopupMenu</code> listener.
+     *
+     * @param l the <code>PopupMenuListener</code> to remove
+     *  @see JPopupMenu#removePopupMenuListener
+     */
+    public void removeListener(PopupMenuListener l) {
+        menu.removePopupMenuListener(l);
+    }
+    
+    /**
+     * Returns all enabled node actions.
+     * @return All node actions that have been added.
+     * @see #addAction(Action)
+     */
+    public Collection<NodeAction> getNodeActions() {
+        return Collections.unmodifiableCollection(nodeActions);
+    }
+
+    /**
+     * Returns all enabled way actions.
+     * @return All way actions that have been added.
+     * @see #addAction(Action)
+     */
+    public Collection<WayAction> getWayActions() {
+        return Collections.unmodifiableCollection(wayActions);
+    }
+
+    /**
+     * Returns all enabled relation actions.
+     * @return All relation actions that have been added or enabled.
+     * @see #addAction(Action)
+     * @see #enableAddMembersToSelectionAction()
+     * @see #enableAddRelationToSelectionAction()
+     * @see #enableDownloadIncompleteMembersAction()
+     * @see #enableEditRelationAction()
+     * @see #enableSelectInRelationListAction()
+     * @see #enableSelectMembersAction()
+     * @see #enableSelectRelationAction() 
+     */
+    public Collection<RelationAction> getRelationActions() {
+        return Collections.unmodifiableCollection(relationActions);
+    }
+    
+    /**
+     * Specifies the working set of nodes for all node actions.
+     * @param nodes The new working set of nodes. Can be null or empty
+     * @see NodeAction#setNodes
+     */
+    public void setNodes(Collection<Node> nodes) {
+        for (NodeAction action : nodeActions) {
+            action.setNodes(nodes);
+        }
+    }
+    
+    /**
+     * Specifies the working set of ways for all way actions.
+     * @param ways The new working set of ways. Can be null or empty
+     * @see WayAction#setWays
+     */
+    public void setWays(Collection<Way> ways) {
+        for (WayAction action : wayActions) {
+            action.setWays(ways);
+        }
+    }
+    
+    /**
+     * Specifies the working set of relations for all relation actions.
+     * @param relations The new working set of relations. Can be null or empty
+     * @see RelationAction#setRelations
+     */
+    public void setRelations(Collection<Relation> relations) {
+        for (RelationAction action : relationActions) {
+            action.setRelations(relations);
+        }
+    }
+
+    /**
+     * Replies the "Select relation (add)" action.
+     * @return the "Select relation (add)" action, if previously enabled, {@code null} otherwise.
+     * @see #enableAddRelationToSelectionAction
+     */
+    public final SelectRelationAction getAddRelationToSelectionAction() {
+        return addRelationToSelectionAction;
+    }
+
+    /**
+     * Replies the "Select members (add)" action.
+     * @return the "Select members (add)" action, if previously enabled, {@code null} otherwise.
+     * @see #enableAddMembersToSelectionAction
+     */
+    public final SelectMembersAction getAddMembersToSelectionAction() {
+        return addMembersToSelectionAction;
+    }
+
+    /**
+     * Replies the "Select relation" action.
+     * @return the "Select relation" action, if previously enabled, {@code null} otherwise.
+     * @see #enableSelectRelationAction
+     */
+    public final SelectRelationAction getSelectRelationAction() {
+        return selectRelationAction;
+    }
+
+    /**
+     * Replies the "Select in relation list" action.
+     * @return the "Select in relation list" action, if previously enabled, {@code null} otherwise.
+     * @see #enableSelectInRelationListAction
+     */
+    public final SelectInRelationListAction getSelectInRelationListAction() {
+        return selectInRelationListAction;
+    }
+
+    /**
+     * Replies the "Edit relation" action.
+     * @return the "Edit relation" action, if previously enabled, {@code null} otherwise.
+     * @see #enableEditRelationAction
+     */
+    public final EditRelationAction getEditRelationAction() {
+        return editRelationAction;
+    }
+
+    /**
+     * Replies the "Select members" action.
+     * @return the "Select members" action, if previously enabled, {@code null} otherwise.
+     * @see #enableSelectMembersAction
+     */
+    public final SelectMembersAction getSelectMembersAction() {
+        return selectMembersAction;
+    }
+
+    /**
+     * Replies the "Download members" action.
+     * @return the "Download members" action, if previously enabled, {@code null} otherwise.
+     * @see #enableDownloadMembersAction
+     */
+    public final DownloadMembersAction getDownloadMembersAction() {
+        return downloadMembersAction;
+    }
+    
+    /**
+     * Replies the "Download incomplete members" action.
+     * @return the "Download incomplete members" action, if previously enabled, {@code null} otherwise.
+     * @see #enableDownloadIncompleteMembersAction
+     */
+    public final DownloadSelectedIncompleteMembersAction getDownloadSelectedIncompleteMembersAction() {
+        return downloadIncompleteMembersAction;
+    }
+}
Index: core/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- core/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 5801)
+++ core/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(working copy)
@@ -21,11 +21,9 @@
 
 import javax.swing.AbstractAction;
 import javax.swing.AbstractListModel;
-import javax.swing.Action;
 import javax.swing.DefaultListSelectionModel;
 import javax.swing.JComponent;
 import javax.swing.JList;
-import javax.swing.JMenuItem;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
@@ -38,16 +36,13 @@
 import javax.swing.event.DocumentListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
-import javax.swing.event.PopupMenuListener;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.data.RelationAction;
 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.data.osm.DataSet;
@@ -64,6 +59,7 @@
 import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
 import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.gui.DataActionPopupMenuHandler;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
@@ -94,25 +90,20 @@
 
     private final NewAction newAction;
     
-    /** the popup menu */
-    private final RelationDialogPopupMenu popupMenu;
+    /** the popup menu and its handler */
+    private final JPopupMenu popupMenu;
+    private final DataActionPopupMenuHandler popupMenuHandler;
 
     private final JTextField filter;
     
-    // Actions
+    // Actions specific to this dialog (other may be found inside popupMenu.handler)
     /** the edit action */
     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();
-    private final SelectMembersAction selectMemebersAction = new SelectMembersAction(false);
-    private final SelectMembersAction addMembersToSelectionAction = new SelectMembersAction(true);
-    private final SelectRelationAction selectRelationAction = new SelectRelationAction(false);
-    private final SelectRelationAction addRelationToSelectionAction = new SelectRelationAction(true);
-    /** add all selected primitives to the given realtions */
+    /** add all selected primitives to the given relations */
     private final AddSelectionToRelations addSelectionToRelations = new AddSelectionToRelations();
     
     /**
@@ -153,6 +144,12 @@
                 updateActionsRelationLists();
             }
         });
+
+        // Create popup menu and relation actions
+        popupMenu = new JPopupMenu();
+        popupMenuHandler = setupPopupMenuHandler();
+        
+        SelectRelationAction selectRelationAction = popupMenuHandler.getSelectRelationAction();
         
         JPanel pane = new JPanel(new BorderLayout());
         pane.add(filter, BorderLayout.NORTH);
@@ -174,8 +171,6 @@
         // Select relation on Ctrl-Enter
         InputMapUtils.addEnterAction(displaylist, selectRelationAction);
 
-        popupMenu = new RelationDialogPopupMenu();
-
         // Edit relation on Ctrl-Enter
         displaylist.getActionMap().put("edit", editAction);
         displaylist.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK), "edit");
@@ -185,22 +180,16 @@
     
     // 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);
+        List<Relation> rels = model.getSelectedRelations();
+        for (RelationAction relAction : popupMenuHandler.getRelationActions()) {
+            if (relAction == popupMenuHandler.getDownloadMembersAction()) {
+                relAction.setRelations(model.getSelectedNonNewRelations());
+            } else if (relAction == popupMenuHandler.getDownloadSelectedIncompleteMembersAction()) {
+                relAction.setRelations(model.getSelectedRelationsWithIncompleteMembers());
+            } else {
+                relAction.setRelations(rels);
+            }
+        }
     }
     
     @Override public void showNotify() {
@@ -655,49 +644,38 @@
         }
     }
 
-    class RelationDialogPopupMenu extends JPopupMenu {
-
-        public RelationDialogPopupMenu() {
-            // -- download members action
-            add(downloadMembersAction);
+    private final DataActionPopupMenuHandler setupPopupMenuHandler() {
+        DataActionPopupMenuHandler handler = new DataActionPopupMenuHandler(popupMenu);
+        
+        // -- download members action
+        handler.enableDownloadMembersAction();
 
-            // -- download incomplete members action
-            add(downloadSelectedIncompleteMembersAction);
+        // -- download incomplete members action
+        handler.enableDownloadIncompleteMembersAction();
 
-            addSeparator();
+        handler.addSeparator();
 
-            // -- select members action
-            add(selectMemebersAction);
-            add(addMembersToSelectionAction);
+        // -- select members action
+        handler.enableSelectMembersAction();
+        handler.enableAddMembersToSelectionAction();
 
-            // -- select action
-            add(selectRelationAction);
-            add(addRelationToSelectionAction);
+        // -- select action
+        handler.enableSelectRelationAction();
+        handler.enableAddRelationToSelectionAction();
 
-            addSeparator();
+        handler.addSeparator();
 
-            add(addSelectionToRelations);
-        }
+        handler.addAction(addSelectionToRelations);
+        
+        return handler;
     }
-
+    
     /* ---------------------------------------------------------------------------------- */
-    /* Methods that can be called from plugins                                                                    */
+    /* Methods that can be called from plugins                                            */
     /* ---------------------------------------------------------------------------------- */
 
-    public void addPopupMenuSeparator() {
-        popupMenu.addSeparator();
-    }
-
-    public JMenuItem addPopupMenuAction(Action a) {
-        return popupMenu.add(a);
-    }
-
-    public void addPopupMenuListener(PopupMenuListener l) {
-        popupMenu.addPopupMenuListener(l);
-    }
-
-    public void removePopupMenuListener(PopupMenuListener l) {
-        popupMenu.addPopupMenuListener(l);
+    public DataActionPopupMenuHandler getPopupMenuHandler() {
+        return popupMenuHandler;
     }
 
     public Collection<Relation> getSelectedRelations() {
Index: core/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- core/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 5801)
+++ core/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(working copy)
@@ -23,7 +23,6 @@
 
 import javax.swing.AbstractAction;
 import javax.swing.AbstractListModel;
-import javax.swing.Action;
 import javax.swing.DefaultListSelectionModel;
 import javax.swing.JList;
 import javax.swing.JMenuItem;
@@ -34,13 +33,10 @@
 import javax.swing.event.ListDataListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
-import javax.swing.event.PopupMenuListener;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AutoScaleAction;
-import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction;
-import org.openstreetmap.josm.actions.relation.EditRelationAction;
-import org.openstreetmap.josm.actions.relation.SelectInRelationListAction;
+import org.openstreetmap.josm.actions.data.RelationAction;
 import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting;
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.Node;
@@ -62,6 +58,7 @@
 import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.DataActionPopupMenuHandler;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
@@ -87,11 +84,10 @@
     private SearchAction actSearch;
     private ZoomToJOSMSelectionAction actZoomToJOSMSelection;
     private ZoomToListSelection actZoomToListSelection;
-    private SelectInRelationListAction actSetRelationSelection;
-    private EditRelationAction actEditRelationSelection;
-    private DownloadSelectedIncompleteMembersAction actDownloadSelectedIncompleteMembers;
 
-    private SelectionPopup popupMenu;
+    /** the popup menu and its handler */
+    private final ListPopupMenu popupMenu;
+    private final DataActionPopupMenuHandler popupMenuHandler;
 
     /**
      * Builds the content panel for this dialog
@@ -143,27 +139,31 @@
         model.addListDataListener(actZoomToJOSMSelection);
 
         actZoomToListSelection = new ZoomToListSelection();
-        actSetRelationSelection = new SelectInRelationListAction();
-        actEditRelationSelection = new EditRelationAction();
-        actDownloadSelectedIncompleteMembers = new DownloadSelectedIncompleteMembersAction();
+
+        popupMenu = new ListPopupMenu(lstPrimitives);
+        popupMenuHandler = setupPopupMenuHandler();
 
         lstPrimitives.addListSelectionListener(new ListSelectionListener() {
             @Override
             public void valueChanged(ListSelectionEvent e) {
                 actZoomToListSelection.valueChanged(e);
-                List<Relation> rels;
-                rels = model.getSelectedRelationsWithIncompleteMembers();
-                actDownloadSelectedIncompleteMembers.setRelations(rels); 
-                rels = OsmPrimitive.getFilteredList(model.getSelected(), Relation.class);
-                actSetRelationSelection.setRelations(rels);
-                actEditRelationSelection.setRelations(rels);
+                Collection<OsmPrimitive> selection = model.getSelected();
+                popupMenuHandler.setNodes(OsmPrimitive.getFilteredList(selection, Node.class));
+                popupMenuHandler.setWays(OsmPrimitive.getFilteredList(selection, Way.class));
+                List<Relation> rels = OsmPrimitive.getFilteredList(selection, Relation.class);
+                for (RelationAction relAction : popupMenuHandler.getRelationActions()) {
+                    if (relAction == popupMenuHandler.getDownloadSelectedIncompleteMembersAction()) {
+                        relAction.setRelations(model.getSelectedRelationsWithIncompleteMembers());
+                    } else {
+                        relAction.setRelations(rels);
+                    }
+                }
             }
         });
                 
         lstPrimitives.addMouseListener(new SelectionPopupMenuLauncher());
         lstPrimitives.addMouseListener(new DblClickHandler());
 
-        popupMenu = new SelectionPopup(lstPrimitives);
         InputMapUtils.addEnterAction(lstPrimitives, actZoomToListSelection);
     }
 
@@ -220,36 +220,20 @@
         }
     }
 
-    /**
-     * The popup menu for the selection list
-     */
-    class SelectionPopup extends ListPopupMenu {
-        public SelectionPopup(JList list) {
-            super(list);
-            add(actZoomToJOSMSelection);
-            add(actZoomToListSelection);
-            addSeparator();
-            add(actSetRelationSelection);
-            add(actEditRelationSelection);
-            addSeparator();
-            add(actDownloadSelectedIncompleteMembers);
-        }
+    private final DataActionPopupMenuHandler setupPopupMenuHandler() {
+        DataActionPopupMenuHandler handler = new DataActionPopupMenuHandler(popupMenu);
+        handler.addAction(actZoomToJOSMSelection);
+        handler.addAction(actZoomToListSelection);
+        handler.addSeparator();
+        handler.enableSelectInRelationListAction();
+        handler.enableEditRelationAction();
+        handler.addSeparator();
+        handler.enableDownloadIncompleteMembersAction();
+        return handler;
     }
 
-    public void addPopupMenuSeparator() {
-        popupMenu.addSeparator();
-    }
-
-    public JMenuItem addPopupMenuAction(Action a) {
-        return popupMenu.add(a);
-    }
-
-    public void addPopupMenuListener(PopupMenuListener l) {
-        popupMenu.addPopupMenuListener(l);
-    }
-
-    public void removePopupMenuListener(PopupMenuListener l) {
-        popupMenu.addPopupMenuListener(l);
+    public DataActionPopupMenuHandler getPopupMenuActionHandler() {
+        return popupMenuHandler;
     }
 
     public Collection<OsmPrimitive> getSelectedPrimitives() {
Index: core/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- core/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 5801)
+++ core/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(working copy)
@@ -51,9 +51,6 @@
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction;
-import org.openstreetmap.josm.actions.relation.SelectMembersAction;
-import org.openstreetmap.josm.actions.relation.SelectRelationAction;
 import org.openstreetmap.josm.actions.search.SearchAction.SearchMode;
 import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting;
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -72,6 +69,7 @@
 import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
 import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
 import org.openstreetmap.josm.data.osm.event.SelectionEventManager;
+import org.openstreetmap.josm.gui.DataActionPopupMenuHandler;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MapFrame;
@@ -110,8 +108,10 @@
  * @author imi
  */
 public class PropertiesDialog extends ToggleDialog implements SelectionChangedListener, MapView.EditLayerChangeListener, DataSetListenerAdapter.Listener {
-    // hook for roadsigns plugin to display a small
-    // button in the upper right corner of this dialog
+
+    /**
+     * hook for roadsigns plugin to display a small button in the upper right corner of this dialog
+     */
     public static final JPanel pluginHook = new JPanel();
 
     /**
@@ -133,8 +133,8 @@
      */
     private final JTable membershipTable = new JTable(membershipData);
 
-    private JPopupMenu propertyMenu;
-    private JPopupMenu membershipMenu;
+    private final JPopupMenu propertyMenu = new JPopupMenu();
+    private final JPopupMenu membershipMenu = new JPopupMenu();
 
     private final Map<String, Map<String, Integer>> valueCount = new TreeMap<String, Map<String, Integer>>();
     /**
@@ -156,10 +156,7 @@
     private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
 
     // relation actions
-    private final DownloadSelectedIncompleteMembersAction downloadSelectedIncompleteMembersAction = new DownloadSelectedIncompleteMembersAction();
-    private final SelectRelationAction addRelationToSelectionAction = new SelectRelationAction(true);
-    private final SelectMembersAction addMembersToSelectionAction = new SelectMembersAction(true);
-    private final SelectRelationAction selectRelationAction = new SelectRelationAction(false);
+    private final DataActionPopupMenuHandler membershipMenuHandler = new DataActionPopupMenuHandler(membershipMenu);
     
     /**
      * The Add button (needed to be able to disable it)
@@ -201,6 +198,7 @@
     
     /**
      * Create a new PropertiesDialog
+     * @param mapFrame The parent map fram
      */
     public PropertiesDialog(MapFrame mapFrame) {
         super(tr("Properties/Memberships"), "propertiesdialog", tr("Properties for selected objects."),
@@ -369,11 +367,10 @@
      */
     private void setupMembershipMenu() {
         // setting up the membership table
-        membershipMenu = new JPopupMenu();
-        membershipMenu.add(addRelationToSelectionAction);
-        membershipMenu.add(selectRelationAction);
-        membershipMenu.add(addMembersToSelectionAction);
-        membershipMenu.add(downloadSelectedIncompleteMembersAction);
+        membershipMenuHandler.enableAddRelationToSelectionAction();
+        membershipMenuHandler.enableSelectRelationAction();
+        membershipMenuHandler.enableAddMembersToSelectionAction();
+        membershipMenuHandler.enableDownloadIncompleteMembersAction();
         membershipMenu.addSeparator();
         membershipMenu.add(helpAction);
 
@@ -388,15 +385,12 @@
                     membershipTable.changeSelection(row, 0, false, false);
                     idx = new int[]{row};
                 }
-                List<Relation> rels =  new ArrayList<Relation>(10);
+                List<Relation> rels = new ArrayList<Relation>();
                 for (int i: idx) {
                     Relation r = (Relation) (membershipData.getValueAt(i, 0));
                     rels.add(r);
                 }
-                selectRelationAction.setRelations(rels);
-                addRelationToSelectionAction.setRelations(rels);
-                addMembersToSelectionAction.setRelations(rels);
-                downloadSelectedIncompleteMembersAction.setRelations(rels);
+                membershipMenuHandler.setRelations(rels);
                 membershipMenu.show(membershipTable, p.x, p.y-3);
             }
         });
@@ -406,7 +400,6 @@
      * 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);
@@ -720,20 +713,8 @@
                 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 DataActionPopupMenuHandler getMembershipPopupMenuHandler() {
+        return membershipMenuHandler;
     }
 
     public IRelation getSelectedMembershipRelation() {
