diff --git a/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java
new file mode 100644
index 0000000..06befa9
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java
@@ -0,0 +1,61 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveData;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+
+public class PrimitiveTransferable implements Transferable {
+
+    public static final DataFlavor PRIMITIVE_DATA = new DataFlavor(PrimitiveData.class, PrimitiveData.class.getName());
+    private final Collection<OsmPrimitive> primitives;
+
+    public PrimitiveTransferable(Collection<OsmPrimitive> members) {
+        this.primitives = members;
+    }
+
+    @Override
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[]{PRIMITIVE_DATA, DataFlavor.stringFlavor};
+    }
+
+    @Override
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return flavor == PRIMITIVE_DATA;
+    }
+
+    @Override
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
+        if (DataFlavor.stringFlavor.equals(flavor)) {
+            return getStringData();
+        } else if (PRIMITIVE_DATA.equals(flavor)) {
+            return getRelationMemberData();
+        }
+        throw new UnsupportedFlavorException(flavor);
+    }
+
+    protected String getStringData() {
+        final StringBuilder sb = new StringBuilder();
+        for (OsmPrimitive primitive : primitives) {
+            sb.append(primitive.getType());
+            sb.append(" ").append(primitive.getUniqueId());
+            sb.append(" #").append(primitive.getDisplayName(DefaultNameFormatter.getInstance()));
+            sb.append("\n");
+        }
+        return sb.toString().replace("\u200E", "").replace("\u200F", "");
+    }
+
+    protected Collection<PrimitiveData> getRelationMemberData() {
+        final Collection<PrimitiveData> r = new ArrayList<>(primitives.size());
+        for (OsmPrimitive primitive : primitives) {
+            r.add(primitive.save());
+        }
+        return r;
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java
new file mode 100644
index 0000000..b8afcd1
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java
@@ -0,0 +1,62 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.RelationMemberData;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+
+public class RelationMemberTransferable implements Transferable {
+
+    public static final DataFlavor RELATION_MEMBER_DATA = new DataFlavor(RelationMemberData.class, RelationMemberData.class.getName());
+    private final Collection<RelationMember> members;
+
+    public RelationMemberTransferable(Collection<RelationMember> members) {
+        this.members = members;
+    }
+
+    @Override
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[]{RELATION_MEMBER_DATA, DataFlavor.stringFlavor};
+    }
+
+    @Override
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return flavor == RELATION_MEMBER_DATA;
+    }
+
+    @Override
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
+        if (DataFlavor.stringFlavor.equals(flavor)) {
+            return getStringData();
+        } else if (RELATION_MEMBER_DATA.equals(flavor)) {
+            return getRelationMemberData();
+        }
+        throw new UnsupportedFlavorException(flavor);
+    }
+
+    protected String getStringData() {
+        final StringBuilder sb = new StringBuilder();
+        for (RelationMember member : members) {
+            sb.append(member.getType());
+            sb.append(" ").append(member.getUniqueId());
+            sb.append(" ").append(member.getRole());
+            sb.append(" #").append(member.getMember().getDisplayName(DefaultNameFormatter.getInstance()));
+            sb.append("\n");
+        }
+        return sb.toString().replace("\u200E", "").replace("\u200F", "");
+    }
+
+    protected Collection<RelationMemberData> getRelationMemberData() {
+        final Collection<RelationMemberData> r = new ArrayList<>(members.size());
+        for (RelationMember member : members) {
+            r.add(new RelationMemberData(member.getRole(), member.getType(), member.getUniqueId()));
+        }
+        return r;
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java b/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
index f9cdafd..9c9ec79 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
@@ -6,6 +6,7 @@
 
 import java.awt.Component;
 import java.awt.Rectangle;
+import java.awt.datatransfer.Transferable;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
@@ -23,10 +24,12 @@
 import javax.swing.AbstractAction;
 import javax.swing.AbstractListModel;
 import javax.swing.DefaultListSelectionModel;
+import javax.swing.JComponent;
 import javax.swing.JList;
 import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
 import javax.swing.ListSelectionModel;
+import javax.swing.TransferHandler;
 import javax.swing.event.ListDataEvent;
 import javax.swing.event.ListDataListener;
 import javax.swing.event.ListSelectionEvent;
@@ -65,6 +68,7 @@
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.gui.PopupMenuHandler;
 import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable;
 import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
@@ -107,8 +111,8 @@ protected void buildContentPanel() {
         lstPrimitives.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
         lstPrimitives.setSelectionModel(selectionModel);
         lstPrimitives.setCellRenderer(new OsmPrimitivRenderer());
-        // Fix #6290. Drag & Drop is not supported anyway and Copy/Paste is better propagated to main window
-        lstPrimitives.setTransferHandler(null);
+        lstPrimitives.setTransferHandler(new SelectionTransferHandler());
+        lstPrimitives.setDragEnabled(true);
 
         lstPrimitives.getSelectionModel().addListSelectionListener(actSelect);
         lstPrimitives.getSelectionModel().addListSelectionListener(actShowHistory);
@@ -854,4 +858,20 @@ public SelectionHistoryPopup(Collection<Collection<? extends OsmPrimitive>> hist
             }
         }
     }
