diff --git a/src/org/openstreetmap/josm/actions/AbstractPasteAction.java b/src/org/openstreetmap/josm/actions/AbstractPasteAction.java
new file mode 100644
index 0000000..183d3af
--- /dev/null
+++ b/src/org/openstreetmap/josm/actions/AbstractPasteAction.java
@@ -0,0 +1,83 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions;
+
+import java.awt.MouseInfo;
+import java.awt.Point;
+import java.awt.datatransfer.FlavorEvent;
+import java.awt.datatransfer.FlavorListener;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.ActionEvent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
+import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * This is the base class for all actions that paste objects.
+ * @author Michael Zangl
+ * @since xxx
+ */
+public abstract class AbstractPasteAction extends JosmAction implements FlavorListener {
+
+    protected final OsmTransferHandler transferHandler;
+
+    /**
+     * Create a new {@link AbstractPasteAction}
+     * @param name See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)}
+     * @param iconName See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)}
+     * @param tooltip See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)}
+     * @param shortcut See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)}
+     * @param registerInToolbar See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)}
+     */
+    public AbstractPasteAction(String name, String iconName, String tooltip, Shortcut shortcut,
+            boolean registerInToolbar) {
+        super(name, iconName, tooltip, shortcut, registerInToolbar);
+        transferHandler = new OsmTransferHandler();
+        ClipboardUtils.getClipboard().addFlavorListener(this);
+    }
+
+    /**
+     * Compute the location the objects should be pasted at.
+     * @param e The action event that triggered the paste
+     * @return The paste position.
+     */
+    protected EastNorth computePastePosition(ActionEvent e) {
+        // default to paste in center of map (pasted via menu or cursor not in MapView)
+        EastNorth mPosition = Main.map.mapView.getCenter();
+        // We previously checked for modifier to know if the action has been trigerred via shortcut or via menu
+        // But this does not work if the shortcut is changed to a single key (see #9055)
+        // Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it
+        if (e != null && !getValue(NAME).equals(e.getActionCommand())) {
+            final Point mp = MouseInfo.getPointerInfo().getLocation();
+            final Point tl = Main.map.mapView.getLocationOnScreen();
+            final Point pos = new Point(mp.x-tl.x, mp.y-tl.y);
+            if (Main.map.mapView.contains(pos)) {
+                mPosition = Main.map.mapView.getEastNorth(pos.x, pos.y);
+            }
+        }
+        return mPosition;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Transferable contents = ClipboardUtils.getClipboard().getContents(null);
+        doPaste(e, contents);
+    }
+
+    protected void doPaste(ActionEvent e, Transferable contents) {
+        transferHandler.pasteOn(Main.getLayerManager().getEditLayer(), computePastePosition(e), contents);
+    }
+
+    @Override
+    protected void updateEnabledState() {
+        setEnabled(getLayerManager().getEditDataSet() != null && transferHandler.isDataAvailable());
+    }
+
+    @Override
+    public void flavorsChanged(FlavorEvent e) {
+        updateEnabledState();
+    }
+
+}
diff --git a/src/org/openstreetmap/josm/actions/DuplicateAction.java b/src/org/openstreetmap/josm/actions/DuplicateAction.java
index 66efb08..cb8bb5d 100644
--- a/src/org/openstreetmap/josm/actions/DuplicateAction.java
+++ b/src/org/openstreetmap/josm/actions/DuplicateAction.java
@@ -9,9 +9,7 @@ import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
 import java.util.Collection;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
 import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable;
 import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -19,7 +17,7 @@ import org.openstreetmap.josm.tools.Shortcut;
 /**
  * An action that duplicates the given nodes. They are not added to the clipboard.
  */
