Index: trunk/src/org/openstreetmap/josm/actions/CopyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 3384)
@@ -3,6 +3,6 @@
 package org.openstreetmap.josm.actions;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 
 import java.awt.Toolkit;
@@ -14,5 +14,4 @@
 import java.awt.event.KeyEvent;
 import java.util.Collection;
-import java.util.LinkedList;
 
 import javax.swing.JOptionPane;
@@ -20,9 +19,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.Shortcut;
 
 public final class CopyAction extends JosmAction {
-
-    private LinkedList<JosmAction> listeners;
 
     public CopyAction() {
@@ -31,9 +29,4 @@
                 Shortcut.registerShortcut("system:copy", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_C, Shortcut.GROUP_MENU), true);
         putValue("help", ht("/Action/Copy"));
-        listeners = new LinkedList<JosmAction>();
-    }
-
-    @Override public void addListener(JosmAction a) {
-        listeners.add(a);
     }
 
@@ -42,7 +35,11 @@
         Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
 
+        copy(getEditLayer(), selection);
+    }
+
+    public static void copy(OsmDataLayer source, Collection<OsmPrimitive> primitives) {
         /* copy ids to the clipboard */
         StringBuilder idsBuilder = new StringBuilder();
-        for (OsmPrimitive p : selection) {
+        for (OsmPrimitive p : primitives) {
             idsBuilder.append(p.getId()+",");
         }
@@ -56,12 +53,7 @@
         }
         catch (RuntimeException x) {}
-        
-        Main.pasteBuffer.makeCopy(selection);
-        Main.pasteSource = getEditLayer();
-        Main.main.menu.paste.setEnabled(true); /* now we have a paste buffer we can make paste available */
 
-        for(JosmAction a : listeners) {
-            a.pasteBufferChanged(Main.pasteBuffer);
-        }
+        Main.pasteBuffer.makeCopy(primitives);
+        Main.pasteSource = source;
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 3384)
@@ -12,5 +12,4 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -103,11 +102,4 @@
      * needs to be overridden to be useful
      */
-    public void pasteBufferChanged(PrimitiveDeepCopy newPasteBuffer) {
-        return;
-    }
-
-    /**
-     * needs to be overridden to be useful
-     */
     public void addListener(JosmAction a) {
         return;
Index: trunk/src/org/openstreetmap/josm/actions/PasteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PasteAction.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/actions/PasteAction.java	(revision 3384)
@@ -23,9 +23,10 @@
 import org.openstreetmap.josm.data.osm.RelationMemberData;
 import org.openstreetmap.josm.data.osm.WayData;
+import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.tools.Shortcut;
 
-public final class PasteAction extends JosmAction {
+public final class PasteAction extends JosmAction implements PasteBufferChangedListener {
 
     public PasteAction() {
@@ -33,4 +34,5 @@
                 Shortcut.registerShortcut("system:paste", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_V, Shortcut.GROUP_MENU), true);
         putValue("help", ht("/Action/Paste"));
+        Main.pasteBuffer.addPasteBufferChangedListener(this);
     }
 
@@ -167,3 +169,8 @@
         setEnabled(!Main.pasteBuffer.isEmpty());
     }
+
+    @Override
+    public void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer) {
+        updateEnabledState();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 3384)
@@ -3,6 +3,6 @@
 package org.openstreetmap.josm.actions;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.trn;
 
@@ -24,8 +24,9 @@
 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
 import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
 import org.openstreetmap.josm.gui.conflict.tags.PasteTagsConflictResolverDialog;
 import org.openstreetmap.josm.tools.Shortcut;
 
-public final class PasteTagsAction extends JosmAction {
+public final class PasteTagsAction extends JosmAction implements PasteBufferChangedListener {
 
     public PasteTagsAction(JosmAction copyAction) {
@@ -33,5 +34,5 @@
                 tr("Apply tags of contents of paste buffer to all selected items."),
                 Shortcut.registerShortcut("system:pastestyle", tr("Edit: {0}", tr("Paste Tags")), KeyEvent.VK_V, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
-        copyAction.addListener(this);
+        Main.pasteBuffer.addPasteBufferChangedListener(this);
         putValue("help", ht("/Action/PasteTags"));
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/PrimitiveDeepCopy.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/PrimitiveDeepCopy.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/data/osm/PrimitiveDeepCopy.java	(revision 3384)
@@ -7,4 +7,5 @@
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
@@ -17,6 +18,11 @@
 public class PrimitiveDeepCopy {
 
+    public interface PasteBufferChangedListener {
+        void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer);
+    }
+
     private final List<PrimitiveData> directlyAdded = new ArrayList<PrimitiveData>();
     private final List<PrimitiveData> referenced = new ArrayList<PrimitiveData>();
+    private final CopyOnWriteArrayList<PasteBufferChangedListener> listeners = new CopyOnWriteArrayList<PasteBufferChangedListener>();
 
     public PrimitiveDeepCopy() {
@@ -74,4 +80,6 @@
             }
         }.visitAll();
+
+        firePasteBufferChanged();
     }
 
@@ -95,3 +103,17 @@
     }
 
+    private void firePasteBufferChanged() {
+        for (PasteBufferChangedListener listener: listeners) {
+            listener.pasteBufferChanged(this);
+        }
+    }
+
+    public void addPasteBufferChangedListener(PasteBufferChangedListener listener) {
+        listeners.addIfAbsent(listener);
+    }
+
+    public void removePasteBufferChangedListener(PasteBufferChangedListener listener) {
+        listeners.remove(listener);
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 3383)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 3384)
@@ -27,4 +27,5 @@
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Logger;
 
