diff --git a/GUI/Model/Data/Data2DItem.cpp b/GUI/Model/Data/Data2DItem.cpp
index 93bcc5ad8885b4dc8f8f7abf5b15e74a55674415..34e14fd912a87768d804b8a09a7a75d3c365e6f2 100644
--- a/GUI/Model/Data/Data2DItem.cpp
+++ b/GUI/Model/Data/Data2DItem.cpp
@@ -334,11 +334,9 @@ Datafield* Data2DItem::createMaskedField() const
     std::unique_ptr<IShape2D> roi;
     Datafield* result = c_field()->clone();
     MaskStack detectorMask;
-    const auto& maskItems = masksSet()->shared();
 
     // reverse loop (waiting for C++ ranges)
-    for (auto maskIter = maskItems.crbegin(); maskIter != maskItems.crend(); maskIter++) {
-        const MaskItem* t = *maskIter;
+    for (auto t : *masksSet()) {
         if (t->isVisible()) {
             if (auto* roiItem = dynamic_cast<const RegionOfInterestItem*>(t))
                 roi = roiItem->createShape();
diff --git a/GUI/Model/Detector/DetectorItem.cpp b/GUI/Model/Detector/DetectorItem.cpp
index f530981102d21ef5c934fedca7569e9806bc894b..a7fc3024fa76325bd7429ad7df636cf160b6fafc 100644
--- a/GUI/Model/Detector/DetectorItem.cpp
+++ b/GUI/Model/Detector/DetectorItem.cpp
@@ -70,11 +70,7 @@ std::unique_ptr<IDetector> DetectorItem::createDetector() const
     auto result = std::make_unique<Detector2D>(x_wid, y_wid, n_x, n_y, x_cen, y_cen);
 
     if (m_masks) {
-        const auto& maskItems = m_masks->shared();
-
-        // reverse loop (waiting for C++ ranges)
-        for (auto maskIter = maskItems.crbegin(); maskIter != maskItems.crend(); maskIter++) {
-            const MaskItem* m = *maskIter;
+        for (const auto m : *m_masks) {
             if (m->isVisible()) {
                 if (auto* ii = dynamic_cast<const RegionOfInterestItem*>(m)) {
                     result->setRegionOfInterest(ii->xLow(), ii->yLow(), ii->xUp(), ii->yUp());
diff --git a/GUI/Model/FromCore/ItemizeSimulation.cpp b/GUI/Model/FromCore/ItemizeSimulation.cpp
index 75ac2d507796361ff815bfcf61f71c0bba46cd31..84afcfd35d46a010f50f47798ef8854411601b7d 100644
--- a/GUI/Model/FromCore/ItemizeSimulation.cpp
+++ b/GUI/Model/FromCore/ItemizeSimulation.cpp
@@ -66,7 +66,7 @@ MasksSet* getMasksSet(const IDetector& detector)
             ellipseItem->setAngle(ellipse->getTheta());
             ellipseItem->setMaskValue(mask_value);
             // TODO: why prepend the mask, instead of appending it?
-            result->insert_at(0, ellipseItem);
+            result->add_item(ellipseItem);
         }
 
         else if (const auto* rectangle = dynamic_cast<const Rectangle*>(shape)) {
@@ -77,7 +77,7 @@ MasksSet* getMasksSet(const IDetector& detector)
             rectangleItem->setYUp(rectangle->getYup());
             rectangleItem->setMaskValue(mask_value);
             // TODO: why prepend the mask, instead of appending it?
-            result->insert_at(0, rectangleItem);
+            result->add_item(rectangleItem);
         }
 
         else if (const auto* polygon = dynamic_cast<const Polygon*>(shape)) {
@@ -90,7 +90,7 @@ MasksSet* getMasksSet(const IDetector& detector)
             polygonItem->setMaskValue(mask_value);
             polygonItem->setIsClosed(true);
             // TODO: why prepend the mask, instead of appending it?
-            result->insert_at(0, polygonItem);
+            result->add_item(polygonItem);
         }
 
         else if (const auto* vline = dynamic_cast<const VerticalLine*>(shape)) {
@@ -98,7 +98,7 @@ MasksSet* getMasksSet(const IDetector& detector)
             lineItem->setPos(vline->getXpos());
             lineItem->setMaskValue(mask_value);
             // TODO: why prepend the mask, instead of appending it?
-            result->insert_at(0, lineItem);
+            result->add_item(lineItem);
         }
 
         else if (const auto* hline = dynamic_cast<const HorizontalLine*>(shape)) {
@@ -106,14 +106,14 @@ MasksSet* getMasksSet(const IDetector& detector)
             lineItem->setPos(hline->getYpos());
             lineItem->setMaskValue(mask_value);
             // TODO: why prepend the mask, instead of appending it?
-            result->insert_at(0, lineItem);
+            result->add_item(lineItem);
         }
 
         else if (const auto* plane = dynamic_cast<const InfinitePlane*>(shape)) {
             Q_UNUSED(plane);
             auto* planeItem = new FullframeItem();
             planeItem->setMaskValue(mask_value);
-            result->push_back(planeItem);
+            result->add_item(planeItem);
         }
 
         else
@@ -129,7 +129,7 @@ MasksSet* getMasksSet(const IDetector& detector)
         roiItem->setYLow(yBounds.first);
         roiItem->setXUp(xBounds.second);
         roiItem->setYUp(yBounds.second);
-        result->push_back(roiItem);
+        result->add_item(roiItem);
     }
 
     return result;
diff --git a/GUI/Model/Mask/MasksQModel.cpp b/GUI/Model/Mask/MasksQModel.cpp
index 938c37d94050f6e6587fe563848f326aea6744c4..0d5f1fadedefb322863d67ad28e2948c713099ae 100644
--- a/GUI/Model/Mask/MasksQModel.cpp
+++ b/GUI/Model/Mask/MasksQModel.cpp
@@ -77,45 +77,10 @@ QModelIndex MasksQModel::pushItem(MaskItem* t)
         return {};
     const size_t row = set()->size();
     beginInsertRows({}, row, row);
-    set()->push_back(t);
+    set()->add_item(t);
     endInsertRows();
 
     emit set()->setChanged();
 
     return createIndex(row, 0);
 }
-
-//! Move mask to a given row
-void MasksQModel::moveMask(int from_row, int to_row)
-{
-    emit QAbstractListModel::beginMoveRows(m_masks->rootIndex, from_row, from_row,
-                                           m_masks->rootIndex, to_row);
-    m_masks->swap(from_row, to_row);
-    emit QAbstractListModel::endMoveRows();
-}
-
-void MasksQModel::moveUp()
-{
-    /*
-    for (const QModelIndex& itemIndex : m_selection_model->selectedIndexes()) {
-        int row = itemIndex.row();
-        int new_row = row - 1;
-        if (new_row >= 0 && new_row < rowCount({}))
-            moveMask(row, new_row);
-    }
-    */
-}
-
-void MasksQModel::moveDown()
-{
-    /*
-    for (const QModelIndex& itemIndex : m_selection_model->selectedIndexes()) {
-        int row = itemIndex.row();
-        int new_row = row + 1;
-        if (new_row >= 0 && new_row < rowCount({}))
-            // Here we lower element from 'new_row' instead of rising element from 'row'
-            // The result should be the same, but rising doesn't work for an unknown reason
-            moveMask(new_row, row);
-    }
-    */
-}
diff --git a/GUI/Model/Mask/MasksQModel.h b/GUI/Model/Mask/MasksQModel.h
index eb930d86d9abe53e21b6f30095931c95e9cc5be1..9b46e63c4ed2190388ef93731ead67cf9881fe3a 100644
--- a/GUI/Model/Mask/MasksQModel.h
+++ b/GUI/Model/Mask/MasksQModel.h
@@ -38,10 +38,6 @@ public:
     void deleteItem();
     QModelIndex pushItem(MaskItem*);
 
-    void moveMask(int from_row, int to_row);
-    void moveUp();
-    void moveDown();
-
     MasksSet* set() { return m_masks; }
     const MasksSet* set() const { return m_masks; }
 
diff --git a/GUI/Model/Mask/MasksSet.h b/GUI/Model/Mask/MasksSet.h
index 5455df59a8479c374b5ef4fe2e14147ddadd3732..1481b7c4d5835dcf5e01edafac038028cfeb87a6 100644
--- a/GUI/Model/Mask/MasksSet.h
+++ b/GUI/Model/Mask/MasksSet.h
@@ -15,16 +15,16 @@
 #ifndef BORNAGAIN_GUI_MODEL_MASK_MASKSSET_H
 #define BORNAGAIN_GUI_MODEL_MASK_MASKSSET_H
 
-#include "Base/Types/VectorWC.h"
 #include "GUI/Model/Mask/MaskItems.h"
-#include <QModelIndex>
+#include "GUI/Model/Type/SetWithModel.h"
 #include <QXmlStreamReader>
 
+class MaskItem;
 class RegionOfInterestItem;
 
 //! Container holding various masks as children
 
-class MasksSet : public QObject, public VectorWC<MaskItem> {
+class MasksSet : public SetWithModel<MaskItem> {
     Q_OBJECT
 public:
     MasksSet();
@@ -35,14 +35,6 @@ public:
 
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
-
-    const QModelIndex rootIndex;
-
-    void add_item(MaskItem* t) { push_back(t); }
-
-signals:
-    void setChanged() const;
-    void currentModified() const;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_MASK_MASKSSET_H
diff --git a/GUI/Model/Mask/OverlayItem.h b/GUI/Model/Mask/OverlayItem.h
index 086f78f28f2cbc74a19f35c84178bb9f2f2dddc3..2096d95cfd92ab91e0abfc4622f90e1d69cca2f6 100644
--- a/GUI/Model/Mask/OverlayItem.h
+++ b/GUI/Model/Mask/OverlayItem.h
@@ -15,11 +15,12 @@
 #ifndef BORNAGAIN_GUI_MODEL_MASK_OVERLAYITEM_H
 #define BORNAGAIN_GUI_MODEL_MASK_OVERLAYITEM_H
 
+#include "GUI/Model/Type/NamedItem.h"
 #include <QObject>
 
 //! Something to be shown as overlay in a graphics scene. Base class for point and mask items.
 
-class OverlayItem : public QObject {
+class OverlayItem : public QObject, public NamedItem {
     Q_OBJECT
 public:
     explicit OverlayItem();
diff --git a/GUI/View/Scene/MaskGraphicsScene.cpp b/GUI/View/Scene/MaskGraphicsScene.cpp
index 34d23b71d5e19b6efe2d7472944e363555d79f53..c8487bba403e2f4eab5a3e0a82140801e2669ad1 100644
--- a/GUI/View/Scene/MaskGraphicsScene.cpp
+++ b/GUI/View/Scene/MaskGraphicsScene.cpp
@@ -59,6 +59,7 @@ void MaskGraphicsScene::associateItems(Data2DItem* data_item, MasksQModel* masks
     m_data_item = data_item;
 
     ASSERT(masks_qmodel);
+    m_masks = masks_qmodel->set();
 
     if (masks_qmodel == m_masks_qmodel)
         return;
@@ -118,7 +119,7 @@ void MaskGraphicsScene::cancelCurrentDrawing()
 {
     if (m_drawing_in_progress) {
         ASSERT(m_active_mask);
-        m_masks_qmodel->deleteItem();
+        m_masks->delete_current();
         setDrawingInProgress(false);
     }
 }
@@ -259,15 +260,15 @@ void MaskGraphicsScene::resetScene()
 
 void MaskGraphicsScene::updateScene()
 {
-    if (!m_masks_qmodel)
+    if (!m_masks)
         return;
 
     updateProxyWidget();
     updateOverlays();
 
     // update Z-values of all IMaskView to reflect stacking order
-    int z = m_masks_qmodel->set()->size();
-    for (const MaskItem* maskItem : *m_masks_qmodel->set()) {
+    int z = m_masks->size();
+    for (const MaskItem* maskItem : *m_masks) {
         if (IOverlay* overlay = m_mask2overlay[maskItem])
             overlay->setZValue(z);
         --z;
@@ -294,10 +295,8 @@ void MaskGraphicsScene::updateProxyWidget()
 
 void MaskGraphicsScene::updateOverlays()
 {
-    ASSERT(m_masks_qmodel);
-    MasksSet* holder_item = m_masks_qmodel->set();
-    ASSERT(holder_item);
-    for (MaskItem* mask_item : *holder_item) {
+    ASSERT(m_masks);
+    for (MaskItem* mask_item : *m_masks) {
         IOverlay* item_overlay = registerOverlay(mask_item);
         ASSERT(item_overlay);
 
@@ -403,7 +402,7 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent*
         else
             ASSERT_NEVER;
 
-        m_masks_qmodel->pushItem(m_active_mask);
+        m_masks->add_item(m_active_mask);
 
         if (m_mode != Canvas2DMode::ROI)
             m_active_mask->setMaskValue(m_mask_value);
@@ -441,7 +440,7 @@ void MaskGraphicsScene::processPolygonItem(QGraphicsSceneMouseEvent* event)
     if (!m_active_mask) {
         setDrawingInProgress(true);
         auto* new_poly = new PolygonItem;
-        m_masks_qmodel->pushItem(new_poly);
+        m_masks->add_item(new_poly);
         new_poly->setMaskValue(m_mask_value);
         m_active_mask = new_poly;
     }
@@ -484,7 +483,7 @@ void MaskGraphicsScene::processLineItem(QGraphicsSceneMouseEvent* event)
 void MaskGraphicsScene::processVerticalLineItem(const QPointF& pos)
 {
     auto* item = new VerticalLineItem;
-    m_masks_qmodel->pushItem(item);
+    m_masks->add_item(item);
     m_active_mask = item;
     item->setPos(m_plot->fromSceneX(pos.x()));
 }
@@ -492,7 +491,7 @@ void MaskGraphicsScene::processVerticalLineItem(const QPointF& pos)
 void MaskGraphicsScene::processHorizontalLineItem(const QPointF& pos)
 {
     auto* item = new HorizontalLineItem;
-    m_masks_qmodel->pushItem(item);
+    m_masks->add_item(item);
     m_active_mask = item;
     item->setPos(m_plot->fromSceneY(pos.y()));
 }
@@ -503,7 +502,7 @@ void MaskGraphicsScene::processFullframeItem(QGraphicsSceneMouseEvent* event)
     Q_UNUSED(event);
     setDrawingInProgress(true);
     auto* item = new FullframeItem;
-    m_masks_qmodel->pushItem(item);
+    m_masks->add_item(item);
     m_active_mask = item;
     setDrawingInProgress(false);
 }
diff --git a/GUI/View/Scene/MaskGraphicsScene.h b/GUI/View/Scene/MaskGraphicsScene.h
index 87914e86c6d2d0822c36e812169d2873fb72d720..10c5ad3f0ee2ab2fc438edce73fcd339ca4c2644 100644
--- a/GUI/View/Scene/MaskGraphicsScene.h
+++ b/GUI/View/Scene/MaskGraphicsScene.h
@@ -28,6 +28,7 @@ class MaskEditorAction;
 class MaskGraphicsProxy;
 class MaskItem;
 class MasksQModel;
+class MasksSet;
 class OverlayItem;
 class PolygonOverlay;
 
@@ -90,6 +91,7 @@ private:
     std::unique_ptr<ColorMap> m_plot;
     std::unique_ptr<MaskGraphicsProxy> m_proxy;
     MasksQModel* m_masks_qmodel = nullptr;
+    MasksSet* m_masks = nullptr;
     QMap<const OverlayItem*, IOverlay*> m_mask2overlay;
     bool m_block_selection = false;
     bool m_mouse_is_pressed = false;
diff --git a/GUI/View/Setup/MasksPanel.cpp b/GUI/View/Setup/MasksPanel.cpp
index 8beabdf2b4384e57ea75c27e714268eec229ad6a..f4fa36c070d47de1635fcb11a9586afe158994b0 100644
--- a/GUI/View/Setup/MasksPanel.cpp
+++ b/GUI/View/Setup/MasksPanel.cpp
@@ -87,7 +87,6 @@ void MasksPanel::updateMasksPanel(MasksQModel* masks_qmodel)
 
     m_qlistview->setModel(m_qlistmodel);
     m_qlistview->setSelectionMode(QAbstractItemView::ExtendedSelection);
-    m_qlistview->setRootIndex(m_qlistmodel->set()->rootIndex);
 }
 
 //! Private function, called by different functions.
diff --git a/GUI/View/Setup/MasksPanel.h b/GUI/View/Setup/MasksPanel.h
index 6fc9afc370a25650169ef98c1e761a020e2cc431..7640df9fc85231b4d243c596577ac24c1d3244aa 100644
--- a/GUI/View/Setup/MasksPanel.h
+++ b/GUI/View/Setup/MasksPanel.h
@@ -16,10 +16,7 @@
 #define BORNAGAIN_GUI_VIEW_SETUP_MASKSPANEL_H
 
 #include <QFormLayout>
-#include <QItemSelection>
-#include <QItemSelectionModel>
 #include <QListView>
-#include <QModelIndex>
 #include <QWidget>
 #include <functional>