diff --git a/GUI/Model/Data/Data2DItem.cpp b/GUI/Model/Data/Data2DItem.cpp
index 2d7803c37b4ef97b68a136b325a5a8c6bd72d2d2..c1ae3c7a6100d1cd0096df406e7820d53fe6d9cd 100644
--- a/GUI/Model/Data/Data2DItem.cpp
+++ b/GUI/Model/Data/Data2DItem.cpp
@@ -365,7 +365,7 @@ Datafield* Data2DItem::createMaskedField() const
     std::unique_ptr<IShape2D> roi;
     Datafield* result = c_field()->clone();
     MaskStack detectorMask;
-    const auto& maskItems = masksSet()->maskItems();
+    const auto& maskItems = masksSet()->maskItemsQ();
 
     // reverse loop (waiting for C++ ranges)
     for (auto maskIter = maskItems.crbegin(); maskIter != maskItems.crend(); maskIter++) {
diff --git a/GUI/Model/Descriptor/PolyItem.h b/GUI/Model/Descriptor/PolyItem.h
index d3f2cb536ab1e0251de34240fd31bc42c68caa6d..961a61fb3296ad149fd67c215419b1d66d81eb33 100644
--- a/GUI/Model/Descriptor/PolyItem.h
+++ b/GUI/Model/Descriptor/PolyItem.h
@@ -81,20 +81,21 @@ public:
         m_item.reset(t);
     }
 
-    //! Serializes the catalog index of the currently selected type and calls
-    //! main serialization method of the selected class.
-    void writeTo(QXmlStreamWriter* w) const
+    static void writeItemTo(const BaseType* t, QXmlStreamWriter* w)
     {
-        const uint typeIndex = static_cast<uint>(Catalog::type(m_item.get()));
+        const uint typeIndex = static_cast<uint>(Catalog::type(t));
         XML::writeAttribute(w, XML::Attrib::type, typeIndex);
         // The next line allows to see the name of item type in XML. May be skipped while reading.
-        XML::writeAttribute(w, XML::Attrib::name,
-                            Catalog::uiInfo(Catalog::type(m_item.get())).menuEntry);
+        XML::writeAttribute(w, XML::Attrib::name, Catalog::uiInfo(Catalog::type(t)).menuEntry);
         XML::writeAttribute(w, XML::Attrib::selection_version, uint(1));
-        if (m_item)
-            m_item->writeTo(w);
+        if (t)
+            t->writeTo(w);
     }
 
+    //! Serializes the catalog index of the currently selected type and calls
+    //! main serialization method of the selected class.
+    void writeTo(QXmlStreamWriter* w) const { writeItemTo(m_item.get(), w); }
+
     //! Deserializes the catalog index of the currently selected type, creates a new
     //! object of this type and calls main deserialization method of the selected class.
     template <typename... Args> void readFrom(QXmlStreamReader* r, Args... args)
diff --git a/GUI/Model/Descriptor/PolyVector.h b/GUI/Model/Descriptor/PolyVector.h
index 7105439703cacdafc5a7f5695236a61f348720d1..24e6215adbd5d7de4c082514d92e9891f0ecbdbe 100644
--- a/GUI/Model/Descriptor/PolyVector.h
+++ b/GUI/Model/Descriptor/PolyVector.h
@@ -56,7 +56,7 @@ public:
                         m_v.begin() + toIndex + 1);
     }
 
-    QVector<BaseType*> toModifiableQVector() const
+    QVector<BaseType*> toQVector() const
     {
         QVector<BaseType*> result;
         for (const auto& p : m_v)
@@ -64,14 +64,6 @@ public:
         return result;
     }
 
-    QVector<const BaseType*> toQVector() const
-    {
-        QVector<const BaseType*> result;
-        for (const auto& p : m_v)
-            result.append(p.certainItem());
-        return result;
-    }
-
     void emplace_item_back(BaseType* item) { insert_item_at(m_v.size(), item); }
     void clear() { m_v.clear(); }
     size_t size() const { return m_v.size(); }
