diff --git a/GUI/Model/Data/IntensityDataItem.cpp b/GUI/Model/Data/IntensityDataItem.cpp
index 45863620d8222a9b91c2b9edeaefba1fe0b61995..cb8b01926c6c8347ad750571bb73525cc5c9c5dd 100644
--- a/GUI/Model/Data/IntensityDataItem.cpp
+++ b/GUI/Model/Data/IntensityDataItem.cpp
@@ -30,6 +30,8 @@ const QString BaseData("BaseData");
 const QString ZAxis("ZAxis");
 const QString Interpolation("Interpolation");
 const QString Gradient("Gradient");
+const QString MaskContainer("MaskContainer");
+const QString ProjectionContainer("ProjectionContainer");
 
 } // namespace Tag
 
@@ -335,6 +337,20 @@ void IntensityDataItem::writeTo(QXmlStreamWriter* w, const QString& projectDir)
     w->writeStartElement(Tag::ZAxis);
     m_zAxis->writeTo(w);
     w->writeEndElement();
+
+    // masks
+    if (m_maskContainerItem) {
+        w->writeStartElement(Tag::MaskContainer);
+        m_maskContainerItem->writeTo(w);
+        w->writeEndElement();
+    }
+
+    // projections
+    if (m_projectionContainerItem) {
+        w->writeStartElement(Tag::ProjectionContainer);
+        m_projectionContainerItem->writeTo(w);
+        w->writeEndElement();
+    }
 }
 
 void IntensityDataItem::readFrom(QXmlStreamReader* r)
@@ -365,6 +381,16 @@ void IntensityDataItem::readFrom(QXmlStreamReader* r)
             m_zAxis->readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // masks
