diff --git a/Grinder/Grinder.pro b/Grinder/Grinder.pro
index ec831b0d9565e301ee2844ea3b1cccf6e98d0032..432a1f62db583146ec0fa0cdfd034629e1d63b8b 100644
--- a/Grinder/Grinder.pro
+++ b/Grinder/Grinder.pro
@@ -496,7 +496,8 @@ SOURCES += \
     ui/ml/rf/RandomForestFeaturesDialog.cpp \
     ml/blocks/MergeInferenceBlock.cpp \
     ml/processors/MergeInferenceProcessor.cpp \
-    engine/EngineUtils.cpp
+    engine/EngineUtils.cpp \
+    ui/image/PasteNodesDialog.cpp
 
 HEADERS += \
 	ui/mainwnd/GrinderWindow.h \
@@ -1086,7 +1087,8 @@ HEADERS += \
     ui/ml/rf/RandomForestFeaturesDialog.h \
     ml/blocks/MergeInferenceBlock.h \
     ml/processors/MergeInferenceProcessor.h \
-    engine/EngineUtils.h
+    engine/EngineUtils.h \
+    ui/image/PasteNodesDialog.h
 
 FORMS += \
 	ui/mainwnd/GrinderWindow.ui \
@@ -1107,7 +1109,8 @@ FORMS += \
 	ui/cmd/tasks/CommandInterfaceTestTaskWidget.ui \
     ui/dlg/BrowseDialog.ui \
     ui/image/LayerSettingsDialog.ui \
-    ui/ml/rf/RandomForestFeaturesDialog.ui
+    ui/ml/rf/RandomForestFeaturesDialog.ui \
+    ui/image/PasteNodesDialog.ui
 
 RESOURCES += \
 	res/Grinder.qrc
diff --git a/Grinder/Version.h b/Grinder/Version.h
index 30111b3a55c4b36160ffe1f99f25ebb9c8dd1444..4c5e8d43c17eb8f05f9018b9bd1c3fe19a2715c5 100644
--- a/Grinder/Version.h
+++ b/Grinder/Version.h
@@ -10,14 +10,14 @@
 
 #define GRNDR_INFO_TITLE		"Grinder"
 #define GRNDR_INFO_COPYRIGHT	"Copyright (c) WWU Muenster"
-#define GRNDR_INFO_DATE			"10.02.2020"
+#define GRNDR_INFO_DATE			"26.02.2020"
 #define GRNDR_INFO_COMPANY		"WWU Muenster"
 #define GRNDR_INFO_WEBSITE		"http://www.uni-muenster.de"
 
 #define GRNDR_VERSION_MAJOR		0
 #define GRNDR_VERSION_MINOR		17
 #define GRNDR_VERSION_REVISION	0
-#define GRNDR_VERSION_BUILD		431
+#define GRNDR_VERSION_BUILD		433
 
 namespace grndr
 {
diff --git a/Grinder/controller/ImageEditorController.cpp b/Grinder/controller/ImageEditorController.cpp
index 7a3feea81efe53aab93452e13b1518d257f9e6de..f836a24a6d487aa4a27689ea4abb0816065fccfa 100644
--- a/Grinder/controller/ImageEditorController.cpp
+++ b/Grinder/controller/ImageEditorController.cpp
@@ -839,6 +839,56 @@ void ImageEditorController::pasteSelectedNodes()
 	});
 }
 