diff --git a/GUI/Model/Detector/DetectorItem.cpp b/GUI/Model/Detector/DetectorItem.cpp
index 7ffedbacd053d653859391c5f74c48eefdcbd408..d96c15e1fdb2ee97bed484b9f024987d09e8fe7a 100644
--- a/GUI/Model/Detector/DetectorItem.cpp
+++ b/GUI/Model/Detector/DetectorItem.cpp
@@ -68,7 +68,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->maskItems();
+        const auto& maskItems = m_masks->maskItemsQ();
 
         // reverse loop (waiting for C++ ranges)
         for (auto maskIter = maskItems.crbegin(); maskIter != maskItems.crend(); maskIter++) {
diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp
index 8daebd40e18367d92960d2c4e534841211f9ab8b..ff0f8072a220676db75498465f74145f4140499f 100644
--- a/GUI/Model/Job/JobItem.cpp
+++ b/GUI/Model/Job/JobItem.cpp
@@ -228,7 +228,7 @@ void JobItem::convertMaskCoords()
     // then from bins to target coords.
     // If 'IDetector::addBinMask' is used by detector, only "orig coords --> bins" is needed.
     if (const auto* container = m_dfile_item->data2DItem()->masksSet())
-        for (auto* maskItem : container->modifiableMaskItems())
+        for (auto* maskItem : container->maskItemsQ())
             mask_converter.convertToNbins(maskItem);
 }
 
diff --git a/GUI/Model/Mask/MasksSet.cpp b/GUI/Model/Mask/MasksSet.cpp
index 81799480752e4c01e9e78e7a942aafbbb6d36769..3ea98dc1068fd5f5afedf185c3326fe2a327c482 100644
--- a/GUI/Model/Mask/MasksSet.cpp
+++ b/GUI/Model/Mask/MasksSet.cpp
@@ -13,7 +13,9 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Mask/MasksSet.h"
+#include "GUI/Model/Descriptor/PolyItem.h"
 #include "GUI/Model/Mask/MaskItems.h"