+
+    /**
+     * A transfer handler class for drag-and-drop support.
+     */
+    protected class SelectionTransferHandler extends TransferHandler {
+
+        @Override
+        public int getSourceActions(JComponent c) {
+            return COPY;
+        }
+
+        @Override
+        protected Transferable createTransferable(JComponent c) {
+            return new PrimitiveTransferable(getSelectedPrimitives());
+        }
+    }
 }
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
index 3d41fd3..9eb25c7 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
@@ -14,6 +14,7 @@
 import java.util.List;
 
 import javax.swing.AbstractAction;
+import javax.swing.DropMode;
 import javax.swing.JComponent;
 import javax.swing.JPopupMenu;
 import javax.swing.JTable;
@@ -82,6 +83,11 @@ protected void init() {
         //
         getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
         getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
+
+        setTransferHandler(new MemberTransferHandler());
+        setFillsViewportHeight(true); // allow drop on empty table
+        setDragEnabled(true);
+        setDropMode(DropMode.INSERT_ROWS);
     }
 
     @Override
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
index f87ef71..7564a7e 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
@@ -422,22 +422,11 @@ public boolean hasIncompleteSelectedMembers() {
     }
 
     private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int index) {
-        final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets(EnumSet.of(TaggingPresetType.RELATION),
-                presetHandler.getSelection().iterator().next().getKeys(), false);
         if (primitives == null)
             return;
         int idx = index;
         for (OsmPrimitive primitive : primitives) {
-            Set<String> potentialRoles = new TreeSet<>();
-            for (TaggingPreset tp : presets) {
-                String suggestedRole = tp.suggestRoleForOsmPrimitive(primitive);
-                if (suggestedRole != null) {
-                    potentialRoles.add(suggestedRole);
-                }
-            }
-            // TODO: propose user to choose role among potential ones instead of picking first one
-            final String role = potentialRoles.isEmpty() ? null : potentialRoles.iterator().next();
-            RelationMember member = new RelationMember(role == null ? "" : role, primitive);
+            final RelationMember member = getRelationMemberForPrimitive(primitive);
             members.add(idx++, member);
         }
         fireTableDataChanged();
@@ -446,6 +435,29 @@ private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int inde
         fireMakeMemberVisible(index);
     }
 