+void ImageEditorController::pasteSelectedNodesTo(std::vector<const ImageReference*> targetImageReferences, QString layerName)
+{
+	callControllerFunction("Pasting draft items", [this](std::vector<const ImageReference*> targetImageReferences, QString layerName) {
+		_undoStack.beginMerging();
+
+		LongOperation opPasteNodes{"Pasting draft items", static_cast<unsigned int>(targetImageReferences.size()), true};
+
+		// Paste the items onto each target image reference
+		for (auto imageRef : targetImageReferences)
+		{
+			LongOperationStep opPasteToImage{QString{"Pasting to '%1'"}.arg(imageRef->getImageFileName())};
+
+			if (const auto activeLabel = grinder()->projectController().activeLabel())
+			{
+				// Ensure that the image build exists
+				grinder()->engineController().executeLabel(nullptr, imageRef, Engine::ExecutionMode::Execute);
+
+				// Get the target image build for pasting
+				if (auto targetImageBuild = activeLabel->imageBuildPool().imageBuild(_activeImageBuild->block(), imageRef))
+				{
+					QApplication::processEvents();
+
+					// Create the target layer if necessary
+					auto layer = targetImageBuild->layers().selectByName(layerName);
+
+					if (!layer)
+						layer = targetImageBuild->createLayer(layerName);
+
+					if (layer && checkLayerEditability(layer.get(), false))
+					{
+						// Create draft items for each object in the clipboard
+						grinder()->clipboardManager().deserialize<DraftItem>(DraftItemVector::Serialization_Element, [this, &layer](const SettingsContainer& settings) {
+							DraftItemType type = settings(DraftItem::Serialization_Value_Type, DraftItemType::Undefined).toString();
+
+							return createDraftItem(type, layer.get(), false).get();
+						});
+					}
+				}
+			}
+
+			if (opPasteNodes.wasCanceled())
+				break;
+		}
+
+		_undoStack.endMerging();
+
+		return true;
+	}, targetImageReferences, layerName);
+}
+
 void ImageEditorController::cutSelectedNodes() const
 {
 	copySelectedNodes();
diff --git a/Grinder/controller/ImageEditorController.h b/Grinder/controller/ImageEditorController.h
index 11ef383a1e3a457c0cd4de828508e58a9799c278..7e0e55fe11673c7f9bfb6eb056d315f7ca070f2b 100644
--- a/Grinder/controller/ImageEditorController.h
+++ b/Grinder/controller/ImageEditorController.h
@@ -92,6 +92,7 @@ namespace grndr
 
 		void copySelectedNodes() const;
 		void pasteSelectedNodes();
+		void pasteSelectedNodesTo(std::vector<const ImageReference*> targetImageReferences, QString layerName);
 		void cutSelectedNodes() const;
 		void removeSelectedNodes() const;
 
diff --git a/Grinder/ui/image/ImageEditorView.cpp b/Grinder/ui/image/ImageEditorView.cpp
index a2d7dac8075a4021b5f7105e76abe7fe87c84edc..1d18ef7ec474b4df54d4e1d1791b225793922ab1 100644
--- a/Grinder/ui/image/ImageEditorView.cpp
+++ b/Grinder/ui/image/ImageEditorView.cpp
@@ -10,6 +10,7 @@
 #include "DraftItemNode.h"
 #include "core/GrinderApplication.h"
 #include "controller/ImageEditorController.h"
+#include "ui/image/PasteNodesDialog.h"
 #include "ui/UIUtils.h"
 #include "res/Resources.h"
 
@@ -48,6 +49,7 @@ ImageEditorView::ImageEditorView(QWidget* parent) : VisualSceneView(parent)
 	_copyDraftItems->setShortcut(QKeySequence{QKeySequence::Copy});
 	_pasteDraftItems = UIUtils::createAction(this, "&Paste item(s)", FILE_ICON_PASTE, SLOT(pasteDraftItems()), "Paste items from the clipboard");
 	_pasteDraftItems->setShortcut(QKeySequence{QKeySequence::Paste});
+	_pasteDraftItemsTo = UIUtils::createAction(this, "Paste item(s) &to...", FILE_ICON_PASTE, SLOT(pasteDraftItemsTo()), "Paste items from the clipboard to one or more images", "Ctrl+Shift+V");
 	_cutDraftItems = UIUtils::createAction(this, "Cu&t item(s)", FILE_ICON_CUT, SLOT(cutDraftItems()), "Copy the selected items to the clipboard and remove them afterwards");
 	_cutDraftItems->setShortcut(QKeySequence{QKeySequence::Cut});
 	_convertDraftItemsAction = UIUtils::createAction(this, "&Convert to pixels", FILE_ICON_EDITOR_CONVERTTOPIXELS, SLOT(convertDraftItems()), "Converts the selected items to pixels", "Return");
@@ -116,6 +118,7 @@ void ImageEditorView::prepareNodeContextMenu(QMenu& menu) const
 	menu.insertAction(firstAction, _cutDraftItems);
 	menu.insertAction(firstAction, _copyDraftItems);
 	menu.insertAction(firstAction, _pasteDraftItems);
+	menu.insertAction(firstAction, _pasteDraftItemsTo);
 	menu.insertSeparator(firstAction);
 	menu.insertAction(firstAction, _convertDraftItemsAction);
 }
@@ -134,6 +137,7 @@ std::vector<QAction*> ImageEditorView::getActions(AddActionsMode mode) const
 		actions.push_back(_cutDraftItems);
 		actions.push_back(_copyDraftItems);
 		actions.push_back(_pasteDraftItems);
+		actions.push_back(_pasteDraftItemsTo);
 		actions.push_back(nullptr);
 
 		actions.push_back(_selectAllAction);
@@ -242,6 +246,7 @@ void ImageEditorView::updateActions()
 
 	_copyDraftItems->setEnabled(_scene && draftItemSelected);
 	_pasteDraftItems->setEnabled(_scene && grinder()->clipboardManager().hasData(DraftItemVector::Serialization_Element) && activeLayerEditable);