+#include "GUI/Support/XML/UtilXML.h"
 #include <QRegularExpression>
 
 namespace {
@@ -28,42 +30,40 @@ MasksSet::MasksSet() = default;
 
 MasksSet::~MasksSet() = default;
 
-QVector<MaskItem*> MasksSet::modifiableMaskItems() const
+QVector<MaskItem*> MasksSet::maskItemsQ() const
 {
-    return m_mask_items.toModifiableQVector();
-}
-
-QVector<const MaskItem*> MasksSet::maskItems() const
-{
-    return m_mask_items.toQVector();
+    QVector<MaskItem*> ret;
+    for (MaskItem* t : m_mask_items)
+        ret << t;
+    return ret;
 }
 
 void MasksSet::insertMask(int row, MaskItem* maskItem)
 {
     // takes owning of maskItem!
-    m_mask_items.insert_item_at(row, maskItem);
+    m_mask_items.insert_at(row, maskItem);
 }
 
 void MasksSet::addMaskItem(MaskItem* maskItem)
 {
     // takes owning of maskItem!
-    m_mask_items.emplace_item_back(maskItem);
+    m_mask_items.emplace_back(maskItem);
 }
 
 void MasksSet::moveMask(int from_row, int to_row)
 {
-    m_mask_items.move_polyitem(from_row, to_row);
+    m_mask_items.swap(from_row, to_row);
 }
 
 void MasksSet::removeMaskAt(int row)
 {
-    m_mask_items.delete_polyitem_at(row);
+    m_mask_items.delete_at(row);
 }
 
 RegionOfInterestItem* MasksSet::regionOfInterestItem() const
 {
-    for (const auto& maskSel : m_mask_items)
-        if (auto* roi = dynamic_cast<RegionOfInterestItem*>(maskSel.certainItem()))
+    for (auto* t : m_mask_items)
+        if (auto* roi = dynamic_cast<RegionOfInterestItem*>(t))
             return roi;
 
     return nullptr;
@@ -86,7 +86,7 @@ int MasksSet::size() const
 
 MaskItem* MasksSet::at(const int idx)
 {
-    return m_mask_items.at(idx).certainItem();
+    return m_mask_items.at(idx);
 }
 
 int MasksSet::indexOfItem(const MaskItem* maskItem) const
@@ -99,9 +99,8 @@ void MasksSet::updateMaskNames()
     const auto reg = QRegularExpression("[0-9]");
 
     QMap<QString, int> numMasksByType;
-    for (const auto& m_mask_item : m_mask_items) {
-
-        QString name = m_mask_item.certainItem()->maskName();
+    for (MaskItem* t : m_mask_items) {
+        QString name = t->maskName();
         name.remove(reg);
 
         int numMasks = 1;
@@ -112,7 +111,7 @@ void MasksSet::updateMaskNames()
         numMasksByType.insert(name, numMasks);
         name += QString::number(numMasks);
 
-        m_mask_item.certainItem()->setMaskName(name);
+        t->setMaskName(name);
     }
 }
 
@@ -120,9 +119,9 @@ void MasksSet::writeTo(QXmlStreamWriter* w) const
 {
     XML::writeAttribute(w, XML::Attrib::version, uint(1));
 
-    for (const auto& sel : m_mask_items) {
+    for (const MaskItem* t : m_mask_items) {
         w->writeStartElement(Tag::Mask);
-        sel.writeTo(w);
+        PolyItem<MasksCatalog>::writeItemTo(t, w);
         w->writeEndElement();
     }
 }
@@ -140,7 +139,7 @@ void MasksSet::readFrom(QXmlStreamReader* r, MessageService*)
         if (tag == Tag::Mask) {
             PolyItem<MasksCatalog> p;
             p.readFrom(r);
-            m_mask_items.emplace_item_back(p.releaseItem());
+            m_mask_items.emplace_back(p.releaseItem());
             XML::gotoEndElementOfTag(r, tag);
 
         } else
diff --git a/GUI/Model/Mask/MasksSet.h b/GUI/Model/Mask/MasksSet.h
index 5dd0c66c71b1204d00d20034ce1d4c24cf7bd590..7d33acdc4a0e33d08e6a45c12c7333e6d96bf38f 100644
--- a/GUI/Model/Mask/MasksSet.h
+++ b/GUI/Model/Mask/MasksSet.h
@@ -19,6 +19,7 @@
 #include "GUI/Model/Descriptor/PolyVector.h"
 #include "GUI/Model/Mask/MasksCatalog.h"
 #include <QModelIndex>
+#include <QXmlStreamWriter>
 
 class MaskItem;
 class MessageService;
@@ -31,8 +32,7 @@ public:
     MasksSet();
     virtual ~MasksSet();
 
-    QVector<MaskItem*> modifiableMaskItems() const;
-    QVector<const MaskItem*> maskItems() const;
+    QVector<MaskItem*> maskItemsQ() const;
 
     //! Insert mask at given row.
     void insertMask(int row, MaskItem* maskItem);
@@ -72,7 +72,7 @@ public:
     const QModelIndex rootIndex;
 
 protected:
-    PolyVector<MasksCatalog> m_mask_items;
+    OwningVector<MaskItem> m_mask_items;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_MASK_MASKSSET_H
diff --git a/GUI/Model/Mask/ProjectionsSet.h b/GUI/Model/Mask/ProjectionsSet.h
index aedb9bf4611ec0b6b732dd2d6f288626574742eb..a8fa6505e0127d6e4096455729bc83514d26e6b8 100644
--- a/GUI/Model/Mask/ProjectionsSet.h
+++ b/GUI/Model/Mask/ProjectionsSet.h
@@ -33,8 +33,8 @@ private:
     template <typename LineType> QVector<const LineItem*> projections() const
     {
         QVector<const LineItem*> result;
-        for (const auto& proj : m_mask_items)
-            if (const auto* line_item = dynamic_cast<const LineType*>(proj.certainItem()))
+        for (const auto* proj : m_mask_items)
+            if (const auto* line_item = dynamic_cast<const LineType*>(proj))
                 result.push_back(line_item);
         return result;
     }
diff --git a/GUI/Model/Sample/CompoundItem.cpp b/GUI/Model/Sample/CompoundItem.cpp
index c39af0c8f881dac663292116a4f9eadcbfbcff97..a138c6c8f3b52347bd891abb03412323fb47eece 100644
--- a/GUI/Model/Sample/CompoundItem.cpp
+++ b/GUI/Model/Sample/CompoundItem.cpp
@@ -141,7 +141,7 @@ std::unique_ptr<Compound> CompoundItem::createCompound() const
 
 QVector<ItemWithParticles*> CompoundItem::itemsWithParticles() const
 {
-    return m_particles.toModifiableQVector();
+    return m_particles.toQVector();
 }
 
 QVector<ItemWithParticles*> CompoundItem::containedItemsWithParticles() const
diff --git a/GUI/Model/Sample/ParticleLayoutItem.cpp b/GUI/Model/Sample/ParticleLayoutItem.cpp
index 9e1d6443715c9d49baadf6a7d8325f41122f3c31..fdeefbac5778fd625f3bc140c0ad301233b08338 100644
--- a/GUI/Model/Sample/ParticleLayoutItem.cpp
+++ b/GUI/Model/Sample/ParticleLayoutItem.cpp
@@ -70,7 +70,7 @@ double ParticleLayoutItem::totalDensityValue() const
 
 QVector<ItemWithParticles*> ParticleLayoutItem::itemsWithParticles() const
 {
-    return m_particles.toModifiableQVector();
+    return m_particles.toQVector();
 }
 
 void ParticleLayoutItem::addItemWithParticleSelection(ItemWithParticles* particle)
diff --git a/GUI/View/Canvas/MaskEditorCanvas.cpp b/GUI/View/Canvas/MaskEditorCanvas.cpp
index 99ff27d011c06d76faac53dffeeff9748a6463fc..00067c0a25277547bd220a895eb5ca1407e5c956 100644
--- a/GUI/View/Canvas/MaskEditorCanvas.cpp
+++ b/GUI/View/Canvas/MaskEditorCanvas.cpp
@@ -121,7 +121,7 @@ void MaskEditorCanvas::onPresentationChange(bool pixelized)
     }
 
     if (auto* container = m_data_item->masksSet())
-        for (MaskItem* mask : container->modifiableMaskItems())
+        for (MaskItem* mask : container->maskItemsQ())
             mask->setIsVisible(!pixelized && mask->wasVisible());
 }
 
diff --git a/GUI/View/Scene/MaskGraphicsScene.cpp b/GUI/View/Scene/MaskGraphicsScene.cpp
index 331b207f41795e4c239a593ffbe588bcae007fbb..319bac59272493a3a8eec4679ee5ba92ce3af343 100644
--- a/GUI/View/Scene/MaskGraphicsScene.cpp
+++ b/GUI/View/Scene/MaskGraphicsScene.cpp
@@ -310,7 +310,7 @@ void MaskGraphicsScene::updateScene()
 
     // update Z-values of all IMaskView to reflect stacking order
     int z = m_masks_qmodel->masksSet()->size();
-    for (const MaskItem* maskItem : m_masks_qmodel->masksSet()->maskItems()) {
+    for (const MaskItem* maskItem : m_masks_qmodel->masksSet()->maskItemsQ()) {
         if (IOverlay* overlay = m_mask2overlay[maskItem])
             overlay->setZValue(z);
         --z;
@@ -366,7 +366,7 @@ void MaskGraphicsScene::updateOverlays()
     ASSERT(m_masks_qmodel);
     MasksSet* holder_item = m_masks_qmodel->masksSet();
     ASSERT(holder_item);
-    for (MaskItem* mask_item : holder_item->modifiableMaskItems()) {
+    for (MaskItem* mask_item : holder_item->maskItemsQ()) {
         IOverlay* item_overlay = registerOverlay(mask_item);
         ASSERT(item_overlay);