-public final class DuplicateAction extends JosmAction {
+public final class DuplicateAction extends AbstractPasteAction {
 
     /**
      * Constructs a new {@code DuplicateAction}.
@@ -34,8 +32,7 @@ public final class DuplicateAction extends JosmAction {
     @Override
     public void actionPerformed(ActionEvent e) {
         PrimitiveTransferData data = PrimitiveTransferData.getDataWithReferences(getLayerManager().getEditDataSet().getSelected());
-        new OsmTransferHandler().pasteOn(Main.getLayerManager().getEditLayer(),
-                PasteAction.computePastePosition(e, getValue(NAME)), new PrimitiveTransferable(data));
+        doPaste(e, new PrimitiveTransferable(data));
     }
 
     @Override
diff --git a/src/org/openstreetmap/josm/actions/PasteAction.java b/src/org/openstreetmap/josm/actions/PasteAction.java
index 9ab5725..b54f14b 100644
--- a/src/org/openstreetmap/josm/actions/PasteAction.java
+++ b/src/org/openstreetmap/josm/actions/PasteAction.java
@@ -5,70 +5,26 @@ package org.openstreetmap.josm.actions;
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.MouseInfo;
-import java.awt.Point;
-import java.awt.datatransfer.FlavorEvent;
-import java.awt.datatransfer.FlavorListener;
-import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
-import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
  * Paste OSM primitives from clipboard to the current edit layer.
  * @since 404
  */
-public final class PasteAction extends JosmAction implements FlavorListener {
-
-    private final OsmTransferHandler transferHandler;
+public final class PasteAction extends AbstractPasteAction {
 
     /**
      * Constructs a new {@code PasteAction}.
      */
     public PasteAction() {
-        super(tr("Paste"), "paste", tr("Paste contents of paste buffer."),
+        super(tr("Paste"), "paste", tr("Paste contents of clipboard."),
                 Shortcut.registerShortcut("system:paste", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_V, Shortcut.CTRL), true);
         putValue("help", ht("/Action/Paste"));
         // CUA shortcut for paste (https://en.wikipedia.org/wiki/IBM_Common_User_Access#Description)
         Main.registerActionShortcut(this,
                 Shortcut.registerShortcut("system:paste:cua", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_INSERT, Shortcut.SHIFT));
-        transferHandler = new OsmTransferHandler();
-        ClipboardUtils.getClipboard().addFlavorListener(this);
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        transferHandler.pasteOn(Main.getLayerManager().getEditLayer(), computePastePosition(e, getValue(NAME)));
-    }
-
-    static EastNorth computePastePosition(ActionEvent e, Object name) {
-        // default to paste in center of map (pasted via menu or cursor not in MapView)
-        EastNorth mPosition = Main.map.mapView.getCenter();
-        // We previously checked for modifier to know if the action has been trigerred via shortcut or via menu
-        // But this does not work if the shortcut is changed to a single key (see #9055)
-        // Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it
-        if (e != null && !name.equals(e.getActionCommand())) {
-            final Point mp = MouseInfo.getPointerInfo().getLocation();
-            final Point tl = Main.map.mapView.getLocationOnScreen();
-            final Point pos = new Point(mp.x-tl.x, mp.y-tl.y);
-            if (Main.map.mapView.contains(pos)) {
-                mPosition = Main.map.mapView.getEastNorth(pos.x, pos.y);
-            }
-        }
-        return mPosition;
-    }
-
-    @Override
-    protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditDataSet() != null && transferHandler.isDataAvailable());
-    }
-
-    @Override
-    public void flavorsChanged(FlavorEvent e) {
-        updateEnabledState();
     }
 }
diff --git a/src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java b/src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java
new file mode 100644
index 0000000..86a1f14
--- /dev/null
+++ b/src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java
@@ -0,0 +1,34 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * A special version of the {@link PasteAction} that pastes at the exact source location the item was copied from.
+ * @author Michael Zangl
+ * @since xxx
+ */
+public class PasteAtSourcePositionAction extends AbstractPasteAction {
+    /**
+     * Constructs a new {@link PasteAtSourcePositionAction}
+     */
+    public PasteAtSourcePositionAction() {
+        super(tr("Paste at source position"), "paste", tr("Paste contents of clipboard at the position they were copied from."),
+                Shortcut.registerShortcut("menu:edit:pasteAtSource", tr("Edit: {0}", tr("Paste at source position")),
+                        KeyEvent.VK_V, Shortcut.ALT_CTRL), true);
+        putValue("help", ht("/Action/Paste"));
+    }
+
+    @Override
+    protected EastNorth computePastePosition(ActionEvent e) {
+        // null means use old position
+        return null;
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/MainMenu.java b/src/org/openstreetmap/josm/gui/MainMenu.java
index 172e60b..060c293 100644
--- a/src/org/openstreetmap/josm/gui/MainMenu.java
+++ b/src/org/openstreetmap/josm/gui/MainMenu.java
@@ -73,6 +73,7 @@ import org.openstreetmap.josm.actions.OrthogonalizeAction;
 import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
 import org.openstreetmap.josm.actions.OverpassDownloadAction;
 import org.openstreetmap.josm.actions.PasteAction;
+import org.openstreetmap.josm.actions.PasteAtSourcePositionAction;
 import org.openstreetmap.josm.actions.PasteTagsAction;
 import org.openstreetmap.josm.actions.PreferenceToggleAction;
 import org.openstreetmap.josm.actions.PreferencesAction;
@@ -194,6 +195,8 @@ public class MainMenu extends JMenuBar {
     public final JosmAction copyCoordinates = new CopyCoordinatesAction();
     /** Edit / Paste */
     public final PasteAction paste = new PasteAction();
+    /** Edit / Paste at source */
+    private final PasteAtSourcePositionAction pasteAtSource = new PasteAtSourcePositionAction();
     /** Edit / Paste Tags */
     public final PasteTagsAction pasteTags = new PasteTagsAction();
     /** Edit / Duplicate */
@@ -679,6 +682,7 @@ public class MainMenu extends JMenuBar {
         add(editMenu, copy);
         add(editMenu, copyCoordinates, true);
         add(editMenu, paste);
+        add(editMenu, pasteAtSource);
         add(editMenu, pasteTags);
         add(editMenu, duplicate);
         add(editMenu, delete);
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
index 5001c48..fdc8b89 100644
--- a/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
+++ b/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
@@ -82,7 +82,7 @@ public class OsmTransferHandler extends TransferHandler {
     /**
      * Paste the current clipboard current at the given position
      * @param editLayer The layer to paste on.
-     * @param mPosition The position to paste at.
+     * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used.
      */
     public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition) {
         Transferable transferable = ClipboardUtils.getClipboard().getContents(null);
@@ -92,7 +92,7 @@ public class OsmTransferHandler extends TransferHandler {
     /**
      * Paste the given clipboard current at the given position
      * @param editLayer The layer to paste on.
-     * @param mPosition The position to paste at.
+     * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used.
      * @param transferable The transferable to use.
      */
     public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition, Transferable transferable) {
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java b/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java
index 1823263..804b209 100644
--- a/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java
+++ b/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java
@@ -49,7 +49,7 @@ public final class PrimitiveDataPaster extends AbstractOsmDataPaster {
         }
 
         EastNorth center = pasteBuffer.getCenter();
-        EastNorth offset = center == null ? null : pasteAt.subtract(center);
+        EastNorth offset = center == null || pasteAt == null ? new EastNorth(0, 0) : pasteAt.subtract(center);
 
         AddPrimitivesCommand command = createNewPrimitives(pasteBuffer, offset, layer);
 