+	_pasteDraftItemsTo->setEnabled(_scene && grinder()->clipboardManager().hasData(DraftItemVector::Serialization_Element));
 	_cutDraftItems->setEnabled(_scene && draftItemSelected && editableItemSelected);
 	_convertDraftItemsAction->setEnabled(_scene && draftItemSelected && editableItemSelected);
 	_deleteSelectedAction->setEnabled(_deleteSelectedAction->isEnabled() && draftItemSelected && editableItemSelected);
@@ -405,6 +410,20 @@ void ImageEditorView::pasteDraftItems() const
 		_editorScene->imageEditor()->controller().pasteSelectedNodes();
 }
 
+void ImageEditorView::pasteDraftItemsTo() const
+{
+	if (_editorScene)
+	{
+		if (auto layer = _editorScene->imageEditor()->controller().activeLayer())
+		{
+			PasteNodesDialog dlg{layer->getName()};
+
+			if (dlg.exec() == QDialog::Accepted)
+				_editorScene->imageEditor()->controller().pasteSelectedNodesTo(dlg.getImageReferences().imageReferences(), dlg.getLayerName());
+		}
+	}
+}
+
 void ImageEditorView::cutDraftItems() const
 {
 	if (_editorScene)
diff --git a/Grinder/ui/image/ImageEditorView.h b/Grinder/ui/image/ImageEditorView.h
index f77e39d1dc1b44ac9aaf5c6881c243a6caeceed1..eeb0aaac91e6b48d2b722701217c42eefc07de05 100644
--- a/Grinder/ui/image/ImageEditorView.h
+++ b/Grinder/ui/image/ImageEditorView.h
@@ -77,6 +77,7 @@ namespace grndr
 
 		void copyDraftItems() const;
 		void pasteDraftItems() const;
+		void pasteDraftItemsTo() const;
 		void cutDraftItems() const;
 		void convertDraftItems() const;	
 
@@ -96,6 +97,7 @@ namespace grndr
 
 		QAction* _copyDraftItems{nullptr};
 		QAction* _pasteDraftItems{nullptr};
+		QAction* _pasteDraftItemsTo{nullptr};
 		QAction* _cutDraftItems{nullptr};
 		QAction* _convertDraftItemsAction{nullptr};
 	};