+        } else if (tag == Tag::MaskContainer) {
+            getOrCreateMaskContainerItem()->readFrom(r);
+            XML::gotoEndElementOfTag(r, tag);
+
+            // projections
+        } else if (tag == Tag::ProjectionContainer) {
+            getOrCreateProjectionContainerItem()->readFrom(r);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Data/IntensityDataItem.h b/GUI/Model/Data/IntensityDataItem.h
index 9e4e6c1763a326e2f63abc79bac17bbe608013b9..49c4a3e07dbf00b847003fa9e06c39c764f19b6b 100644
--- a/GUI/Model/Data/IntensityDataItem.h
+++ b/GUI/Model/Data/IntensityDataItem.h
@@ -19,6 +19,7 @@
 
 class AmplitudeAxisItem;
 class MaskContainerItem;
+class MaskItemObject;
 class ProjectionContainerItem;
 class QCPColorGradient;
 
@@ -115,8 +116,8 @@ signals:
     void gradientChanged();
     void interpolationChanged(bool isInterpol);
     void projectionCreated();
-    void projectionPositionChanged(SessionItem* projection);
-    void projectionGone(SessionItem* projection);
+    void projectionPositionChanged(MaskItemObject* projection);
+    void projectionGone(MaskItemObject* projection);
     void alignRanges();
 
 private:
diff --git a/GUI/Model/Data/ProjectionItems.cpp b/GUI/Model/Data/ProjectionItems.cpp
index c0200d34ff42bf448e4b46ba2a3ab72b61bdb2d3..05e5d325dd19d9b18260e6777ad8e3f68b561dc4 100644
--- a/GUI/Model/Data/ProjectionItems.cpp
+++ b/GUI/Model/Data/ProjectionItems.cpp
@@ -16,14 +16,10 @@
 #include <stdexcept>
 
 ProjectionContainerItem::ProjectionContainerItem()
-    : MaskContainerItem(M_TYPE)
+    : MaskContainerItem()
 {
-    // const QString T_CHILDREN = "children tag";
-    // registerTag(T_CHILDREN, 0, -1, {HorizontalLineItem::M_TYPE, VerticalLineItem::M_TYPE});
-    // setDefaultTag(T_CHILDREN);
 }
 
-
 void ProjectionContainerItem::insertMask(int row, MaskItem* maskItem)
 {
     verifyMask(maskItem);
@@ -40,17 +36,17 @@ void ProjectionContainerItem::verifyMask(MaskItem* maskItem) const
 {
     ASSERT(maskItem);
 
-    ASSERT(maskItem->modelType() == HorizontalLineItem::M_TYPE
-           || maskItem->modelType() == VerticalLineItem::M_TYPE);
+    ASSERT(dynamic_cast<HorizontalLineItem*>(maskItem)
+           || dynamic_cast<VerticalLineItem*>(maskItem));
 }
 
-QVector<SessionItem*> ProjectionContainerItem::projectionsOfType(const QString& projectionType)
+QVector<MaskItem*> ProjectionContainerItem::projectionsOfType(ProjectionType projectionType)
 {
-    QVector<SessionItem*> projections;
-    for (MaskItem* projection : m_maskItems) {
-        if (projection->modelType() == projectionType)
-            projections.push_back(projection);
-    }
-
-    return projections;
+    if (projectionType == ProjectionType::Horizontal)
+        return projections<HorizontalLineItem>();
+    else if (projectionType == ProjectionType::Vertical)
+        return projections<VerticalLineItem>();
+    else
+        ASSERT(false);
+    return {};
 }
diff --git a/GUI/Model/Data/ProjectionItems.h b/GUI/Model/Data/ProjectionItems.h
index 9ade761a8d23a4960e1202920fa108620a12e274..fc023750a49ba5e2c177c1230fe717efe7c8608d 100644
--- a/GUI/Model/Data/ProjectionItems.h
+++ b/GUI/Model/Data/ProjectionItems.h
@@ -16,20 +16,32 @@
 #define BORNAGAIN_GUI_MODEL_DATA_PROJECTIONITEMS_H
 
 #include "GUI/Model/Device/MaskItems.h"
+#include "GUI/Support/Data/ProjectionType.h"
 
 //! A container to hold ProjectionItems, intended to store projections of color map on X, Y axes.
 
 class ProjectionContainerItem : public MaskContainerItem {
 public:
-    static constexpr auto M_TYPE{"ProjectionContainer"};
-
     ProjectionContainerItem();
     //! Verify the type of the given MaskItem (throws excepctions)
     void verifyMask(MaskItem* maskItem) const;
 
     void insertMask(int row, MaskItem* maskItem) override;
     void addMask(MaskItem* maskItem) override;
-    QVector<SessionItem*> projectionsOfType(const QString& projectionType);
+
+    QVector<MaskItem*> projectionsOfType(ProjectionType projectionType);
+
+private:
+    template <typename LineType>
+    QVector<MaskItem*> projections()
+    {
+        QVector<MaskItem*> result;
+        for (const auto& proj : m_maskItems)
+            if (dynamic_cast<LineType*>(proj.currentItem()))
+                result.push_back(proj.currentItem());
+        return result;
+    }
 };
 
+
 #endif // BORNAGAIN_GUI_MODEL_DATA_PROJECTIONITEMS_H
diff --git a/GUI/Model/Device/MaskItems.cpp b/GUI/Model/Device/MaskItems.cpp
index 6dc79bad250c115ea519e08eed7bcf1d642f53ee..423c4a41059e9ba278e3c4e9bd8e91d573611d6c 100644
--- a/GUI/Model/Device/MaskItems.cpp
+++ b/GUI/Model/Device/MaskItems.cpp
@@ -18,8 +18,8 @@
 #include "Device/Mask/Line.h"
 #include "Device/Mask/Polygon.h"
 #include "Device/Mask/Rectangle.h"
-#include "GUI/Model/Model/SessionModel.h"
 #include "GUI/Support/XML/UtilXML.h"
+#include <QRegularExpression>
 
 namespace {
 namespace Tag {
@@ -47,41 +47,25 @@ const QString Mask("Mask");
 } // namespace
 
 MaskContainerItem::MaskContainerItem()
-    : MaskItemObject(M_TYPE)
-{
-}
-
-MaskContainerItem::MaskContainerItem(const QString& modelType)
-    : MaskItemObject(modelType)
+    : MaskItemObject()
 {
 }
 
 QVector<MaskItem*> MaskContainerItem::maskItems() const
 {
-    return m_maskItems;
-}
-
-std::vector<SelectionProperty<MaskItemCatalog>> MaskContainerItem::maskItemSelections() const
-{
-    std::vector<SelectionProperty<MaskItemCatalog>> maskSelections;
-    for (MaskItem* maskItem : m_maskItems) {
-        SelectionProperty<MaskItemCatalog> newMaskSelection;
-        newMaskSelection.setCurrentItem(maskItem);
-        maskSelections.push_back(std::move(newMaskSelection));
-    }
-    return maskSelections;
+    return m_maskItems.toQVector();
 }
 
 void MaskContainerItem::insertMask(int row, MaskItem* maskItem)
 {
-    maskItem->setParentAndModel(this, SessionItem::model());
-    m_maskItems.insert(row, maskItem);
+    // takes owning of maskItem!
+    m_maskItems.insert_at(row, maskItem);
 }
 
 void MaskContainerItem::addMask(MaskItem* maskItem)
 {
-    maskItem->setParentAndModel(this, SessionItem::model());
-    m_maskItems.push_back(maskItem); // TODO: check whether the order of masks matter
+    // takes owning of maskItem!
+    m_maskItems.push_back(maskItem);
 }
 
 void MaskContainerItem::moveMask(int from_row, int to_row)
@@ -91,19 +75,19 @@ void MaskContainerItem::moveMask(int from_row, int to_row)
 
 void MaskContainerItem::removeMaskAt(int row)
 {
-    m_maskItems.removeAt(row);
+    m_maskItems.delete_at(row);
 }
 
 void MaskContainerItem::removeMask(MaskItem* maskItem)
 {
-    m_maskItems.removeOne(maskItem);
+    m_maskItems.delete_element(maskItem);
 }
 
 RegionOfInterestItem* MaskContainerItem::regionOfInterestItem() const
 {
-    for (MaskItem* maskItem : m_maskItems)
-        if (maskItem->modelType() == RegionOfInterestItem::M_TYPE)
-            return dynamic_cast<RegionOfInterestItem*>(maskItem);
+    for (const auto& maskSel : m_maskItems)
+        if (auto* roi = dynamic_cast<RegionOfInterestItem*>(maskSel.currentItem()))
+            return roi;
 
     return nullptr;
 }
@@ -125,12 +109,12 @@ int MaskContainerItem::size() const
 
 MaskItem* MaskContainerItem::at(const int idx)
 {
-    return m_maskItems.at(idx);
+    return m_maskItems.at(idx).currentItem();
 }
 
 int MaskContainerItem::indexOfItem(MaskItem* maskItem) const
 {
-    return m_maskItems.indexOf(maskItem);
+    return m_maskItems.index_of(maskItem);
 }
 
 void MaskContainerItem::copy(const MaskContainerItem* maskContainer)
@@ -152,11 +136,33 @@ void MaskContainerItem::setModel(MaskContainerModel* model)
     model->maskContainer = this;
 }
 
+void MaskContainerItem::updateMaskNames()
+{
+    const auto reg = QRegularExpression("[0-9]");
+
+    QMap<QString, int> numMasksByType;
+    for (size_t i = 0; i < m_maskItems.size(); i++) {
+
+        QString name = m_maskItems[i].currentItem()->maskName();
+        name.remove(reg);
+
+        int numMasks = 1;
+        if (numMasksByType.contains(name)) {
+            numMasks = numMasksByType.value(name) + 1;
+            numMasksByType.remove(name);
+        }
+        numMasksByType.insert(name, numMasks);
+        name += QString::number(numMasks);
+
+        m_maskItems[i].currentItem()->setMaskName(name);
+    }
+}
+
 void MaskContainerItem::writeTo(QXmlStreamWriter* w) const
 {
     XML::writeAttribute(w, XML::Attrib::version, uint(1));
 
-    for (const SelectionProperty<MaskItemCatalog>& sel : maskItemSelections()) {
+    for (const auto& sel : m_maskItems) {
         w->writeStartElement(Tag::Mask);
         sel.writeTo(w);
         w->writeEndElement();
@@ -174,9 +180,8 @@ void MaskContainerItem::readFrom(QXmlStreamReader* r, MessageService*)
         QString tag = r->name().toString();
 
         if (tag == Tag::Mask) {
-            SelectionProperty<MaskItemCatalog> sel;
-            sel.readFrom(r);
-            addMask(sel.currentItem());
+            addMask(nullptr);
+            m_maskItems.back().readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
         } else
@@ -188,12 +193,12 @@ void MaskContainerItem::readFrom(QXmlStreamReader* r, MessageService*)
 
 QString MaskItem::maskName() const
 {
-    return itemName();
+    return m_maskName;
 }
 
 void MaskItem::setMaskName(const QString& name)
 {
-    setItemName(name);
+    m_maskName = name;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -226,17 +231,17 @@ void MaskItem::writeTo(QXmlStreamWriter* w) const
 
     // name
     w->writeStartElement(Tag::Name);
-    XML::writeAttribute(w, XML::Attrib::value, maskName());
+    XML::writeAttribute(w, XML::Attrib::value, m_maskName);
     w->writeEndElement();
 
     // mask value
     w->writeStartElement(Tag::MaskValue);
-    XML::writeAttribute(w, XML::Attrib::value, maskValue());
+    XML::writeAttribute(w, XML::Attrib::value, m_maskValue);
     w->writeEndElement();
 
     // is visible?
     w->writeStartElement(Tag::IsVisible);
-    XML::writeAttribute(w, XML::Attrib::value, isVisibleValue());
+    XML::writeAttribute(w, XML::Attrib::value, m_isVisible);
     w->writeEndElement();
 }
 
@@ -250,23 +255,17 @@ void MaskItem::readFrom(QXmlStreamReader* r)
 
         // name
         if (tag == Tag::Name) {
-            QString name;
-            XML::readAttribute(r, XML::Attrib::value, &name);
-            setMaskName(name);
+            XML::readAttribute(r, XML::Attrib::value, &m_maskName);
             XML::gotoEndElementOfTag(r, tag);
 
             // mask value
         } else if (tag == Tag::MaskValue) {
-            bool maskValue = true;
-            XML::readAttribute(r, XML::Attrib::value, &maskValue);
-            setMaskValue(maskValue);
+            XML::readAttribute(r, XML::Attrib::value, &m_maskValue);
             XML::gotoEndElementOfTag(r, tag);
 
             // is visible?
         } else if (tag == Tag::IsVisible) {
-            bool isVisible = true;
-            XML::readAttribute(r, XML::Attrib::value, &isVisible);
-            setIsVisibleValue(isVisible);
+            XML::readAttribute(r, XML::Attrib::value, &m_isVisible);
             XML::gotoEndElementOfTag(r, tag);
 
         } else
@@ -274,22 +273,17 @@ void MaskItem::readFrom(QXmlStreamReader* r)
     }
 }
 
-MaskItem::MaskItem(const QString& name)
-    : MaskItemObject(name)
+MaskItem::MaskItem()
+    : MaskItemObject()
 {
 }
 
 /* ------------------------------------------------------------------------- */
 
 RectangleItem::RectangleItem()
-    : RectangleItem(M_TYPE)
+    : MaskItem()
 {
-}
-
-RectangleItem::RectangleItem(const QString& modelType)
-    : MaskItem(modelType)
-{
-    setItemName(modelType);
+    setMaskName("RectangleMask");
 }
 
 std::unique_ptr<IShape2D> RectangleItem::createShape(double scale) const
@@ -424,8 +418,9 @@ void RectangleItem::readFrom(QXmlStreamReader* r)
 /* ------------------------------------------------------------------------- */
 
 RegionOfInterestItem::RegionOfInterestItem()
-    : RectangleItem(M_TYPE)
+    : RectangleItem()
 {
+    setMaskName("RegionOfInterest");
     setMaskValue(false);
 }
 
@@ -439,9 +434,8 @@ std::unique_ptr<IShape2D> RegionOfInterestItem::createShape(double scale) const
 /* ------------------------------------------------------------------------- */
 
 PolygonPointItem::PolygonPointItem()
-    : MaskItemObject(M_TYPE)
+    : MaskItemObject()
 {
-    setItemName(M_TYPE);
 }
 
 double PolygonPointItem::posX() const
@@ -490,9 +484,9 @@ void PolygonPointItem::readFrom(QXmlStreamReader* r)
 /* ------------------------------------------------------------------------- */
 
 PolygonItem::PolygonItem()
-    : MaskItem(M_TYPE)
+    : MaskItem()
 {
-    setItemName(M_TYPE);
+    setMaskName("PolygonMask");
 }
 
 std::unique_ptr<IShape2D> PolygonItem::createShape(double scale) const
@@ -525,9 +519,7 @@ void PolygonItem::addPoint(double x, double y)
     auto* pointItem = new PolygonPointItem;
     pointItem->setPosX(x);
     pointItem->setPosY(y);
-    pointItem->setParentAndModel(this, model());
     m_points.push_back(pointItem); // TODO: check whether the order of points matter
-    // insertChild(-1, new PolygonPointItem);
 }
 
 void PolygonItem::writeTo(QXmlStreamWriter* w) const
@@ -595,9 +587,9 @@ PolygonItem::~PolygonItem()
 /* ------------------------------------------------------------------------- */
 
 VerticalLineItem::VerticalLineItem()
-    : MaskItem(M_TYPE)
+    : MaskItem()
 {
-    setItemName(M_TYPE);
+    setMaskName("VerticalLineMask");
 }
 
 std::unique_ptr<IShape2D> VerticalLineItem::createShape(double scale) const
@@ -659,9 +651,9 @@ void VerticalLineItem::readFrom(QXmlStreamReader* r)
 /* ------------------------------------------------------------------------- */
 
 HorizontalLineItem::HorizontalLineItem()
-    : MaskItem(M_TYPE)
+    : MaskItem()
 {
-    setItemName(M_TYPE);
+    setMaskName("HorizontalLineMask");
 }
 
 std::unique_ptr<IShape2D> HorizontalLineItem::createShape(double scale) const
@@ -723,9 +715,9 @@ void HorizontalLineItem::readFrom(QXmlStreamReader* r)
 /* ------------------------------------------------------------------------- */
 
 EllipseItem::EllipseItem()
-    : MaskItem(M_TYPE)
+    : MaskItem()
 {
-    setItemName(M_TYPE);
+    setMaskName("EllipseMask");
 }
 
 std::unique_ptr<IShape2D> EllipseItem::createShape(double scale) const
@@ -885,10 +877,9 @@ void EllipseItem::readFrom(QXmlStreamReader* r)
 /* ------------------------------------------------------------------------- */
 
 MaskAllItem::MaskAllItem()
-    : MaskItem(M_TYPE)
+    : MaskItem()
 {
-    setItemName(M_TYPE);
-    // maskValueItem()->setEnabled(false);  // TODO: Is this needed?
+    setMaskName("MaskAllMask");
 }
 
 std::unique_ptr<IShape2D> MaskAllItem::createShape(double) const
@@ -898,8 +889,8 @@ std::unique_ptr<IShape2D> MaskAllItem::createShape(double) const
 
 /* ------------------------------------------------------------------------- */
 
-MaskItemObject::MaskItemObject(const QString& modelType)
-    : SessionItem(modelType)
+MaskItemObject::MaskItemObject()
+    : QObject()
 {
 }
 
@@ -910,7 +901,6 @@ MaskItemObject::~MaskItemObject()
 /* ------------------------------------------------------------------------- */
 
 // Implementation of MaskContainerModel is based on the Qt source code for QStringListModel
-// NOTE: Dependence on SessionModel will be removed at the latest step of refactoring.
 
 MaskContainerModel::MaskContainerModel() {}
 
@@ -950,7 +940,6 @@ void MaskContainerModel::insertMask(int row, MaskItem* maskItem)
 {
     QAbstractListModel::beginInsertRows(maskContainer->rootIndex, row, row);
     maskContainer->insertMask(row, maskItem);
-    // QModelIndex idx = index(row, 0, {});
     QAbstractListModel::endInsertRows();
 }
 
@@ -958,7 +947,7 @@ void MaskContainerModel::addMask(MaskItem* maskItem)
 {
     qsizetype row = maskContainer->size() - 1;
     QAbstractListModel::beginInsertRows(maskContainer->rootIndex, row, row);
-    maskContainer->addMask(maskItem); // TODO: check whether the order of masks matter
+    maskContainer->addMask(maskItem);
     QAbstractListModel::endInsertRows();
 }
 
@@ -966,7 +955,6 @@ void MaskContainerModel::addMask(MaskItem* maskItem)
 //! Move mask to a given row
 void MaskContainerModel::moveMask(int from_row, int to_row)
 {
-
     emit QAbstractListModel::beginMoveRows(maskContainer->rootIndex, from_row, from_row,
                                            maskContainer->rootIndex, to_row);
     maskContainer->moveMask(from_row, to_row);
@@ -980,7 +968,6 @@ void MaskContainerModel::removeMaskAt(int row)
     QAbstractListModel::endRemoveRows();
 }
 
-
 void MaskContainerModel::removeMask(MaskItem* maskItem)
 {
     const int row = maskContainer->indexOfItem(maskItem);
@@ -990,13 +977,13 @@ void MaskContainerModel::removeMask(MaskItem* maskItem)
 RegionOfInterestItem* MaskContainerModel::regionOfInterestItem() const
 {
     for (MaskItem* maskItem : maskContainer->maskItems())
-        if (maskItem->modelType() == RegionOfInterestItem::M_TYPE)
-            return dynamic_cast<RegionOfInterestItem*>(maskItem);
+        if (auto* reg = dynamic_cast<RegionOfInterestItem*>(maskItem))
+            return reg;
 
     return nullptr;
 }
 
-QModelIndex MaskContainerModel::indexOfItem(SessionItem* item) const
+QModelIndex MaskContainerModel::indexOfItem(MaskItemObject* item) const
 {
     const int row = maskContainer->indexOfItem(dynamic_cast<MaskItem*>(item));
     return QAbstractListModel::index(row, 0, {});
diff --git a/GUI/Model/Device/MaskItems.h b/GUI/Model/Device/MaskItems.h
index 5c6811ced876c1fbab42aa14a90683d9e85d08f4..993361a7ed21c48e939af6a25ea96bef23498a35 100644
--- a/GUI/Model/Device/MaskItems.h
+++ b/GUI/Model/Device/MaskItems.h
@@ -15,19 +15,21 @@
 #ifndef BORNAGAIN_GUI_MODEL_DEVICE_MASKITEMS_H
 #define BORNAGAIN_GUI_MODEL_DEVICE_MASKITEMS_H
 
-#include "GUI/Model/BaseItem/SessionItem.h"
+#include "Base/Types/OwningVector.h"
+#include "Base/Util/Assert.h"
 #include "GUI/Model/CatDevice/MaskItemCatalog.h"
 #include "GUI/Model/Descriptor/SelectionProperty.h"
-#include "GUI/Model/Model/SessionModel.h"
+#include <QAbstractListModel>
 
 class IShape2D;
+class MessageService;
 
-//! SessionItem with signals used in masks
+//! QObject with signals used in masks
 
-class MaskItemObject : public QObject, public SessionItem {
+class MaskItemObject : public QObject {
     Q_OBJECT
 public:
-    explicit MaskItemObject(const QString& modelType);
+    explicit MaskItemObject();
     ~MaskItemObject();
 
 signals:
@@ -55,16 +57,14 @@ public:
     virtual void readFrom(QXmlStreamReader* r);
 
 protected:
-    explicit MaskItem(const QString& name);
+    explicit MaskItem();
+    QString m_maskName = "nameless by default";
     bool m_maskValue = true;
     bool m_isVisible = true;
 };
 
 class RectangleItem : public MaskItem {
-
 public:
-    static constexpr auto M_TYPE{"RectangleMask"};
-
     explicit RectangleItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 
@@ -92,15 +92,11 @@ private:
 
 class RegionOfInterestItem : public RectangleItem {
 public:
-    static constexpr auto M_TYPE{"RegionOfInterest"};
-
     RegionOfInterestItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 };
 
 class PolygonPointItem : public MaskItemObject {
-    Q_OBJECT
-
 public:
     static constexpr auto M_TYPE{"PolygonPoint"};
 
@@ -121,8 +117,6 @@ private:
 
 class PolygonItem : public MaskItem {
 public:
-    static constexpr auto M_TYPE{"PolygonMask"};
-
     PolygonItem();
     ~PolygonItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
@@ -143,8 +137,6 @@ private:
 
 class VerticalLineItem : public MaskItem {
 public:
-    static constexpr auto M_TYPE{"VerticalLineMask"};
-
     VerticalLineItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 
@@ -160,8 +152,6 @@ private:
 
 class HorizontalLineItem : public MaskItem {
 public:
-    static constexpr auto M_TYPE{"HorizontalLineMask"};
-
     HorizontalLineItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 
@@ -177,8 +167,6 @@ private:
 
 class EllipseItem : public MaskItem {
 public:
-    static constexpr auto M_TYPE{"EllipseMask"};
-
     EllipseItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 
@@ -210,8 +198,6 @@ private:
 
 class MaskAllItem : public MaskItem {
 public:
-    static constexpr auto M_TYPE{"MaskAllMask"};
-
     MaskAllItem();
     std::unique_ptr<IShape2D> createShape(double scale) const override;
 };
@@ -222,15 +208,10 @@ class MaskContainerModel;
 //! Container holding various masks as children
 
 class MaskContainerItem : public MaskItemObject {
-    Q_OBJECT
 public:
-    static constexpr auto M_TYPE{"MaskContainer"};
-
     MaskContainerItem();
-    MaskContainerItem(const QString& modelType);
 
     QVector<MaskItem*> maskItems() const;
-    std::vector<SelectionProperty<MaskItemCatalog>> maskItemSelections() const;
 
     //! Insert mask at given row.
     virtual void insertMask(int row, MaskItem* maskItem);
@@ -254,13 +235,13 @@ public:
     //! Return true if the container has no MaskItems
     bool isEmpty() const;
 
-    //! Returns the number of MaskItems
+    //! Return the number of MaskItems
     int size() const;
 
-    //! Returns the MaskItem at a given index
+    //! Return the MaskItem at a given index
     int indexOfItem(MaskItem* maskItem) const;
 
-    //! Returns the index corresponding to a given MaskItem
+    //! Return the index corresponding to a given MaskItem
     MaskItem* at(const int idx);
 
     //! Copy masks from another MaskContainerItem
@@ -270,17 +251,20 @@ public:
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r, MessageService* messageService = nullptr);
 
-    //! Returns the corresponding MaskContainerModel
+    //! Return the corresponding MaskContainerModel
     MaskContainerModel* model();
 
-    //! Sets the corresponding MaskContainerModel
+    //! Set the corresponding MaskContainerModel
     void setModel(MaskContainerModel* model);
 
+    //! Update numbers in mask names
+    void updateMaskNames();
+
 public:
     const QModelIndex rootIndex;
 
 protected:
-    QVector<MaskItem*> m_maskItems;
+    SelectionVector<MaskItemCatalog> m_maskItems;
     MaskContainerModel* m_model = nullptr;
 };
 
@@ -318,9 +302,9 @@ public:
     void moveMask(int from_row, int to_row);
     void removeMaskAt(int row);
 
-    QModelIndex indexOfItem(SessionItem* item) const; // TODO: change this to MaskItem*
+    QModelIndex indexOfItem(MaskItemObject* item) const; // TODO: change this to MaskItem*
     MaskItem* itemForIndex(const QModelIndex& index) const;
-    // QString modelType() const;
+
     RegionOfInterestItem* regionOfInterestItem() const;
 
     void setParent(QObject* parent);
diff --git a/GUI/Model/Device/MaskUnitsConverter.cpp b/GUI/Model/Device/MaskUnitsConverter.cpp
index d5b2d6540190bff2c63ab0889c8322de612a3fbf..ce1b57363427c0be3e0e7055bb4a4b56cb84a2df 100644
--- a/GUI/Model/Device/MaskUnitsConverter.cpp
+++ b/GUI/Model/Device/MaskUnitsConverter.cpp
@@ -55,9 +55,8 @@ void MaskUnitsConverter::convertIntensityDataItem(IntensityDataItem* intensityDa
             convertMask(maskItem);
 
     if (intensityData->projectionContainerItem())
-        for (SessionItem* item : intensityData->projectionContainerItem()->maskItems())
-            if (auto* maskItem = dynamic_cast<MaskItem*>(item))
-                convertMask(maskItem);
+        for (auto* maskItem : intensityData->projectionContainerItem()->maskItems())
+            convertMask(maskItem);
 }
 
 //! Converts single mask from/to bin-fraction coordinates
diff --git a/GUI/Model/Device/MaskUnitsConverter.h b/GUI/Model/Device/MaskUnitsConverter.h
index 2879df43bb5f01e8c44fc855189fa18df3e90955..2f3a32406d7ab2e98e52043f4d4e49325bf0e4a5 100644
--- a/GUI/Model/Device/MaskUnitsConverter.h
+++ b/GUI/Model/Device/MaskUnitsConverter.h
@@ -16,10 +16,7 @@
 #define BORNAGAIN_GUI_MODEL_DEVICE_MASKUNITSCONVERTER_H
 
 class IntensityDataItem;
-class SessionItem;
-class IAxis;
 class Datafield;
-class QString;
 class MaskItem;
 
 //! The MaskUnitsConverter converts coordinates of all masks from one units to anoter.
diff --git a/GUI/Model/MakeItem/ItemCatalog.cpp b/GUI/Model/MakeItem/ItemCatalog.cpp
index 4cd328789c94804e11a4111fd96a978e3df19d76..f7d3fcc6581b997634a2a14a3a9091291e9f082d 100644
--- a/GUI/Model/MakeItem/ItemCatalog.cpp
+++ b/GUI/Model/MakeItem/ItemCatalog.cpp
@@ -37,20 +37,7 @@ ItemCatalog::ItemCatalog()
     addItem<IntensityDataItem>();
     addItem<SpecularDataItem>();
 
-    addItem<MaskContainerItem>();
-    addItem<RectangleItem>();
-    addItem<PolygonPointItem>();
-    addItem<PolygonItem>();
-    addItem<VerticalLineItem>();
-    addItem<HorizontalLineItem>();
-    addItem<EllipseItem>();
-    addItem<MaskAllItem>();
-
-    addItem<RegionOfInterestItem>();
-
     addItem<RealItem>();
-
-    addItem<ProjectionContainerItem>();
 }
 
 ItemCatalog& ItemCatalog::instance()
diff --git a/GUI/Support/Data/ProjectionType.h b/GUI/Support/Data/ProjectionType.h
new file mode 100644
index 0000000000000000000000000000000000000000..5bbb9e5284c424ec6e61bf24a758b543fc5961f0
--- /dev/null
+++ b/GUI/Support/Data/ProjectionType.h
@@ -0,0 +1,22 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      GUI/Support/Data/ProjectionType.h
+//! @brief     Defines enum ProjectionType
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2022
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#ifndef BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H
+#define BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H
+
+//! Lists the possible states of a projection type.
+
+enum ProjectionType { Horizontal, Vertical, Invalid };
+
+#endif // BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H
diff --git a/GUI/View/Import/RealDataMaskWidget.cpp b/GUI/View/Import/RealDataMaskWidget.cpp
index 68e1385e96f442512efa974b6dd8881519c396bf..552ac10e28f114bd19a2028a8d7aad7a54c4a95b 100644
--- a/GUI/View/Import/RealDataMaskWidget.cpp
+++ b/GUI/View/Import/RealDataMaskWidget.cpp
@@ -91,7 +91,7 @@ void RealDataMaskWidget::setContext()
 
     m_editorPropertyPanel->setMaskContext(containerModel);
 
-    ASSERT(containerItem->modelType() == MaskContainerItem::M_TYPE);
+    ASSERT(dynamic_cast<MaskContainerItem*>(containerItem));
     m_editorCanvas->setSelectionModel(m_editorPropertyPanel->selectionModel());
     m_editorCanvas->setMaskContext(currentIntensityDataItem());
 
diff --git a/GUI/View/Mask/EllipseView.cpp b/GUI/View/Mask/EllipseView.cpp
index 1111105ff21bcf6964f3b90075bfe0896979e83d..e45e4a83c8cd14d5d3a2e418cd9b4aa9f77663ed 100644
--- a/GUI/View/Mask/EllipseView.cpp
+++ b/GUI/View/Mask/EllipseView.cpp
@@ -95,7 +95,7 @@ QPainterPath EllipseView::shape() const
     return path;
 }
 
-SessionItem* EllipseView::parameterizedItem() const
+MaskItemObject* EllipseView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/EllipseView.h b/GUI/View/Mask/EllipseView.h
index 0a746df9786c3792e040732b0b642d602be70d37..14046db34137b58b14b8f6526bcb4cd3dbc1f8c4 100644
--- a/GUI/View/Mask/EllipseView.h
+++ b/GUI/View/Mask/EllipseView.h
@@ -30,7 +30,7 @@ public:
 
     explicit EllipseView(EllipseItem* item);
 
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void onChangedX() override;
diff --git a/GUI/View/Mask/IShape2DView.cpp b/GUI/View/Mask/IShape2DView.cpp
index 956c43403e53d14eef5991ec86e3c8367ac94b92..bc459e472ee0f5dc1fec93c92ac9b388715aa241 100644
--- a/GUI/View/Mask/IShape2DView.cpp
+++ b/GUI/View/Mask/IShape2DView.cpp
@@ -22,7 +22,7 @@
 
 namespace {
 
-bool itemMaskValue(const SessionItem* item)
+bool itemMaskValue(const MaskItemObject* item)
 {
     if (const auto* maskItem = dynamic_cast<const MaskItem*>(item))
         return maskItem->maskValue();
diff --git a/GUI/View/Mask/IShape2DView.h b/GUI/View/Mask/IShape2DView.h
index 33fbbaa930a524f1c67f5ddd4d91352bfb62a389..6d1c7a5498839f93d6e580c626d42eb1d2efd568 100644
--- a/GUI/View/Mask/IShape2DView.h
+++ b/GUI/View/Mask/IShape2DView.h
@@ -21,7 +21,6 @@
 
 class MaskItemObject;
 class ISceneAdaptor;
-class SessionItem;
 
 //! Main interface class for views representing MaskItems, Projections on graphics scene.
 
@@ -33,7 +32,7 @@ public:
 
     QRectF boundingRect() const override;
 
-    virtual SessionItem* parameterizedItem() const = 0;
+    virtual MaskItemObject* parameterizedItem() const = 0;
 
     void setSceneAdaptor(const ISceneAdaptor* adaptor);
 
diff --git a/GUI/View/Mask/LineViews.cpp b/GUI/View/Mask/LineViews.cpp
index 1d070ab3799aec3085fec73f18930b9f85b80b5e..787012d245533a72a77a21e1567307596cc69343 100644
--- a/GUI/View/Mask/LineViews.cpp
+++ b/GUI/View/Mask/LineViews.cpp
@@ -43,7 +43,7 @@ QPainterPath VerticalLineView::shape() const
     return p;
 }
 
-SessionItem* VerticalLineView::parameterizedItem() const
+MaskItemObject* VerticalLineView::parameterizedItem() const
 {
     return m_item;
 }
@@ -121,7 +121,7 @@ QPainterPath HorizontalLineView::shape() const
     return path;
 }
 
-SessionItem* HorizontalLineView::parameterizedItem() const
+MaskItemObject* HorizontalLineView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/LineViews.h b/GUI/View/Mask/LineViews.h
index 3060f16f181c6c10fe23076b88f7582b98511fc2..93ecb378362962db16e8f3785e5d0301f4398af9 100644
--- a/GUI/View/Mask/LineViews.h
+++ b/GUI/View/Mask/LineViews.h
@@ -31,7 +31,7 @@ public:
     explicit VerticalLineView(VerticalLineItem* item);
 
     QPainterPath shape() const override;
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void update_view() override;
@@ -58,7 +58,7 @@ public:
     explicit HorizontalLineView(HorizontalLineItem* item);
 
     QPainterPath shape() const override;
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void update_view() override;
diff --git a/GUI/View/Mask/MaskAllView.cpp b/GUI/View/Mask/MaskAllView.cpp
index 5b52c1a8e8af421f44ce58c4c55c7cacc5668b4b..dded5ae464f369ce5ebe5dbb8da50c6920337039 100644
--- a/GUI/View/Mask/MaskAllView.cpp
+++ b/GUI/View/Mask/MaskAllView.cpp
@@ -26,7 +26,7 @@ MaskAllView::MaskAllView(MaskAllItem* item)
     setFlag(QGraphicsItem::ItemIsSelectable);
 }
 
-SessionItem* MaskAllView::parameterizedItem() const
+MaskItemObject* MaskAllView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/MaskAllView.h b/GUI/View/Mask/MaskAllView.h
index 601e248724eee0f052f9ca43a5a8b342e4d7f9c7..445e7f5754741196f9f356339b32fa2abcec32fe 100644
--- a/GUI/View/Mask/MaskAllView.h
+++ b/GUI/View/Mask/MaskAllView.h
@@ -29,7 +29,7 @@ public:
 
     explicit MaskAllView(MaskAllItem* item);
 
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void update_view() override;
diff --git a/GUI/View/Mask/MaskContainerView.cpp b/GUI/View/Mask/MaskContainerView.cpp
index 3a907b1c6d61bf585b182be96fdc56037ed5b55a..e6184c0b231d7db07c12c4e5be07fb231b8e6494 100644
--- a/GUI/View/Mask/MaskContainerView.cpp
+++ b/GUI/View/Mask/MaskContainerView.cpp
@@ -35,7 +35,7 @@ MaskContainerView::MaskContainerView(ProjectionContainerItem* item)
     setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
 }
 
-SessionItem* MaskContainerView::parameterizedItem() const
+MaskItemObject* MaskContainerView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/MaskContainerView.h b/GUI/View/Mask/MaskContainerView.h
index 8c56282f115d8888d461e4fa3f7c90763beb47a6..86ae900bce1081eeb25c27e9a8f0516756cb3347 100644
--- a/GUI/View/Mask/MaskContainerView.h
+++ b/GUI/View/Mask/MaskContainerView.h
@@ -38,7 +38,7 @@ public:
     explicit MaskContainerView(MaskContainerItem* item);
     explicit MaskContainerView(ProjectionContainerItem* item);
 
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void update_view() override;
@@ -47,7 +47,7 @@ protected:
     void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override;
 
 private:
-    SessionItem* m_item;
+    MaskContainerItem* m_item;
 };
 
 #endif // BORNAGAIN_GUI_VIEW_MASK_MASKCONTAINERVIEW_H
diff --git a/GUI/View/Mask/MaskDrawingContext.cpp b/GUI/View/Mask/MaskDrawingContext.cpp
index 8c838d3337dc179afc5cbd59beb5334d7e7efd98..1f2b91b933004ecaf94a34a14d0cbb0316d357bc 100644
--- a/GUI/View/Mask/MaskDrawingContext.cpp
+++ b/GUI/View/Mask/MaskDrawingContext.cpp
@@ -118,19 +118,6 @@ bool MaskDrawingContext::isActivityRequiresDrawingCancel(
            && proposed_new_activity >= MaskEditorFlags::PAN_ZOOM_MODE;
 }
 
-//! Returns model type corresponding to current activity.
-
-QString MaskDrawingContext::activityToModelType() const
-{
-    if (isRectangleMode())
-        return RectangleItem::M_TYPE;
-    if (isEllipseMode())
-        return EllipseItem::M_TYPE;
-    if (isROIMode())
-        return RegionOfInterestItem::M_TYPE;
-    return "";
-}
-
 //! Returns model row corresponding to given activity. All shapes, except ROI, will be added
 //! on top of each other. ROI shape will be added at the bottom.
 
diff --git a/GUI/View/Mask/MaskDrawingContext.h b/GUI/View/Mask/MaskDrawingContext.h
index 00f1c5200c2fafdd4e1390f88d6e2ba35de1c22d..2d0e40a4b910237fd6420853ea024dc968677178 100644
--- a/GUI/View/Mask/MaskDrawingContext.h
+++ b/GUI/View/Mask/MaskDrawingContext.h
@@ -46,7 +46,6 @@ public:
 
     bool isActivityRequiresDrawingCancel(MaskEditorFlags::Activity proposed_new_activity) const;
 
-    QString activityToModelType() const;
     int activityToRow() const;
 
 private:
diff --git a/GUI/View/Mask/MaskGraphicsProxy.h b/GUI/View/Mask/MaskGraphicsProxy.h
index 183987342240cd7353d40fdd55e87fa1d66b7f13..46de4d36c4bb25f1813974e8ff2ba49bb6105d6f 100644
--- a/GUI/View/Mask/MaskGraphicsProxy.h
+++ b/GUI/View/Mask/MaskGraphicsProxy.h
@@ -18,7 +18,6 @@
 #include "GUI/View/Mask/MaskEditorHelper.h"
 #include <QGraphicsProxyWidget>
 
-class SessionItem;
 class ISceneAdaptor;
 class ColorMapSceneAdaptor;
 class ColorMap;
diff --git a/GUI/View/Mask/MaskGraphicsScene.cpp b/GUI/View/Mask/MaskGraphicsScene.cpp
index 24ec49e0e201a3d51efa523f61553cc5b3097579..17c908c189d9fce7d5b24467db24c7f4138ef37c 100644
--- a/GUI/View/Mask/MaskGraphicsScene.cpp
+++ b/GUI/View/Mask/MaskGraphicsScene.cpp
@@ -18,18 +18,12 @@
 #include "GUI/Model/Data/ProjectionItems.h"
 #include "GUI/Model/Device/MaskItems.h"
 #include "GUI/Model/MakeItem/ItemFactory.h"
-#include "GUI/Model/Model/SessionModel.h"
 #include "GUI/Util/Error.h"
 #include "GUI/View/Mask/ColorMapSceneAdaptor.h"
 #include "GUI/View/Mask/MaskGraphicsProxy.h"
 #include "GUI/View/Mask/MaskViewFactory.h"
 #include "GUI/View/Mask/PolygonView.h"
-#include <QGraphicsItem>
-#include <QGraphicsSceneMoveEvent>
-#include <QItemSelection>
-#include <QLineF>
-#include <QPainter>
-
+#include <QGraphicsSceneContextMenuEvent>
 #include <boost/polymorphic_cast.hpp>
 
 using boost::polymorphic_downcast;
@@ -72,9 +66,8 @@ void MaskGraphicsScene::setMaskContext(IntensityDataItem* intensityItem)
         disconnectMaskContainer(m_maskContainerModel);
 
         // check container type
-        const QString containerType{maskContainerItem->modelType()};
-        ASSERT(containerType == MaskContainerItem::M_TYPE
-               && containerType == ProjectionContainerItem::M_TYPE);
+        ASSERT(dynamic_cast<MaskContainerItem*>(maskContainerItem)
+               || dynamic_cast<ProjectionContainerItem*>(maskContainerItem));
 
         m_maskContainerItem = maskContainerItem;
         m_maskContainerModel = maskContainerModel;
@@ -391,21 +384,17 @@ void MaskGraphicsScene::updateViews()
 
     IShape2DView* maskView = addViewForItem(m_maskContainerItem);
 
-    for (SessionItem* maskItem : m_maskContainerItem->maskItems()) {
+    for (MaskItem* maskItem : m_maskContainerItem->maskItems()) {
         if (!maskItem)
             continue;
-        if (maskItem->hasModelType<PropertyItem>())
-            continue;
 
         IShape2DView* itemView = addViewForItem(maskItem);
 
         if (itemView && maskView) {
             maskView->addView(itemView);
 
-            // Add views for the points of the PolygonItem without
-            // using the SessionItem mechanism
-            if (maskItem->hasModelType<PolygonItem>()) {
-                auto polygonItem = dynamic_cast<PolygonItem*>(maskItem);
+            // Add views for the points of the PolygonItem
+            if (auto polygonItem = dynamic_cast<PolygonItem*>(maskItem)) {
                 IShape2DView* const polygonView = itemView;
                 for (PolygonPointItem* pointItem : polygonItem->points()) {
                     IShape2DView* pointView = addViewForItem(pointItem);
@@ -418,7 +407,7 @@ void MaskGraphicsScene::updateViews()
 
 //! Creates a view for given item.
 
-IShape2DView* MaskGraphicsScene::addViewForItem(SessionItem* item)
+IShape2DView* MaskGraphicsScene::addViewForItem(MaskItemObject* item)
 {
     ASSERT(item);
     IShape2DView* view = m_ItemToView[item];
@@ -430,14 +419,14 @@ IShape2DView* MaskGraphicsScene::addViewForItem(SessionItem* item)
             return view;
         }
     }
-    subscribeMaskItemObject(dynamic_cast<MaskItemObject*>(item));
+    subscribeMaskItemObject(item);
 
     return view;
 }
 
 //! Removes single view from scene.
 
-void MaskGraphicsScene::removeItemViewFromScene(SessionItem* item)
+void MaskGraphicsScene::removeItemViewFromScene(MaskItem* item)
 {
     for (auto it = m_ItemToView.begin(); it != m_ItemToView.end(); ++it) {
         if (it.key() == item) {
@@ -477,8 +466,8 @@ bool MaskGraphicsScene::isValidForRectangleShapeDrawing(QGraphicsSceneMouseEvent
         return false;
     if (m_context.isROIMode()) {
         // only one ROI is allowed
-        for (SessionItem* item : m_ItemToView.keys())
-            if (item->modelType() == RegionOfInterestItem::M_TYPE)
+        for (MaskItemObject* item : m_ItemToView.keys())
+            if (dynamic_cast<RegionOfInterestItem*>(item))
                 return false;
     }
     return true;
@@ -527,8 +516,9 @@ bool MaskGraphicsScene::isValidForMaskAllDrawing(QGraphicsSceneMouseEvent* event
         return false;
     if (!m_context.isMaskAllMode())
         return false;
-    for (SessionItem* item : m_ItemToView.keys())
-        if (item->modelType() == MaskAllItem::M_TYPE)
+
+    for (MaskItemObject* item : m_ItemToView.keys())
+        if (dynamic_cast<MaskAllItem*>(item))
             return false;
     return true;
 }
@@ -577,9 +567,9 @@ void MaskGraphicsScene::setInPanAndZoomMode(bool value)
 void MaskGraphicsScene::updateCursors()
 {
     for (auto it = m_ItemToView.begin(); it != m_ItemToView.end(); ++it) {
-        if (it.key()->modelType() == VerticalLineItem::M_TYPE)
+        if (dynamic_cast<VerticalLineItem*>(it.key()))
             it.value()->setCursor(m_context.isInZoomMode() ? Qt::ArrowCursor : Qt::SizeHorCursor);
-        else if (it.key()->modelType() == HorizontalLineItem::M_TYPE)
+        else if (dynamic_cast<HorizontalLineItem*>(it.key()))
             it.value()->setCursor(m_context.isInZoomMode() ? Qt::ArrowCursor : Qt::SizeVerCursor);
     }
 }
@@ -606,8 +596,16 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent*
 
     if (!m_currentItem && line.length() > min_distance_to_create_rect) {
 
-        MaskItem* newMaskItem = dynamic_cast<MaskItem*>(
-            GUI::Model::ItemFactory::CreateItem(m_context.activityToModelType()));
+        MaskItem* newMaskItem;
+        if (m_context.isRectangleMode())
+            newMaskItem = new RectangleItem;
+        else if (m_context.isEllipseMode())
+            newMaskItem = new EllipseItem;
+        else if (m_context.isROIMode())
+            newMaskItem = new RegionOfInterestItem;
+        else
+            ASSERT(false);
+
         // TODO: What to do for the case when `m_context.isROIMode() = true`?
         m_maskContainerModel->addMask(newMaskItem);
 
@@ -617,7 +615,8 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent*
 
         if (!m_context.isROIMode())
             dynamic_cast<MaskItem*>(m_currentItem)->setMaskValue(m_context.getMaskValue());
-        setItemName(m_currentItem);
+
+        m_maskContainerItem->updateMaskNames();
     } else if (!m_currentItem)
         return;
 
@@ -626,15 +625,13 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent*
     qreal ymin = std::min(click_pos.y(), mouse_pos.y());
     qreal ymax = std::max(click_pos.y(), mouse_pos.y());
 
-    if (m_currentItem->modelType() == RectangleItem::M_TYPE
-        || m_currentItem->modelType() == RegionOfInterestItem::M_TYPE) {
-        auto* rectItem = polymorphic_downcast<RectangleItem*>(m_currentItem);
+    if (auto* rectItem = dynamic_cast<RectangleItem*>(m_currentItem)) {
+        // RectangleItem or RegionOfInterestItem
         rectItem->setXLow(m_adaptor->fromSceneX(xmin));
         rectItem->setYLow(m_adaptor->fromSceneY(ymax));
         rectItem->setXUp(m_adaptor->fromSceneX(xmax));
         rectItem->setYUp(m_adaptor->fromSceneY(ymin));
-    } else if (m_currentItem->modelType() == EllipseItem::M_TYPE) {
-        auto* ellItem = polymorphic_downcast<EllipseItem*>(m_currentItem);
+    } else if (auto* ellItem = dynamic_cast<EllipseItem*>(m_currentItem)) {
         ellItem->setXCenter(m_adaptor->fromSceneX(xmin + (xmax - xmin) / 2.));
         ellItem->setYCenter(m_adaptor->fromSceneY(ymin + (ymax - ymin) / 2.));
         ellItem->setXRadius((m_adaptor->fromSceneX(xmax) - m_adaptor->fromSceneX(xmin)) / 2.);
@@ -658,9 +655,9 @@ void MaskGraphicsScene::processPolygonItem(QGraphicsSceneMouseEvent* event)
         m_selectionModel->clearSelection();
         m_selectionModel->select(m_maskContainerModel->indexOfItem(m_currentItem),
                                  QItemSelectionModel::Select);
-        setItemName(m_currentItem);
+        m_maskContainerItem->updateMaskNames();
     }
-    ASSERT(m_currentItem->modelType() == PolygonItem::M_TYPE);
+    ASSERT(dynamic_cast<PolygonItem*>(m_currentItem));
 
     if (PolygonView* polygon = currentPolygon()) {
         if (polygon->closePolygonIfNecessary()) {
@@ -690,7 +687,7 @@ void MaskGraphicsScene::processLineItem(QGraphicsSceneMouseEvent* event)
     m_selectionModel->clearSelection();
     m_selectionModel->select(m_maskContainerModel->indexOfItem(m_currentItem),
                              QItemSelectionModel::Select);
-    setItemName(m_currentItem);
+    m_maskContainerItem->updateMaskNames();
     dynamic_cast<MaskItem*>(m_currentItem)->setMaskValue(m_context.getMaskValue());
 
     subscribeMaskItemObject(m_currentItem);
@@ -738,7 +735,7 @@ void MaskGraphicsScene::subscribeMaskItemObject(MaskItemObject* item)
             Qt::UniqueConnection);
 }
 
-//! Update Z-values of all IMaskView to reflect stacking order in SessionModel.
+//! Update Z-values of all IMaskView to reflect stacking order.
 
 void MaskGraphicsScene::setZValues()
 {
@@ -764,27 +761,3 @@ PolygonView* MaskGraphicsScene::currentPolygon() const
     }
     return result;
 }
-
-//! Sets item name depending on alreay existent items.
-//! If there is already "Rectangle1", the new name will be "Rectangle2"
-
-void MaskGraphicsScene::setItemName(SessionItem* itemToChange)
-{
-    if (itemToChange->modelType() == RegionOfInterestItem::M_TYPE)
-        return;
-
-    const QString itemToChange_name = itemToChange->itemName();
-    int i_row = 0, glob_index = i_row;
-    for (MaskItem* currentItem : m_maskContainerItem->maskItems()) {
-        if (currentItem->modelType() == itemToChange->modelType()) {
-            QString itemName = currentItem->itemName();
-            if (itemName.startsWith(itemToChange_name)) {
-                int item_index = itemName.remove(0, itemToChange_name.size()).toInt();
-                if (item_index > glob_index)
-                    glob_index = item_index;
-            }
-        }
-    }
-
-    itemToChange->setItemName(itemToChange_name + QString::number(glob_index + 1));
-}
diff --git a/GUI/View/Mask/MaskGraphicsScene.h b/GUI/View/Mask/MaskGraphicsScene.h
index a14b79ed51e2fcc68cc03fdacf3649149e05d32a..5ed6a703da83af94b62812013e20bb5c0a8446c6 100644
--- a/GUI/View/Mask/MaskGraphicsScene.h
+++ b/GUI/View/Mask/MaskGraphicsScene.h
@@ -18,25 +18,20 @@
 #include "GUI/View/Mask/MaskDrawingContext.h"
 #include "GUI/View/Mask/MaskEditorHelper.h"
 #include <QGraphicsScene>
-#include <QMap>
-#include <QModelIndex>
-#include <QSharedPointer>
+#include <QItemSelection>
+#include <QItemSelectionModel>
 
-class SessionModel;
-class SessionItem;
-class IShape2DView;
 class ISceneAdaptor;
-class MaskItemObject;
+class IShape2DView;
+class IntensityDataItem;
 class MaskContainerItem;
 class MaskContainerModel;
+class MaskEditorAction;
 class MaskGraphicsProxy;
-class QItemSelectionModel;
-class QItemSelection;
+class MaskItem;
+class MaskItemObject;
 class PolygonView;
-class MaskEditorAction;
-class IntensityDataItem;
-class QGraphicsSceneMouseEvent;
-class QPainter;
+
 class ColorMap;
 
 //! Graphics scene for MaskEditorCanvas to draw masks on top of intensity data widgets.
@@ -85,8 +80,8 @@ protected:
 private:
     void updateProxyWidget();
     void updateViews();
-    IShape2DView* addViewForItem(SessionItem* sessionItem);
-    void removeItemViewFromScene(SessionItem* sessionItem);
+    IShape2DView* addViewForItem(MaskItemObject* item);
+    void removeItemViewFromScene(MaskItem* item);
 
     void connectMaskContainer(MaskContainerModel* maskContainerModel);
     void disconnectMaskContainer(MaskContainerModel* maskContainerModel);
@@ -115,12 +110,11 @@ private:
 
     void setZValues();
     PolygonView* currentPolygon() const;
-    void setItemName(SessionItem* itemToChange);
 
     MaskContainerModel* m_maskContainerModel = nullptr;
     MaskContainerItem* m_maskContainerItem = nullptr;
     QItemSelectionModel* m_selectionModel = nullptr;
-    QMap<SessionItem*, IShape2DView*> m_ItemToView;
+    QMap<MaskItemObject*, IShape2DView*> m_ItemToView;
     MaskGraphicsProxy* m_proxy = nullptr;
     QSharedPointer<ISceneAdaptor> m_adaptor;
     bool m_block_selection = false;
diff --git a/GUI/View/Mask/MaskViewFactory.cpp b/GUI/View/Mask/MaskViewFactory.cpp
index c120395489b9142550ef223f839c26b3b31f08a1..c04387a3564c652faa41f597a6494226bdf0fbec 100644
--- a/GUI/View/Mask/MaskViewFactory.cpp
+++ b/GUI/View/Mask/MaskViewFactory.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/View/Mask/MaskViewFactory.h"
-#include "GUI/Model/BaseItem/SessionItem.h"
 #include "GUI/Model/Data/ProjectionItems.h"
 #include "GUI/Model/Device/MaskItems.h"
 #include "GUI/Util/Error.h"
@@ -29,54 +28,42 @@
 
 using boost::polymorphic_downcast;
 
-IShape2DView* MaskViewFactory::createMaskView(SessionItem* item, ISceneAdaptor* adaptor)
+IShape2DView* MaskViewFactory::createMaskView(MaskItemObject* item, ISceneAdaptor* adaptor)
 {
     IShape2DView* result(nullptr);
 
-    if (item->hasModelType<MaskContainerItem>())
-        result = new MaskContainerView(polymorphic_downcast<MaskContainerItem*>(item));
+    if (auto* mask = dynamic_cast<MaskContainerItem*>(item))
+        result = new MaskContainerView(mask);
 
-    else if (item->hasModelType<ProjectionContainerItem>())
-        result = new MaskContainerView(polymorphic_downcast<ProjectionContainerItem*>(item));
+    else if (auto* mask = dynamic_cast<ProjectionContainerItem*>(item))
+        result = new MaskContainerView(mask);
 
+    else if (auto* mask = dynamic_cast<RectangleItem*>(item))
+        result = new RectangleView(mask);
 
-    else if (item->hasModelType<RectangleItem>())
-        result = new RectangleView(polymorphic_downcast<RectangleItem*>(item));
+    else if (auto* mask = dynamic_cast<PolygonItem*>(item))
+        result = new PolygonView(mask);
 
+    else if (auto* mask = dynamic_cast<PolygonPointItem*>(item))
+        result = new PolygonPointView(mask);
 
-    else if (item->hasModelType<PolygonItem>())
-        result = new PolygonView(polymorphic_downcast<PolygonItem*>(item));
+    else if (auto* mask = dynamic_cast<VerticalLineItem*>(item))
+        result = new VerticalLineView(mask);
 
+    else if (auto* mask = dynamic_cast<HorizontalLineItem*>(item))
+        result = new HorizontalLineView(mask);
 
-    else if (item->hasModelType<PolygonPointItem>())
-        result = new PolygonPointView(polymorphic_downcast<PolygonPointItem*>(item));
+    else if (auto* mask = dynamic_cast<EllipseItem*>(item))
+        result = new EllipseView(mask);
 
+    else if (auto* mask = dynamic_cast<MaskAllItem*>(item))
+        result = new MaskAllView(mask);
 
-    else if (item->hasModelType<VerticalLineItem>())
-        result = new VerticalLineView(polymorphic_downcast<VerticalLineItem*>(item));
+    else if (auto* mask = dynamic_cast<RegionOfInterestItem*>(item))
+        result = new RegionOfInterestView(mask);
 
-
-    else if (item->hasModelType<HorizontalLineItem>())
-        result = new HorizontalLineView(polymorphic_downcast<HorizontalLineItem*>(item));
-
-
-    else if (item->hasModelType<EllipseItem>())
-        result = new EllipseView(polymorphic_downcast<EllipseItem*>(item));
-
-
-    else if (item->hasModelType<MaskAllItem>())
-        result = new MaskAllView(polymorphic_downcast<MaskAllItem*>(item));
-
-
-    else if (item->hasModelType<RegionOfInterestItem>())
-        result = new RegionOfInterestView(polymorphic_downcast<RegionOfInterestItem*>(item));
-
-
-    else {
-        throw Error("MaskViewFactory::createSampleView() -> Error! "
-                    "Cannot create a view for "
-                    + item->modelType());
-    }
+    else
+        ASSERT(false);
 
     result->setSceneAdaptor(adaptor);
 
diff --git a/GUI/View/Mask/MaskViewFactory.h b/GUI/View/Mask/MaskViewFactory.h
index 38852220e8cd806b5dbba5ffca7f0cbdade7a24e..e4c807dcba89b71178eb0f19ee655359f8045d94 100644
--- a/GUI/View/Mask/MaskViewFactory.h
+++ b/GUI/View/Mask/MaskViewFactory.h
@@ -18,14 +18,14 @@
 #include <QString>
 
 class IShape2DView;
-class SessionItem;
+class MaskItemObject;
 class ISceneAdaptor;
 
 //! Factory to construct views out of MaskItems for MaskGraphicsScene
 
 class MaskViewFactory {
 public:
-    static IShape2DView* createMaskView(SessionItem* item, ISceneAdaptor* adaptor = nullptr);
+    static IShape2DView* createMaskView(MaskItemObject* item, ISceneAdaptor* adaptor = nullptr);
 };
 
 #endif // BORNAGAIN_GUI_VIEW_MASK_MASKVIEWFACTORY_H
diff --git a/GUI/View/Mask/PolygonPointView.cpp b/GUI/View/Mask/PolygonPointView.cpp
index 14beb64b3acef1f2a6f325640017c2ff5b7f718b..349149654d9c3b40402688b0cfdf402b0eda5969 100644
--- a/GUI/View/Mask/PolygonPointView.cpp
+++ b/GUI/View/Mask/PolygonPointView.cpp
@@ -31,7 +31,7 @@ QRectF PolygonPointView::boundingRect() const
     return QRectF(-4, -4, 8, 8);
 }
 
-SessionItem* PolygonPointView::parameterizedItem() const
+MaskItemObject* PolygonPointView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/PolygonPointView.h b/GUI/View/Mask/PolygonPointView.h
index c47e9c47de985d5474cfc08d8566f5f6f5123b01..9c9ff69ba2f54f395f0aa9534724ad3a1f0d7776 100644
--- a/GUI/View/Mask/PolygonPointView.h
+++ b/GUI/View/Mask/PolygonPointView.h
@@ -31,7 +31,7 @@ public:
 
     QRectF boundingRect() const override;
 
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
     void updateParameterizedItem(const QPointF& pos);
 
diff --git a/GUI/View/Mask/PolygonView.cpp b/GUI/View/Mask/PolygonView.cpp
index 2642d00b4daebd9bf67688772f3e12d977a99f49..4204a45f33d657a54484d3ec6eae6d60560a29b8 100644
--- a/GUI/View/Mask/PolygonView.cpp
+++ b/GUI/View/Mask/PolygonView.cpp
@@ -34,7 +34,7 @@ PolygonView::PolygonView(PolygonItem* item)
     setFlag(QGraphicsItem::ItemSendsGeometryChanges);
 }
 
-SessionItem* PolygonView::parameterizedItem() const
+MaskItemObject* PolygonView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/PolygonView.h b/GUI/View/Mask/PolygonView.h
index d86a25c50e1350fe8c76513ba2fcebc51ba069ae..2c891bd16ee88117195ebbea50223598fd4b3bd2 100644
--- a/GUI/View/Mask/PolygonView.h
+++ b/GUI/View/Mask/PolygonView.h
@@ -31,7 +31,7 @@ public:
 
     explicit PolygonView(PolygonItem* item);
 
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
     void addView(IShape2DView* childView) override;
     bool isClosedPolygon();
diff --git a/GUI/View/Mask/RectangleView.cpp b/GUI/View/Mask/RectangleView.cpp
index c350405e063d630740de33d56d1a9e87e0e3525f..e55fd790216fe995937d5bb7668b174e387cccdd 100644
--- a/GUI/View/Mask/RectangleView.cpp
+++ b/GUI/View/Mask/RectangleView.cpp
@@ -30,7 +30,7 @@ QPainterPath RectangleView::shape() const
     return path;
 }
 
-SessionItem* RectangleView::parameterizedItem() const
+MaskItemObject* RectangleView::parameterizedItem() const
 {
     return m_item;
 }
diff --git a/GUI/View/Mask/RectangleView.h b/GUI/View/Mask/RectangleView.h
index faa382c351fa106c0760f71c503dd8efe33ef400..07e193b7aec31dbb9e6d3f6b1ce300dc83c368cd 100644
--- a/GUI/View/Mask/RectangleView.h
+++ b/GUI/View/Mask/RectangleView.h
@@ -31,7 +31,7 @@ public:
     explicit RectangleView(RectangleItem* item);
 
     QPainterPath shape() const override;
-    SessionItem* parameterizedItem() const override;
+    MaskItemObject* parameterizedItem() const override;
 
 protected slots:
     void onChangedX() override;
diff --git a/GUI/View/Projection/ProjectionsPlot.cpp b/GUI/View/Projection/ProjectionsPlot.cpp
index 7cb5c33f6e374ce16090433f60c76e672a10c055..f70d1d2c4b047b71cef96da1f62c070726f24d09 100644
--- a/GUI/View/Projection/ProjectionsPlot.cpp
+++ b/GUI/View/Projection/ProjectionsPlot.cpp
@@ -27,9 +27,9 @@
 
 using boost::polymorphic_downcast;
 
-ProjectionsPlot::ProjectionsPlot(QString projectionType, QWidget* parent)
+ProjectionsPlot::ProjectionsPlot(ProjectionType projectionType, QWidget* parent)
     : DataItemBundleWidget(parent)
-    , m_projectionType(std::move(projectionType))
+    , m_projectionType(projectionType)
     , m_customPlot(new QCustomPlot)
 {
     auto* vlayout = new QVBoxLayout(this);
@@ -140,17 +140,28 @@ ProjectionContainerItem* ProjectionsPlot::projectionContainerItem()
     return result;
 }
 
-QVector<SessionItem*> ProjectionsPlot::projectionItems()
+QVector<MaskItem*> ProjectionsPlot::projectionItems()
 {
     return projectionContainerItem()->projectionsOfType(m_projectionType);
 }
 
-QCPGraph* ProjectionsPlot::graphForItem(SessionItem* item)
+bool ProjectionsPlot::isCorrectProjectionType(MaskItemObject* item)
+{
+    if (m_projectionType == ProjectionType::Horizontal && dynamic_cast<HorizontalLineItem*>(item))
+        return true;
+
+    if (m_projectionType == ProjectionType::Vertical && dynamic_cast<VerticalLineItem*>(item))
+        return true;
+
+    return false;
+}
+
+QCPGraph* ProjectionsPlot::graphForItem(MaskItemObject* item)
 {
     if (!intensityItem())
         return nullptr;
 
-    if (item->modelType() != m_projectionType)
+    if (!isCorrectProjectionType(item))
         return nullptr;
 
     QCPGraph* graph = m_item_to_graph[item];
@@ -189,7 +200,7 @@ void ProjectionsPlot::updateProjections()
     replot();
 }
 
-void ProjectionsPlot::onProjectionPropertyChanged(SessionItem* item)
+void ProjectionsPlot::onProjectionPropertyChanged(MaskItemObject* item)
 {
     if (auto* graph = graphForItem(item))
         setGraphFromItem(graph, item);
@@ -224,7 +235,7 @@ void ProjectionsPlot::updateAxesTitle()
 
 //! Removes plot corresponding to given projection item.
 
-void ProjectionsPlot::clearProjection(SessionItem* item)
+void ProjectionsPlot::clearProjection(MaskItemObject* item)
 {
     if (auto* graph = graphForItem(item)) {
         m_customPlot->removePlottable(graph);
@@ -243,7 +254,7 @@ void ProjectionsPlot::clearAll()
 
 //! Sets the data to graph from given projection iten.
 
-void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, SessionItem* item)
+void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, MaskItemObject* item)
 {
     if (!intensityItem() || !intensityItem()->datafield())
         return;
@@ -251,13 +262,13 @@ void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, SessionItem* item)
     std::unique_ptr<Datafield> field;
 
     // TODO: merge with very similar code in SaveProjectionsAssistant::projectionsData
-    if (item->modelType() == HorizontalLineItem::M_TYPE) {
-        double value = polymorphic_downcast<HorizontalLineItem*>(item)->posY();
-        field.reset(intensityItem()->datafield()->xProjection(value));
-    } else {
-        double value = polymorphic_downcast<VerticalLineItem*>(item)->posX();
-        field.reset(intensityItem()->datafield()->yProjection(value));
-    }
+    if (const auto* horLine = dynamic_cast<HorizontalLineItem*>(item))
+        field.reset(intensityItem()->datafield()->xProjection(horLine->posY()));
+    else if (const auto* verLine = dynamic_cast<VerticalLineItem*>(item))
+        field.reset(intensityItem()->datafield()->yProjection(verLine->posX()));
+    else
+        ASSERT(false);
+
 
     auto centers = field->axis(0).binCenters();
     auto values = field->flatVector();
@@ -285,5 +296,5 @@ void ProjectionsPlot::replot()
 
 bool ProjectionsPlot::isHorizontalType()
 {
-    return m_projectionType == HorizontalLineItem::M_TYPE;
+    return m_projectionType == ProjectionType::Horizontal;
 }
diff --git a/GUI/View/Projection/ProjectionsPlot.h b/GUI/View/Projection/ProjectionsPlot.h
index 40a99c835fa5383500209619428b48c8f160979f..425857461f05a8a8ae7724803d1c3928fe61b68c 100644
--- a/GUI/View/Projection/ProjectionsPlot.h
+++ b/GUI/View/Projection/ProjectionsPlot.h
@@ -15,14 +15,15 @@
 #ifndef BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H
 #define BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H
 
+#include "GUI/Support/Data/ProjectionType.h"
 #include "GUI/View/Common/DataItemBundleWidget.h"
 #include <QMap>
 #include <memory>
 
+class Datafield;
 class IntensityDataItem;
+class MaskItem;
 class ProjectionContainerItem;
-class Datafield;
-class QCPGraph;
 
 //! A customplot based widget to display projections of IntensityDataItem on X,Y axes.
 
@@ -30,7 +31,7 @@ class ProjectionsPlot : public DataItemBundleWidget {
     Q_OBJECT
 
 public:
-    ProjectionsPlot(QString projectionType, QWidget* parent = nullptr);
+    ProjectionsPlot(ProjectionType projectionType, QWidget* parent = nullptr);
 
     void setIntensityItem(IntensityDataItem* intensityDataItem) override;
 
@@ -42,19 +43,20 @@ public slots:
 
 private:
     IntensityDataItem* intensityItem();
-    QVector<SessionItem*> projectionItems();
+    QVector<MaskItem*> projectionItems();
+    bool isCorrectProjectionType(MaskItemObject* item);
     ProjectionContainerItem* projectionContainerItem();
-    QCPGraph* graphForItem(SessionItem* item);
+    QCPGraph* graphForItem(MaskItemObject* item);
 
     void updateProjectionsData();
     void updateProjections();
-    void onProjectionPropertyChanged(SessionItem* item);
+    void onProjectionPropertyChanged(MaskItemObject* item);
     void updateAxesRange();
     void updateAxesTitle();
-    void clearProjection(SessionItem* item);
+    void clearProjection(MaskItemObject* item);
     void clearAll();
 
-    void setGraphFromItem(QCPGraph* graph, SessionItem* item);
+    void setGraphFromItem(QCPGraph* graph, MaskItemObject* item);
 
     void setInterpolate(bool isInterpolated);
     void setLogz(bool isLogz);
@@ -63,9 +65,9 @@ private:
 
     bool isHorizontalType();
 
-    QString m_projectionType;
+    ProjectionType m_projectionType = ProjectionType::Invalid;
     QCustomPlot* m_customPlot;
-    QMap<SessionItem*, QCPGraph*> m_item_to_graph;
+    QMap<MaskItemObject*, QCPGraph*> m_item_to_graph;
 };
 
 #endif // BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H
diff --git a/GUI/View/Projection/ProjectionsWidget.cpp b/GUI/View/Projection/ProjectionsWidget.cpp
index 0013ad622bbd6802ed06bcb2cb522761a6698aa0..f2abb5c956bd437751ac005d8b6415b1e0119e1f 100644
--- a/GUI/View/Projection/ProjectionsWidget.cpp
+++ b/GUI/View/Projection/ProjectionsWidget.cpp
@@ -28,8 +28,8 @@ const int vertical_projection_tab = 1;
 
 ProjectionsWidget::ProjectionsWidget(QWidget* parent)
     : QWidget(parent)
-    , m_xProjection(new ProjectionsPlot(HorizontalLineItem::M_TYPE))
-    , m_yProjection(new ProjectionsPlot(VerticalLineItem::M_TYPE))
+    , m_xProjection(new ProjectionsPlot(ProjectionType::Horizontal))
+    , m_yProjection(new ProjectionsPlot(ProjectionType::Vertical))
     , m_tabWidget(new QTabWidget)
 {
     auto* layout = new QVBoxLayout;
@@ -37,8 +37,8 @@ ProjectionsWidget::ProjectionsWidget(QWidget* parent)
     layout->setSpacing(0);
 
     m_tabWidget->setTabPosition(QTabWidget::North);
-    m_tabWidget->insertTab(HORIZONTAL, m_xProjection, "Horizontal");
-    m_tabWidget->insertTab(VERTICAL, m_yProjection, "Vertical");
+    m_tabWidget->insertTab(ProjectionType::Horizontal, m_xProjection, "Horizontal");
+    m_tabWidget->insertTab(ProjectionType::Vertical, m_yProjection, "Vertical");
 
     layout->addWidget(m_tabWidget);
     setLayout(layout);
diff --git a/GUI/View/Projection/ProjectionsWidget.h b/GUI/View/Projection/ProjectionsWidget.h
index 4f683477abebcd5313ffc81fd44741aed3065c51..4b997f8aa9795cc56f279f9b9390200b0dd31f08 100644
--- a/GUI/View/Projection/ProjectionsWidget.h
+++ b/GUI/View/Projection/ProjectionsWidget.h
@@ -27,8 +27,6 @@ class ProjectionsWidget : public QWidget {
     Q_OBJECT
 
 public:
-    enum ETabId { HORIZONTAL, VERTICAL };
-
     ProjectionsWidget(QWidget* parent = nullptr);
 
     void setIntensityItem(IntensityDataItem* intensityDataItem);
diff --git a/GUI/View/Projection/SaveProjectionsAssistant.cpp b/GUI/View/Projection/SaveProjectionsAssistant.cpp
index 15b219a94610506f67cf6706de4767c1577147ed..74c404a24c9c109fcfa04f618bddbdb2e73b3816 100644
--- a/GUI/View/Projection/SaveProjectionsAssistant.cpp
+++ b/GUI/View/Projection/SaveProjectionsAssistant.cpp
@@ -17,7 +17,6 @@
 #include "Device/Data/Datafield.h"
 #include "GUI/Application/ApplicationSettings.h"
 #include "GUI/Model/Data/IntensityDataItem.h"
-#include "GUI/Model/Data/ProjectionItems.h"
 #include "GUI/Model/Device/MaskItems.h"
 #include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/Util/Error.h"
@@ -45,13 +44,13 @@ QString to_double_str(double value)
     return QString("%1").arg(QString::fromStdString(str), -bin_centers_colwidth);
 }
 
-bool vert_less_posx(SessionItem* item1, SessionItem* item2)
+bool vert_less_posx(MaskItemObject* item1, MaskItemObject* item2)
 {
     return polymorphic_downcast<VerticalLineItem*>(item1)->posX()
            < polymorphic_downcast<VerticalLineItem*>(item2)->posX();
 }
 
-bool horiz_less_posy(SessionItem* item1, SessionItem* item2)
+bool horiz_less_posy(MaskItemObject* item1, MaskItemObject* item2)
 {
     return polymorphic_downcast<HorizontalLineItem*>(item1)->posY()
            < polymorphic_downcast<HorizontalLineItem*>(item2)->posY();
@@ -88,11 +87,11 @@ void SaveProjectionsAssistant::saveProjections(QWidget* parent, IntensityDataIte
     QTextStream out(&file);
 
     out << "# Projections along x-axis (horizontal projections) \n";
-    out << projectionsToString(HorizontalLineItem::M_TYPE, intensityItem);
+    out << projectionsToString(ProjectionType::Horizontal, intensityItem);
     out << "\n";
 
     out << "# Projections along y-axis (vertical projections) \n";
-    out << projectionsToString(VerticalLineItem::M_TYPE, intensityItem);
+    out << projectionsToString(ProjectionType::Vertical, intensityItem);
     out << "\n";
 
     file.close();
@@ -100,7 +99,7 @@ void SaveProjectionsAssistant::saveProjections(QWidget* parent, IntensityDataIte
 
 //! Generates multi-line string with projections data of given type (horizontal, vertical).
 
-QString SaveProjectionsAssistant::projectionsToString(const QString& projectionsType,
+QString SaveProjectionsAssistant::projectionsToString(ProjectionType projectionsType,
                                                       IntensityDataItem* intensityItem)
 {
     QString result;
@@ -127,23 +126,24 @@ QString SaveProjectionsAssistant::projectionsToString(const QString& projections
 //! Returns projections data for all projections of given type (horizontal, vertical).
 
 SaveProjectionsAssistant::ProjectionsData
-SaveProjectionsAssistant::projectionsData(const QString& projectionsType,
+SaveProjectionsAssistant::projectionsData(ProjectionType projectionsType,
                                           IntensityDataItem* intensityItem)
 {
     ProjectionsData result;
-    result.is_horizontal = (projectionsType != VerticalLineItem::M_TYPE);
+    result.is_horizontal = (projectionsType == ProjectionType::Horizontal);
 
     for (auto* item : projectionItems(projectionsType, intensityItem)) {
         std::unique_ptr<Datafield> field;
         SaveProjectionsAssistant::Projection data;
 
-        if (item->modelType() == HorizontalLineItem::M_TYPE) {
-            data.axis_value = polymorphic_downcast<HorizontalLineItem*>(item)->posY();
+        if (const auto* horLine = dynamic_cast<HorizontalLineItem*>(item)) {
+            data.axis_value = horLine->posY();
             field.reset(m_field->xProjection(data.axis_value));
-        } else {
-            data.axis_value = polymorphic_downcast<VerticalLineItem*>(item)->posX();
+        } else if (const auto* verLine = dynamic_cast<VerticalLineItem*>(item)) {
+            data.axis_value = verLine->posX();
             field.reset(m_field->yProjection(data.axis_value));
-        }
+        } else
+            ASSERT(false);
 
         auto values = field->flatVector();
         auto centers = field->axis(0).binCenters();
@@ -157,12 +157,12 @@ SaveProjectionsAssistant::projectionsData(const QString& projectionsType,
 
 //! Returns vector of ProjectionItems sorted according to axis value.
 
-QVector<SessionItem*> SaveProjectionsAssistant::projectionItems(const QString& projectionsType,
-                                                                IntensityDataItem* intensityItem)
+QVector<MaskItem*> SaveProjectionsAssistant::projectionItems(ProjectionType projectionsType,
+                                                             IntensityDataItem* intensityItem)
 {
     auto result = intensityItem->projectionContainerItem()->projectionsOfType(projectionsType);
     std::sort(result.begin(), result.end(),
-              projectionsType == HorizontalLineItem::M_TYPE ? horiz_less_posy : vert_less_posx);
+              projectionsType == ProjectionType::Horizontal ? horiz_less_posy : vert_less_posx);
     return result;
 }
 
diff --git a/GUI/View/Projection/SaveProjectionsAssistant.h b/GUI/View/Projection/SaveProjectionsAssistant.h
index 07b61e044a7f8871c8429ea84f0bd20aaf568798..78812aa8a0e5cfca221944691cc8a01074bbee0b 100644
--- a/GUI/View/Projection/SaveProjectionsAssistant.h
+++ b/GUI/View/Projection/SaveProjectionsAssistant.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_VIEW_PROJECTION_SAVEPROJECTIONSASSISTANT_H
 #define BORNAGAIN_GUI_VIEW_PROJECTION_SAVEPROJECTIONSASSISTANT_H
 
+#include "GUI/Model/Data/ProjectionItems.h"
 #include <QString>
 #include <QVector>
 #include <QWidget>
@@ -22,7 +23,6 @@
 
 class IntensityDataItem;
 class Datafield;
-class SessionItem;
 
 //! Assistant class which save all projections of IndensityDataItem into ASCII file.
 
@@ -45,13 +45,13 @@ private:
         QVector<Projection> projections;
     };
 
-    QString projectionsToString(const QString& projectionsType, IntensityDataItem* intensityItem);
+    QString projectionsToString(ProjectionType projectionsType, IntensityDataItem* intensityItem);
 
     const Datafield* m_field;
-    ProjectionsData projectionsData(const QString& projectionsType,
+    ProjectionsData projectionsData(ProjectionType projectionsType,
                                     IntensityDataItem* intensityItem);
-    QVector<SessionItem*> projectionItems(const QString& projectionsType,
-                                          IntensityDataItem* intensityItem);
+    QVector<MaskItem*> projectionItems(ProjectionType projectionsType,
+                                       IntensityDataItem* intensityItem);
 
     QString projectionFileHeader(ProjectionsData& projectionsData);
 };
diff --git a/Tests/Unit/GUI/TestMapperForItem.cpp b/Tests/Unit/GUI/TestMapperForItem.cpp
index 044dab3a67d7a5f638a1d3e8ebb886f48ea9fefc..eaf360fc72ecd083e73e202ca4328d65324f7799 100644
--- a/Tests/Unit/GUI/TestMapperForItem.cpp
+++ b/Tests/Unit/GUI/TestMapperForItem.cpp
@@ -104,49 +104,3 @@ TEST_F(TestMapperForItem, initialCondition)
     EXPECT_TRUE(m_mapped_item == nullptr);
     EXPECT_TRUE(!m_mapper);
 }
-
-
-// NOTE: TwoWidgetsSubscription works only with the SessionItem mechanism,
-// but the SessionItem mechanism is removed from HorizontalLineItem.
-// TODO: Remove/refactor this test after elimination of the
-// SessionItem mechanism.
-TEST_F(TestMapperForItem, DISABLED_TwoWidgetsSubscription)
-{
-    Widget w1, w2;
-    JobModel model;
-    auto* container = model.insertItem<ProjectionContainerItem>();
-    auto* line = model.insertItem<HorizontalLineItem>(container);
-
-    // Mapper is looking on child; set property of child
-    setItem(line);
-    w1.subscribe(m_mapper.get(), true);
-    w2.subscribe(m_mapper.get(), true);
-    EXPECT_EQ(w1.m_onPropertyChangeCount, 0);
-    EXPECT_EQ(w2.m_onPropertyChangeCount, 0);
-
-    line->setPosY(1.0);
-    EXPECT_EQ(w1.m_onPropertyChangeCount, 1);
-    EXPECT_EQ(w2.m_onPropertyChangeCount, 1);
-
-    w1.unsubscribe(m_mapper.get());
-    line->setPosY(2.0);
-    EXPECT_EQ(w1.m_onPropertyChangeCount, 1);
-    EXPECT_EQ(w2.m_onPropertyChangeCount, 2);
-}
-
-TEST_F(TestMapperForItem, DISABLED_AboutToRemoveChild)
-{
-    Widget w;
-    JobModel model;
-    auto* container = model.insertItem<ProjectionContainerItem>();
-    auto* line = model.insertItem<HorizontalLineItem>(container);
-
-    setItem(container, &w);
-    EXPECT_EQ(w.m_onAboutToRemoveChild, 0);
-    EXPECT_EQ(w.m_reported_items.size(), 0);
-
-    delete line->itemParent()->takeRow(line->itemParent()->rowOfChild(line));
-    EXPECT_EQ(w.m_onAboutToRemoveChild, 1);
-    EXPECT_EQ(w.m_reported_items.size(), 1);
-    EXPECT_EQ(w.m_reported_items.back(), line);
-}