+    RelationMember getRelationMemberForPrimitive(final OsmPrimitive primitive) {
+        final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets(EnumSet.of(TaggingPresetType.RELATION),
+                presetHandler.getSelection().iterator().next().getKeys(), false);
+        Collection<String> potentialRoles = new TreeSet<>();
+        for (TaggingPreset tp : presets) {
+            String suggestedRole = tp.suggestRoleForOsmPrimitive(primitive);
+            if (suggestedRole != null) {
+                potentialRoles.add(suggestedRole);
+            }
+        }
+        // TODO: propose user to choose role among potential ones instead of picking first one
+        final String role = potentialRoles.isEmpty() ? "" : potentialRoles.iterator().next();
+        return new RelationMember(role == null ? "" : role, primitive);
+    }
+
+    void addMembersAtIndex(final Iterable<RelationMember> newMembers, final int index) {
+        int idx = index;
+        for (RelationMember member : newMembers) {
+            members.add(idx++, member);
+        }
+        fireTableRowsInserted(index, idx - 1);
+    }
+
     public void addMembersAtBeginning(List<? extends OsmPrimitive> primitives) {
         addMembersAtIndex(primitives, 0);
     }
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
new file mode 100644
index 0000000..b4c42c7
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
@@ -0,0 +1,123 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs.relation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.TransferHandler;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveData;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.RelationMemberData;
+import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable;
+import org.openstreetmap.josm.gui.datatransfer.RelationMemberTransferable;
+import org.openstreetmap.josm.tools.Utils.Function;
+
+class MemberTransferHandler extends TransferHandler {
+
+    @Override
+    public int getSourceActions(JComponent c) {
+        return COPY_OR_MOVE;
+    }
+
+    @Override
+    protected Transferable createTransferable(JComponent c) {
+        final MemberTable source = (MemberTable) c;
+        return new RelationMemberTransferable(source.getMemberTableModel().getSelectedMembers());
+    }
+
+    @Override
+    public boolean canImport(TransferSupport support) {
+        support.setShowDropLocation(true);
+        return support.isDataFlavorSupported(RelationMemberTransferable.RELATION_MEMBER_DATA)
+                || support.isDataFlavorSupported(PrimitiveTransferable.PRIMITIVE_DATA);
+    }
+
+    @Override
+    public boolean importData(TransferSupport support) {
+        final MemberTable destination = (MemberTable) support.getComponent();
+        final int insertRow = ((JTable.DropLocation) support.getDropLocation()).getRow();
+
+        try {
+            if (support.isDataFlavorSupported(RelationMemberTransferable.RELATION_MEMBER_DATA)) {
+                importRelationMemberData(support, destination, insertRow);
+            } else if (support.isDataFlavorSupported(PrimitiveTransferable.PRIMITIVE_DATA)) {
+                importPrimitiveData(support, destination, insertRow);
+            }
+        } catch (Exception e) {
+            Main.warn(e);
+            return false;
+        }
+
+        return true;
+    }
+
+    protected void importRelationMemberData(TransferSupport support, final MemberTable destination, int insertRow)
+            throws UnsupportedFlavorException, IOException {
+        //noinspection unchecked
+        final Collection<RelationMemberData> memberData = (Collection<RelationMemberData>)
+                support.getTransferable().getTransferData(RelationMemberTransferable.RELATION_MEMBER_DATA);
+        importData(destination, insertRow, memberData, new Function<RelationMemberData, RelationMember>() {
+            @Override
+            public RelationMember apply(RelationMemberData member) {
+                final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(member.getUniqueId(), member.getType());
+                if (p == null) {
+                    Main.warn(tr("Cannot add {0} since it is not part of dataset", member));
+                    return null;
+                } else {
+                    return new RelationMember(member.getRole(), p);
+                }
+            }
+        });
+    }
+
+    protected void importPrimitiveData(TransferSupport support, final MemberTable destination, int insertRow)
+            throws UnsupportedFlavorException, IOException {
+        //noinspection unchecked
+        final Collection<PrimitiveData> data = (Collection<PrimitiveData>)
+                support.getTransferable().getTransferData(PrimitiveTransferable.PRIMITIVE_DATA);
+        importData(destination, insertRow, data, new Function<PrimitiveData, RelationMember>() {
+            @Override
+            public RelationMember apply(PrimitiveData data) {
+                final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(data);
+                if (p == null) {
+                    Main.warn(tr("Cannot add {0} since it is not part of dataset", data));
+                    return null;
+                } else {
+                    return destination.getMemberTableModel().getRelationMemberForPrimitive(p);
+                }
+            }
+        });
+    }
+
+    protected <T> void importData(MemberTable destination, int insertRow, Collection<T> memberData, Function<T, RelationMember> toMemberFunction) {
+        final Collection<RelationMember> membersToAdd = new ArrayList<>(memberData.size());
+        for (T i : memberData) {
+            final RelationMember member = toMemberFunction.apply(i);
+            if (member != null) {
+                membersToAdd.add(member);
+            }
+        }
+        destination.getMemberTableModel().addMembersAtIndex(membersToAdd, insertRow);
+    }
+
+    @Override
+    protected void exportDone(JComponent sourceComponent, Transferable data, int action) {
+        if (action != MOVE) {
+            return;
+        }
+        final MemberTable source = (MemberTable) sourceComponent;
+        final MemberTableModel model = source.getMemberTableModel();
+        model.remove(source.getSelectedRows());
+        model.selectionChanged(null);
+    }
+}