diff --git a/Grinder/ui/image/PasteNodesDialog.cpp b/Grinder/ui/image/PasteNodesDialog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d11332d39e832a58e6a85ace9c598a51982a21ba
--- /dev/null
+++ b/Grinder/ui/image/PasteNodesDialog.cpp
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * File: PasteNodesDialog.cpp
+ * Date: 26.2.2020
+ *****************************************************************************/
+
+#include "Grinder.h"
+#include "PasteNodesDialog.h"
+#include "ui_PasteNodesDialog.h"
+#include "core/GrinderApplication.h"
+
+PasteNodesDialog::PasteNodesDialog(QString layerName, QWidget *parent) : QDialog(parent, Qt::Dialog|Qt::WindowTitleHint|Qt::WindowCloseButtonHint),
+	ui{new Ui::PasteNodesDialog}
+{
+	setupUi(layerName);
+
+	fillImageReferences(grinder()->project().imageReferences());
+}
+
+PasteNodesDialog::~PasteNodesDialog()
+{
+	delete ui;
+}
+
+ImageReferenceSelection PasteNodesDialog::getImageReferences() const
+{
+	return ui->lstImageReferences->getSelectedImageReferences();
+}
+
+QString PasteNodesDialog::getLayerName() const
+{
+	return ui->txtLayerName->text();
+}
+
+void PasteNodesDialog::accept()
+{
+	// Make sure that a layer name was entered
+	if (ui->txtLayerName->text().isEmpty())
+	{
+		QMessageBox::warning(nullptr, "Paste item(s) to...", "Please enter a layer name.");
+		ui->txtLayerName->setFocus();
+		return;
+	}
+
+	QDialog::accept();
+}
+
+void PasteNodesDialog::setupUi(QString layerName)
+{
+	ui->setupUi(this);
+
+	ui->txtLayerName->setText(layerName);
+
+	// The OK button should only be enabled if at least one image reference is checked
+	connect(ui->lstImageReferences, &QListWidget::itemChanged, this, &PasteNodesDialog::imageReferencesListItemChanged);
+
+	updateUi();
+}
+
+void PasteNodesDialog::updateUi()
+{
+	ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ui->lstImageReferences->getCheckedObjects().size() > 0);
+}
+
+void PasteNodesDialog::fillImageReferences(const ImageReferenceVector& imageRefs)
+{
+	ui->lstImageReferences->populate(imageRefs);
+	ui->lstImageReferences->checkObject(grinder()->projectController().activeImageReference(), false);
+}
diff --git a/Grinder/ui/image/PasteNodesDialog.h b/Grinder/ui/image/PasteNodesDialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7a6cca7a6d0543143ec6c01bae1f73f44e444b8
--- /dev/null
+++ b/Grinder/ui/image/PasteNodesDialog.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * File: PasteNodesDialog.h
+ * Date: 26.2.2020
+ *****************************************************************************/
+
+#ifndef PASTENODESDIALOG_H
+#define PASTENODESDIALOG_H
+
+#include <QDialog>
+
+#include "project/ImageReference.h"
+#include "ui/widgets/project/ImageReferencesCheckListWidget.h"
+#include "ui/mainwnd/ImageReferencesListItem.h"
+
+namespace Ui
+{
+	class PasteNodesDialog;
+}
+
+namespace grndr
+{
+	class Project;
+	class ImageReferenceVector;
+
+	class PasteNodesDialog : public QDialog
+	{
+		Q_OBJECT
+
+	public:
+		PasteNodesDialog(QString layerName = "", QWidget *parent = nullptr);
+		~PasteNodesDialog();
+
+	public:
+		ImageReferenceSelection getImageReferences() const;
+		QString getLayerName() const;
+
+	public slots:
+		virtual void accept() override;
+
+	private:
+		Ui::PasteNodesDialog *ui;
+		void setupUi(QString layerName);
+		void updateUi();
+
+	private slots:
+		void imageReferencesListItemChanged(QListWidgetItem* item) { Q_UNUSED(item); updateUi(); }
+
+	private:
+		void fillImageReferences(const ImageReferenceVector& imageRefs);
+	};
+}
+
+#endif
diff --git a/Grinder/ui/image/PasteNodesDialog.ui b/Grinder/ui/image/PasteNodesDialog.ui
new file mode 100644
index 0000000000000000000000000000000000000000..2f65508d1252a96ed921ce85e8acc3bcb3db3ed6
--- /dev/null
+++ b/Grinder/ui/image/PasteNodesDialog.ui
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasteNodesDialog</class>
+ <widget class="QDialog" name="PasteNodesDialog">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>376</width>
+    <height>499</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Paste item(s) to...</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <property name="modal">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Images</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <widget class="ImageReferencesCheckListWidget" name="lstImageReferences">
+        <property name="selectionMode">
+         <enum>QAbstractItemView::ExtendedSelection</enum>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Layer</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="txtLayerName"/>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>&amp;Name:</string>
+        </property>
+        <property name="buddy">
+         <cstring>txtLayerName</cstring>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Fixed</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>200</width>
+       <height>17</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ImageReferencesCheckListWidget</class>
+   <extends>QListWidget</extends>
+   <header>ui/widgets/project/ImageReferencesCheckListWidget.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>PasteNodesDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>PasteNodesDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/Grinder/ui/widgets/CheckListWidget.h b/Grinder/ui/widgets/CheckListWidget.h
index 658d8aa7f141f08885ee7cb12a864a021880041f..7701a8751f42288d556b23b177ac41e1f9b099cc 100644
--- a/Grinder/ui/widgets/CheckListWidget.h
+++ b/Grinder/ui/widgets/CheckListWidget.h
@@ -28,6 +28,8 @@ namespace grndr
 		template<typename ObjectReturnType = ObjectType>
 		void setCheckedObjects(const std::vector<ObjectReturnType*>& checkedObjects);
 
+		void checkObject(const ObjectType* obj, bool check = true);
+
 	protected:
 		virtual void contextMenuEvent(QContextMenuEvent* event) override;
 
diff --git a/Grinder/ui/widgets/CheckListWidget.impl.h b/Grinder/ui/widgets/CheckListWidget.impl.h
index ff78e7e92b7727b44fbb1130d7f269d82e415e38..3df3e450394d65fd276a7b96b217b8fbb14dd76a 100644
--- a/Grinder/ui/widgets/CheckListWidget.impl.h
+++ b/Grinder/ui/widgets/CheckListWidget.impl.h
@@ -71,6 +71,22 @@ void CheckListWidget<ObjectType, ItemType>::setCheckedObjects(const std::vector<
 	}
 }
 
+template<typename ObjectType, typename ItemType>
+void CheckListWidget<ObjectType, ItemType>::checkObject(const ObjectType* obj, bool check)
+{
+	for (int i = 0; i < this->count(); ++i)
+	{
+		if (auto item = dynamic_cast<ItemType*>(this->item(i)))
+		{
+			if (static_cast<const ObjectType*>(item->object()) == obj)
+			{
+				item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
+				break;
+			}
+		}
+	}
+}
+
 template<typename ObjectType, typename ItemType>
 void CheckListWidget<ObjectType, ItemType>::contextMenuEvent(QContextMenuEvent* event)
 {