@@ -50,4 +51,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.CopyAction;
 import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -56,4 +58,5 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveData;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -91,4 +94,5 @@
 
     /** the model for the selection table */
+    private SelectionTable selectionTable;
     private SelectionTableModel selectionTableModel;
 
@@ -383,4 +387,8 @@
         pnl3.setLayout(new BorderLayout());
         pnl3.add(splitPane, BorderLayout.CENTER);
+
+        new PasteMembersAction();
+        new CopyMembersAction();
+
         return pnl3;
     }
@@ -394,7 +402,7 @@
         JPanel pnl = new JPanel();
         pnl.setLayout(new BorderLayout());
-        SelectionTable tbl = new SelectionTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));
-        tbl.setMemberTableModel(memberTableModel);
-        JScrollPane pane = new JScrollPane(tbl);
+        selectionTable = new SelectionTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));
+        selectionTable.setMemberTableModel(memberTableModel);
+        JScrollPane pane = new JScrollPane(selectionTable);
         pnl.add(pane, BorderLayout.CENTER);
         return pnl;
@@ -591,4 +599,16 @@
     }
 
+    private void registerCopyPasteAction(AbstractAction action, Object actionName, KeyStroke shortcut) {
+        getRootPane().getActionMap().put(actionName, action);
+        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
+        // Assign also to JTables because they have their own Copy&Paste implementation (which is disabled in this case but eats key shortcuts anyway)
+        memberTable.getInputMap(JComponent.WHEN_FOCUSED).put(shortcut, actionName);
+        memberTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);
+        memberTable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
+        selectionTable.getInputMap(JComponent.WHEN_FOCUSED).put(shortcut, actionName);
+        selectionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);
+        selectionTable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
+    }
+
     static class AddAbortException extends Exception  {
     }
@@ -1442,4 +1462,66 @@
     }
 
+    class PasteMembersAction extends AddFromSelectionAction {
+
+        public PasteMembersAction() {
+            registerCopyPasteAction(this, "PASTE_MEMBERS", Shortcut.getPasteKeyStroke());
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            try {
+                List<PrimitiveData> primitives = Main.pasteBuffer.getDirectlyAdded();
+                DataSet ds = getLayer().data;
+                List<OsmPrimitive> toAdd = new ArrayList<OsmPrimitive>();
+                boolean hasNewInOtherLayer = false;
+
+                for (PrimitiveData primitive: primitives) {
+                    OsmPrimitive primitiveInDs = ds.getPrimitiveById(primitive);
+                    if (primitiveInDs != null) {
+                        toAdd.add(primitiveInDs);
+                    } else if (!primitive.isNew()) {
+                        toAdd.add(ds.getPrimitiveById(primitive, true));
+                    } else {
+                        hasNewInOtherLayer = true;
+                        break;
+                    }
+                }
+
+                if (hasNewInOtherLayer) {
+                    JOptionPane.showMessageDialog(Main.parent, tr("Members from paste buffer cannot be added because they are not included in current layer"));
+                    return;
+                }
+
+                toAdd = filterConfirmedPrimitives(toAdd);
+                memberTableModel.addMembersAfterIdx(toAdd, memberTableModel
+                        .getSelectionModel().getMaxSelectionIndex());
+
+                tfRole.requestFocusInWindow();
+
+            } catch (AddAbortException ex) {
+                // Do nothing
+            }
+        }
+    }
+
+    class CopyMembersAction extends AbstractAction {
+
+        public CopyMembersAction() {
+            registerCopyPasteAction(this, "COPY_MEMBERS", Shortcut.getCopyKeyStroke());
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            Set<OsmPrimitive> primitives = new HashSet<OsmPrimitive>();
+            for (RelationMember rm: memberTableModel.getSelectedMembers()) {
+                primitives.add(rm.getMember());
+            }
+            if (!primitives.isEmpty()) {
+                CopyAction.copy(getLayer(), primitives);
+            }
+        }
+
+    }
+
     class MemberTableDblClickAdapter extends MouseAdapter {
         @Override
