diff --git a/GUI/Model/Data/ApplicationModels.cpp b/GUI/Model/Data/ApplicationModels.cpp
index 767adc2483c07bdac56b462b18a669e0d4133389..aaaf1338c91561c249a1d605972aa6f61f81af3e 100644
--- a/GUI/Model/Data/ApplicationModels.cpp
+++ b/GUI/Model/Data/ApplicationModels.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Data/ApplicationModels.h"
-#include "GUI/Model/Data/DocumentModel.h"
 #include "GUI/Model/Data/RealDataModel.h"
 #include "GUI/Model/Instrument/InstrumentModel.h"
 #include "GUI/Model/Job/JobModel.h"
@@ -25,7 +24,6 @@
 
 ApplicationModels::ApplicationModels(QObject* parent)
     : QObject(parent)
-    , m_documentModel(nullptr)
     , m_materialModel(nullptr)
     , m_instrumentModel(nullptr)
     , m_sampleModel(nullptr)
@@ -33,14 +31,12 @@ ApplicationModels::ApplicationModels(QObject* parent)
     , m_jobModel(nullptr)
 {
     //! creates and initializes models, order is important
-    m_documentModel = new DocumentModel(this);
     m_materialModel = new MaterialModel(this);
     m_sampleModel = new SampleModel(this);
     m_instrumentModel = new InstrumentModel(this);
     m_realDataModel = new RealDataModel(this);
     m_jobModel = new JobModel(this);
 
-    connectModel(m_documentModel);
     connectModel(m_materialModel);
     connectModel(m_sampleModel);
     connectModel(m_instrumentModel);
@@ -52,11 +48,6 @@ ApplicationModels::ApplicationModels(QObject* parent)
 
 ApplicationModels::~ApplicationModels() = default;
 
-DocumentModel* ApplicationModels::documentModel() const
-{
-    return m_documentModel;
-}
-
 MaterialModel* ApplicationModels::materialModel() const
 {
     return m_materialModel;
@@ -85,9 +76,6 @@ JobModel* ApplicationModels::jobModel() const
 //! reset all models to initial state
 void ApplicationModels::resetModels()
 {
-    m_documentModel->clear();
-    m_documentModel->insertItem<SimulationOptionsItem>();
-
     m_materialModel->clear();
     m_materialModel->addRefractiveMaterial("Default", 1e-3, 1e-5);
     m_materialModel->addRefractiveMaterial("Vacuum", 0.0, 0.0);
@@ -112,6 +100,11 @@ void ApplicationModels::readFrom(QXmlStreamReader* reader, MessageService* messa
 {
     try {
         for (auto* model : modelList()) {
+            if (reader->name().toString() == "DocumentModel") {
+                reader->skipCurrentElement();
+                break;
+            }
+
             if (model->getModelTag() == reader->name()) {
                 model->readFrom(reader, messageService);
                 break;
@@ -128,7 +121,6 @@ void ApplicationModels::readFrom(QXmlStreamReader* reader, MessageService* messa
 QList<SessionModel*> ApplicationModels::modelList()
 {
     QList<SessionModel*> result;
-    result.append(m_documentModel);
     result.append(m_materialModel);
     result.append(m_instrumentModel);
     result.append(m_sampleModel);
diff --git a/GUI/Model/Data/ApplicationModels.h b/GUI/Model/Data/ApplicationModels.h
index 765a37afcbe361a71ab4bf6d52606efefaa896bf..500878004c388283e94dbb82740d7c2f2c3612dc 100644
--- a/GUI/Model/Data/ApplicationModels.h
+++ b/GUI/Model/Data/ApplicationModels.h
@@ -33,7 +33,6 @@ public:
     explicit ApplicationModels(QObject* parent = nullptr);
     ~ApplicationModels() override;
 
-    DocumentModel* documentModel() const;
     MaterialModel* materialModel() const;
     InstrumentModel* instrumentModel() const;
     SampleModel* sampleModel() const;
diff --git a/GUI/Model/Data/DocumentModel.cpp b/GUI/Model/Data/DocumentModel.cpp
deleted file mode 100644
index 7242015754ed82bbb9ede95cbb47a13dd1e32fc4..0000000000000000000000000000000000000000
--- a/GUI/Model/Data/DocumentModel.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Data/DocumentModel.cpp
-//! @brief     Implements class DocumentModel
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#include "GUI/Model/Data/DocumentModel.h"
-#include "GUI/Model/Session/SimulationOptionsItem.h"
-
-DocumentModel::DocumentModel(QObject* parent)
-    : SessionModel(GUI::Session::XML::DocumentModelTag, parent)
-{
-    setObjectName(GUI::Session::XML::DocumentModelTag);
-}
-
-SimulationOptionsItem* DocumentModel::simulationOptionsItem()
-{
-    return topItem<SimulationOptionsItem>();
-}
diff --git a/GUI/Model/Data/DocumentModel.h b/GUI/Model/Data/DocumentModel.h
deleted file mode 100644
index c8b2afb0328a602d05bb12d688be2c0529a85372..0000000000000000000000000000000000000000
--- a/GUI/Model/Data/DocumentModel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      GUI/Model/Data/DocumentModel.h
-//! @brief     Defines class DocumentModel
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-//  ************************************************************************************************
-
-#ifndef BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H
-#define BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H
-
-#include "GUI/Model/Session/SessionModel.h"
-
-class SimulationOptionsItem;
-
-//! The DocumentModel class is a model with GUI settings related to the opened project.
-//! Can be the place to store splitter position, etc.
-
-class DocumentModel : public SessionModel {
-    Q_OBJECT
-
-public:
-    explicit DocumentModel(QObject* parent = nullptr);
-
-    SimulationOptionsItem* simulationOptionsItem();
-};
-
-#endif // BORNAGAIN_GUI_MODEL_DATA_DOCUMENTMODEL_H
diff --git a/GUI/Model/From/GUIObjectBuilder.cpp b/GUI/Model/From/GUIObjectBuilder.cpp
index 4b27e01397cd5e6a14edab15b319a4564c74d8fb..499ba1ffe608ad0506580e0ba1ca9b39f3b067dd 100644
--- a/GUI/Model/From/GUIObjectBuilder.cpp
+++ b/GUI/Model/From/GUIObjectBuilder.cpp
@@ -16,11 +16,10 @@
 #include "Base/Const/Units.h"
 #include "Base/Util/Assert.h"
 #include "Core/Simulation/includeSimulations.h"
-#include "GUI/Model/Data/DocumentModel.h"
 #include "GUI/Model/From/FromDomain.h"
+#include "GUI/Model/From/GUIDomainSampleVisitor.h"
 #include "GUI/Model/Instrument/InstrumentItems.h"
 #include "GUI/Model/Instrument/InstrumentModel.h"
-#include "GUI/Model/From/GUIDomainSampleVisitor.h"
 #include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "Resample/Options/SimulationOptions.h"
 
@@ -93,18 +92,15 @@ SessionItem* GUI::Model::ObjectBuilder::populateInstrumentModel(InstrumentModel*
     ASSERT(0);
 }
 
-SessionItem* GUI::Model::ObjectBuilder::populateDocumentModel(DocumentModel* p_document_model,
-                                                              const ISimulation& simulation)
+void GUI::Model::ObjectBuilder::populateSimulationOptions(SimulationOptionsItem* item,
+                                                          const ISimulation& simulation)
 {
-    auto* item = p_document_model->insertItem<SimulationOptionsItem>();
-
     if (simulation.options().isIntegrate())
-        item->setUseMonteCarloIntegration(static_cast<int>(simulation.options().getMcPoints()));
+        item->setUseMonteCarloIntegration(
+            static_cast<unsigned>(simulation.options().getMcPoints()));
     else
         item->setUseAnalytical();
 
     item->setUseAverageMaterials(simulation.options().useAvgMaterials());
     item->setIncludeSpecularPeak(simulation.options().includeSpecular());
-
-    return item;
 }
diff --git a/GUI/Model/From/GUIObjectBuilder.h b/GUI/Model/From/GUIObjectBuilder.h
index 877bf3deb767f06619147167392f3ee598ec7944..44cbc403922f5cf904dde5f98fc147a21acf975c 100644
--- a/GUI/Model/From/GUIObjectBuilder.h
+++ b/GUI/Model/From/GUIObjectBuilder.h
@@ -17,7 +17,7 @@
 
 #include <QString>
 
-class DocumentModel;
+class SimulationOptionsItem;
 class ISimulation;
 class InstrumentModel;
 class MaterialModel;
@@ -33,7 +33,7 @@ SessionItem* populateInstrumentModel(InstrumentModel* p_instrument_model,
                                      const ISimulation& simulation,
                                      const QString& instrument_name = "");
 
-SessionItem* populateDocumentModel(DocumentModel* p_document_model, const ISimulation& simulation);
+void populateSimulationOptions(SimulationOptionsItem* item, const ISimulation& simulation);
 
 } // namespace GUI::Model::ObjectBuilder
 
diff --git a/GUI/Model/Group/ItemCatalog.cpp b/GUI/Model/Group/ItemCatalog.cpp
index bf0b112236cd491062ac8264fe81de9fe49c17f6..9b9a3c560caecbb5502be6ffb828374757307dbc 100644
--- a/GUI/Model/Group/ItemCatalog.cpp
+++ b/GUI/Model/Group/ItemCatalog.cpp
@@ -309,8 +309,6 @@ ItemCatalog::ItemCatalog()
     addItem<FitParameterLinkItem>();
     addItem<FitSuiteItem>();
 
-    addItem<SimulationOptionsItem>();
-
     addItem<RealDataItem>();
 
     addItem<MinimizerContainerItem>();
diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp
index 0fd79ad1bbf1ee24f461639d32b3f59119b0e11f..0e17b686d37d127f9051a79159c1425c8b94f74b 100644
--- a/GUI/Model/Job/JobItem.cpp
+++ b/GUI/Model/Job/JobItem.cpp
@@ -28,6 +28,11 @@
 #include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "GUI/Util/Error.h"
 
+namespace {
+const QString SimulationOptionsTag("SimulationOptions");
+} // namespace
+
+
 JobItem::JobItem() : SessionItem(M_TYPE)
 {
     setItemName(M_TYPE);
@@ -55,8 +60,6 @@ JobItem::JobItem() : SessionItem(M_TYPE)
     registerTag(T_DATAVIEW, 1, 1, {Data1DViewItem::M_TYPE});
     registerTag(T_PARAMETER_TREE, 0, -1, {ParameterContainerItem::M_TYPE});
 
-    registerTag(T_SIMULATION_OPTIONS, 1, 1, {SimulationOptionsItem::M_TYPE});
-
     registerTag(T_FIT_SUITE, 1, 1, {FitSuiteItem::M_TYPE});
 
     mapper()->setOnChildPropertyChange([this](SessionItem* item, const QString& name) {
@@ -224,12 +227,12 @@ bool JobItem::isProgressPropertyName(const QString& name)
 
 bool JobItem::runImmediately() const
 {
-    return simulationOptionsItem()->runImmediately();
+    return simulationOptionsItem().runImmediately();
 }
 
 bool JobItem::runInBackground() const
 {
-    return simulationOptionsItem()->runInBackground();
+    return simulationOptionsItem().runInBackground();
 }
 
 MultiLayerItem* JobItem::sampleItem()
@@ -378,6 +381,22 @@ void JobItem::setPresentationType(const QString& type)
     setItemValue(P_PRESENTATION_TYPE, type);
 }
 
+void JobItem::writeNonSessionItems(QXmlStreamWriter* writer) const
+{
+    writer->writeStartElement(SimulationOptionsTag);
+    m_simulationOptionsItem.writeContentTo(writer);
+    writer->writeEndElement();
+}
+
+void JobItem::readNonSessionItems(QXmlStreamReader* reader)
+{
+    reader->readNextStartElement();
+    if (reader->name() == SimulationOptionsTag) {
+        m_simulationOptionsItem.readContentFrom(reader);
+        reader->skipCurrentElement();
+    }
+}
+
 //! Updates the name of file to store intensity data.
 
 void JobItem::updateIntensityDataFileName()
@@ -394,18 +413,12 @@ void JobItem::updateIntensityDataFileName()
     }
 }
 
-SimulationOptionsItem* JobItem::simulationOptionsItem()
-{
-    return const_cast<SimulationOptionsItem*>(
-        static_cast<const JobItem*>(this)->simulationOptionsItem());
-}
-
-const SimulationOptionsItem* JobItem::simulationOptionsItem() const
+const SimulationOptionsItem& JobItem::simulationOptionsItem() const
 {
-    return item<const SimulationOptionsItem>(T_SIMULATION_OPTIONS);
+    return m_simulationOptionsItem;
 }
 
-SimulationOptionsItem* JobItem::copySimulationOptionsIntoJob(const SimulationOptionsItem* options)
+void JobItem::copySimulationOptionsIntoJob(const SimulationOptionsItem& options)
 {
-    return model()->copyItem(options, this, T_SIMULATION_OPTIONS);
+    m_simulationOptionsItem = options;
 }
diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h
index af3cd9677020e021bd5863a7e1d361a0d1a00c7d..16d34064e0ec0db3afcdfa3d88cedf3d44008d44 100644
--- a/GUI/Model/Job/JobItem.h
+++ b/GUI/Model/Job/JobItem.h
@@ -15,10 +15,12 @@
 #ifndef BORNAGAIN_GUI_MODEL_JOB_JOBITEM_H
 #define BORNAGAIN_GUI_MODEL_JOB_JOBITEM_H
 
+#include "GUI/Model/Job/JobStatus.h" // enum cannot be forward declared
 #include "GUI/Model/Session/SessionItem.h"
-
-#include "GUI/Model/Job/JobStatus.h"        // enum cannot be forward declared
 #include "GUI/Model/Session/SessionModel.h" // call to model() from templated fct
+#include "GUI/Model/Session/SimulationOptionsItem.h"
+#include <QDateTime>
+#include <optional>
 
 class Data1DViewItem;
 class DataItem;
@@ -34,9 +36,6 @@ class ParameterContainerItem;
 class RealDataItem;
 class SimulationOptionsItem;
 
-#include <QDateTime>
-#include <optional>
-
 class BA_CORE_API_ JobItem : public SessionItem {
 
 private:
@@ -57,7 +56,6 @@ private:
     static constexpr auto T_REALDATA{"Real Data tag"};
     static constexpr auto T_DATAVIEW{"Data View tag"};
     static constexpr auto T_PARAMETER_TREE{"Parameter tree tag"};
-    static constexpr auto T_SIMULATION_OPTIONS{"Simulation options tag"};
     static constexpr auto T_FIT_SUITE{"Fit suite tag"};
 
 public:
@@ -114,8 +112,8 @@ public:
     InstrumentItem* instrumentItem() const;
     InstrumentItem* copyInstrumentIntoJob(const InstrumentItem* instrument);
 
-    SimulationOptionsItem* simulationOptionsItem();
-    SimulationOptionsItem* copySimulationOptionsIntoJob(const SimulationOptionsItem* options);
+    const SimulationOptionsItem& simulationOptionsItem() const;
+    void copySimulationOptionsIntoJob(const SimulationOptionsItem& options);
 
     void setResults(const ISimulation* simulation);
 
@@ -148,9 +146,13 @@ public:
     QString presentationType() const;
     void setPresentationType(const QString& type);
 
+    void writeNonSessionItems(QXmlStreamWriter* writer) const override;
+    void readNonSessionItems(QXmlStreamReader* reader) override;
+
 private:
     void updateIntensityDataFileName();
-    const SimulationOptionsItem* simulationOptionsItem() const;
+
+    SimulationOptionsItem m_simulationOptionsItem;
 };
 
 template <typename T> T* JobItem::setDataType()
diff --git a/GUI/Model/Job/JobModel.cpp b/GUI/Model/Job/JobModel.cpp
index 1d710658abb73594c7acee37c1d08ef4b959dc6b..34c0f14ba4190c7fca2dc30c33f94d8a1e67a220 100644
--- a/GUI/Model/Job/JobModel.cpp
+++ b/GUI/Model/Job/JobModel.cpp
@@ -69,11 +69,10 @@ JobItem* JobModel::getJobItemForIdentifier(const QString& identifier)
 //! Main method to add a job
 JobItem* JobModel::addJob(const MultiLayerItem* multiLayerItem,
                           const InstrumentItem* instrumentItem, const RealDataItem* realDataItem,
-                          const SimulationOptionsItem* optionItem)
+                          const SimulationOptionsItem& optionItem)
 {
     ASSERT(multiLayerItem);
     ASSERT(instrumentItem);
-    ASSERT(optionItem);
 
     auto* jobItem = insertItem<JobItem>();
     jobItem->setItemName(generateJobName());
diff --git a/GUI/Model/Job/JobModel.h b/GUI/Model/Job/JobModel.h
index b11a3a3d597521793d5a5de8f05437dd80f8e753..62fea049428a533ef028e3a2ae867e0dd65b8a99 100644
--- a/GUI/Model/Job/JobModel.h
+++ b/GUI/Model/Job/JobModel.h
@@ -36,7 +36,7 @@ public:
     JobItem* getJobItemForIdentifier(const QString& identifier);
 
     JobItem* addJob(const MultiLayerItem* multiLayerItem, const InstrumentItem* instrumentItem,
-                    const RealDataItem* realDataItem, const SimulationOptionsItem* optionItem);
+                    const RealDataItem* realDataItem, const SimulationOptionsItem& optionItem);
 
     QVector<JobItem*> jobItems() const;
 
diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp
index 03eafdb077435c35edb53daa342ec2294c7657b0..c18aa8d4c37839e4f781a7cf75136d33f1bcf481 100644
--- a/GUI/Model/Project/ProjectDocument.cpp
+++ b/GUI/Model/Project/ProjectDocument.cpp
@@ -13,11 +13,11 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Project/ProjectDocument.h"
-#include "GUI/Model/Data/DocumentModel.h"
 #include "GUI/Model/IO/ProjectUtils.h"
 #include "GUI/Model/Instrument/LinkInstrumentManager.h"
 #include "GUI/Model/Job/JobModel.h"
 #include "GUI/Model/Project/OutputDataIOService.h"
+#include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "GUI/Util/Error.h"
 #include "GUI/Util/MessageService.h"
 #include "GUI/Util/Path.h"
@@ -34,6 +34,7 @@ const QString BornAgainTag("BornAgain");
 const QString BornAgainVersionAttribute("Version");
 const QString InfoTag("DocumentInfo");
 const QString InfoNameAttribute("ProjectName");
+const QString SimulationOptionsTag("SimulationOptions");
 
 } // namespace
 
@@ -133,9 +134,9 @@ JobModel* ProjectDocument::jobModel() const
     return m_applicationModels.jobModel();
 }
 
-SimulationOptionsItem* ProjectDocument::simulationOptionsItem() const
+SimulationOptionsItem* ProjectDocument::simulationOptionsItem()
 {
-    return m_applicationModels.documentModel()->simulationOptionsItem();
+    return &m_simulationOptionsItem;
 }
 
 LinkInstrumentManager* ProjectDocument::linkInstrumentManager()
@@ -318,7 +319,10 @@ ProjectDocument::ReadResult ProjectDocument::readProject(QIODevice* device,
                 while (reader.readNextStartElement())
                     if (reader.name() == InfoTag)
                         reader.skipCurrentElement();
-                    else
+                    else if (reader.name() == SimulationOptionsTag) {
+                        m_simulationOptionsItem.readContentFrom(&reader);
+                        reader.skipCurrentElement();
+                    } else
                         m_applicationModels.readFrom(&reader, &messageService);
             }
         }
@@ -348,6 +352,10 @@ void ProjectDocument::writeTo(QIODevice* device)
     writer.writeAttribute(InfoNameAttribute, projectName());
     writer.writeEndElement(); // InfoTag
 
+    writer.writeStartElement(SimulationOptionsTag);
+    m_simulationOptionsItem.writeContentTo(&writer);
+    writer.writeEndElement();
+
     m_applicationModels.writeTo(&writer);
 
     writer.writeEndElement(); // BornAgain tag
diff --git a/GUI/Model/Project/ProjectDocument.h b/GUI/Model/Project/ProjectDocument.h
index 4ffac40b4b848ef32a5827d9e1efb0746b3e4594..fcac92afdac9cd0fdf9df828365b6b2a4ec129fe 100644
--- a/GUI/Model/Project/ProjectDocument.h
+++ b/GUI/Model/Project/ProjectDocument.h
@@ -16,6 +16,7 @@
 #define BORNAGAIN_GUI_MODEL_PROJECT_PROJECTDOCUMENT_H
 
 #include "GUI/Model/Data/ApplicationModels.h"
+#include "GUI/Model/Session/SimulationOptionsItem.h"
 #include <QObject>
 #include <QVariant>
 #include <memory>
@@ -74,7 +75,7 @@ public:
     MaterialModel* materialModel() const;
     RealDataModel* realDataModel() const;
     JobModel* jobModel() const;
-    SimulationOptionsItem* simulationOptionsItem() const;
+    SimulationOptionsItem* simulationOptionsItem();
 
     LinkInstrumentManager* linkInstrumentManager();
 
@@ -134,6 +135,7 @@ private:
     bool m_singleInstrumentMode;
     bool m_singleSampleMode;
     Functionalities m_functionalities;
+    SimulationOptionsItem m_simulationOptionsItem;
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(ProjectDocument::Functionalities)
diff --git a/GUI/Model/Session/SessionItem.cpp b/GUI/Model/Session/SessionItem.cpp
index f6a8c9d47645a687888c58b39949271f1a59f801..eb8fed9b6a5bb09cf5d29e29ecee48794abf1769 100644
--- a/GUI/Model/Session/SessionItem.cpp
+++ b/GUI/Model/Session/SessionItem.cpp
@@ -335,9 +335,7 @@ QVariant SessionItem::roleProperty(int role) const
 
 bool SessionItem::setRoleProperty(int role, const QVariant& value)
 {
-    bool result = m_properties->setData(role, m_translatorForRolePropertySetter
-                                                  ? m_translatorForRolePropertySetter(role, value)
-                                                  : value);
+    bool result = m_properties->setData(role, value);
     if (result)
         emitDataChanged(role);
     return result;
@@ -541,10 +539,9 @@ QByteArray SessionItem::serializeBinaryData() const
 
 void SessionItem::deserializeBinaryData(const QByteArray&) {}
 
-void SessionItem::setTranslatorForRolePropertySetter(TranslatorForRolePropertySetter translator)
-{
-    m_translatorForRolePropertySetter = translator;
-}
+void SessionItem::writeNonSessionItems(QXmlStreamWriter*) const {}
+
+void SessionItem::readNonSessionItems(QXmlStreamReader*) {}
 
 void SessionItem::childDeleted(SessionItem* child)
 {
diff --git a/GUI/Model/Session/SessionItem.h b/GUI/Model/Session/SessionItem.h
index e753ce9394f9dd383166dbca41b46bcb0baa9e96..eef243f3d9c0268edab060943191d6da92a3400a 100644
--- a/GUI/Model/Session/SessionItem.h
+++ b/GUI/Model/Session/SessionItem.h
@@ -207,8 +207,6 @@ private:
     static constexpr auto P_NAME{"Name"};
 
 public:
-    using TranslatorForRolePropertySetter = std::function<QVariant(int, const QVariant&)>;
-
     explicit SessionItem(const QString& modelType);
     virtual ~SessionItem();
     SessionModel* model() const;
@@ -314,24 +312,8 @@ public:
     virtual QByteArray serializeBinaryData() const;
     virtual void deserializeBinaryData(const QByteArray& data);
 
-    //! Set a translation function which shall be called when a property is to be set via
-    //! setRoleProperty. Use this e.g. when the type of a property changed, and it should be
-    //! readable by legacy XML. Example: Property P_TRUE_OR_FALSE was a ComboProperty ("true",
-    //! "false") and is now a bool property. To still be able to read legacy XML project files, your
-    //! code could look like this:
-    //!
-    //!  \code
-    //!
-    //!     auto p = addProperty(P_TRUE_OR_FALSE, true);
-    //!     p->->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-    //!         if (role == Qt::DisplayRole && value.canConvert<ComboProperty>())
-    //!             return QVariant(value.value<ComboProperty>().currentIndex() == 0); // 0->"true"
-    //!         return value;
-    //!     });
-    //!
-    //! \endcode
-    //!
-    void setTranslatorForRolePropertySetter(TranslatorForRolePropertySetter translator);
+    virtual void writeNonSessionItems(QXmlStreamWriter* writer) const;
+    virtual void readNonSessionItems(QXmlStreamReader* reader);
 
 private:
     void childDeleted(SessionItem* child);
@@ -347,7 +329,6 @@ private:
     std::unique_ptr<SessionItemData> m_properties;
     std::unique_ptr<SessionItemTags> m_tags;
     std::unique_ptr<ModelMapper> m_mapper;
-    TranslatorForRolePropertySetter m_translatorForRolePropertySetter;
 };
 
 template <typename T> T* SessionItem::item(const QString& tag) const
diff --git a/GUI/Model/Session/SessionModel.cpp b/GUI/Model/Session/SessionModel.cpp
index dad544ad56919f23a71a5acd661c968bf6c578fd..462da433a6f5fb0aafede8b3d28d851891233a73 100644
--- a/GUI/Model/Session/SessionModel.cpp
+++ b/GUI/Model/Session/SessionModel.cpp
@@ -382,11 +382,9 @@ void SessionModel::readFrom(QXmlStreamReader* reader, MessageService* messageSer
     endResetModel();
 }
 
-void SessionModel::writeTo(QXmlStreamWriter* writer, SessionItem* parent)
+void SessionModel::writeTo(QXmlStreamWriter* writer)
 {
-    if (!parent)
-        parent = m_root_item;
-    GUI::Session::XML::writeTo(writer, parent);
+    GUI::Session::XML::writeTo(writer, m_root_item);
 }
 
 //! Move given parameterized item to the new_parent at given row. If new_parent is not defined,
diff --git a/GUI/Model/Session/SessionModel.h b/GUI/Model/Session/SessionModel.h
index 6303ad9ae586d7a2bf55ee00f56a412352ce3abc..8c8b61af6063fb86eb3f68b5970fc5c3b2100c4d 100644
--- a/GUI/Model/Session/SessionModel.h
+++ b/GUI/Model/Session/SessionModel.h
@@ -99,7 +99,7 @@ public:
     SessionItem* itemForIndex(const QModelIndex& index) const;
 
     virtual void readFrom(QXmlStreamReader* reader, MessageService* messageService = nullptr);
-    virtual void writeTo(QXmlStreamWriter* writer, SessionItem* parent = nullptr);
+    virtual void writeTo(QXmlStreamWriter* writer);
 
     SessionItem* moveItem(SessionItem* item, SessionItem* new_parent = nullptr, int row = -1,
                           const QString& tag = "");
diff --git a/GUI/Model/Session/SessionXML.cpp b/GUI/Model/Session/SessionXML.cpp
index 3947af9a1b38a94597a81f54d32e11fd3a9f982f..4d17697f591bcf7adfb1d044158fbc5a2d43ced9 100644
--- a/GUI/Model/Session/SessionXML.cpp
+++ b/GUI/Model/Session/SessionXML.cpp
@@ -25,12 +25,6 @@
 
 namespace {
 
-const QString bool_type_name = "bool";
-const QString double_type_name = "double";
-const QString int_type_name = "int";
-const QString uint_type_name = "uint";
-const QString qstring_type_name = "QString";
-
 void report_error(MessageService* messageService, SessionItem* item, const QString& message)
 {
     if (!messageService)
@@ -99,48 +93,58 @@ void GUI::Session::XML::writeItemAndChildItems(QXmlStreamWriter* writer, const S
         writer->writeEndElement();
     }
 
+    QString nonSessionItemContent;
+    QXmlStreamWriter nonSessionItemStream(&nonSessionItemContent);
+    item->writeNonSessionItems(&nonSessionItemStream);
+    if (!nonSessionItemContent.isEmpty()) {
+        writer->writeStartElement(GUI::Session::XML::NonSessionItemData);
+        writer->writeAttribute(GUI::Session::XML::Version, "1");
+        item->writeNonSessionItems(writer);
+        writer->writeEndElement();
+    }
+
     if (item->parent())
         writer->writeEndElement(); // ItemTag
 }
 
+void GUI::Session::XML::writeAttribute(QXmlStreamWriter* writer, const QString& attributeName,
+                                       const QVariant& variant)
+{
+    ASSERT(writer);
+    ASSERT(variant.isValid());
+
+    if (variant.type() == QVariant::Double) {
+        writer->writeAttribute(attributeName, QString::number(variant.toDouble(), 'e', 12));
+    } else if (variant.type() == QVariant::Int) {
+        writer->writeAttribute(attributeName, QString::number(variant.toInt()));
+    } else if (variant.type() == QVariant::UInt) {
+        writer->writeAttribute(attributeName, QString::number(variant.toUInt()));
+    } else if (variant.type() == QVariant::Bool) {
+        writer->writeAttribute(attributeName, QString::number(variant.toBool()));
+    } else if (variant.type() == QVariant::String) {
+        writer->writeAttribute(attributeName, variant.toString());
+    } else if (variant.type() == QVariant::Color) {
+        const auto col = variant.value<QColor>();
+        const QString tcol = col.isValid() ? col.name(QColor::HexArgb) : "";
+        writer->writeAttribute(attributeName, tcol);
+    } else if (QString(variant.typeName()) == "ComboProperty") {
+        auto combo = variant.value<ComboProperty>();
+        writer->writeAttribute(attributeName, combo.stringOfSelections());
+        writer->writeAttribute(GUI::Session::XML::ParameterExtAttribute, combo.stringOfValues());
+
+    } else
+        throw Error("GUI::Session::XML::writeVariant: Parameter type not supported "
+                    + QString(variant.typeName()));
+}
+
 void GUI::Session::XML::writeVariant(QXmlStreamWriter* writer, QVariant variant, int role)
 {
     ASSERT(writer);
     if (variant.isValid()) {
         writer->writeStartElement(GUI::Session::XML::ParameterTag);
-        QString type_name = variant.typeName();
-        writer->writeAttribute(GUI::Session::XML::ParameterTypeAttribute, type_name);
+        writer->writeAttribute(GUI::Session::XML::ParameterTypeAttribute, variant.typeName());
         writer->writeAttribute(GUI::Session::XML::ParameterRoleAttribute, QString::number(role));
-
-        if (type_name == double_type_name) {
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute,
-                                   QString::number(variant.toDouble(), 'e', 12));
-        } else if (type_name == int_type_name) {
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute,
-                                   QString::number(variant.toInt()));
-        } else if (type_name == uint_type_name) {
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute,
-                                   QString::number(variant.toUInt()));
-        } else if (type_name == bool_type_name) {
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute,
-                                   QString::number(variant.toBool()));
-        } else if (type_name == qstring_type_name) {
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, variant.toString());
-        } else if (type_name == "QColor") {
-            const auto col = variant.value<QColor>();
-            const QString tcol = col.isValid() ? col.name(QColor::HexArgb) : "";
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute, tcol);
-        } else if (type_name == "ComboProperty") {
-            auto combo = variant.value<ComboProperty>();
-            writer->writeAttribute(GUI::Session::XML::ParameterValueAttribute,
-                                   combo.stringOfSelections());
-            writer->writeAttribute(GUI::Session::XML::ParameterExtAttribute,
-                                   combo.stringOfValues());
-
-        } else
-            throw Error("GUI::Session::XML::writeVariant: Parameter type not supported "
-                        + type_name);
-
+        writeAttribute(writer, GUI::Session::XML::ParameterValueAttribute, variant);
         writer->writeEndElement(); // end ParameterTag
     }
 }
@@ -206,6 +210,11 @@ void GUI::Session::XML::readItems(QXmlStreamReader* reader, SessionItem* parent,
                     parent->deserializeBinaryData(data);
                 } else
                     throw DeserializationException::tooNew();
+            } else if (reader->name() == GUI::Session::XML::NonSessionItemData) {
+                if (reader->attributes().value(GUI::Session::XML::Version).toInt() == 1)
+                    parent->readNonSessionItems(reader);
+                else
+                    throw DeserializationException::tooNew();
             }
         } else if (reader->isEndElement()) {
             if (reader->name() == GUI::Session::XML::ItemTag && parent)
@@ -234,23 +243,23 @@ QString GUI::Session::XML::readProperty(QXmlStreamReader* reader, SessionItem* i
     }
 
     QVariant variant;
-    if (parameter_type == double_type_name) {
+    if (parameter_type == "double") {
         double parameter_value =
             reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toDouble();
         variant = parameter_value;
-    } else if (parameter_type == int_type_name) {
+    } else if (parameter_type == "int") {
         int parameter_value =
             reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toInt();
         variant = parameter_value;
-    } else if (parameter_type == uint_type_name) {
+    } else if (parameter_type == "uint") {
         unsigned parameter_value =
             reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toUInt();
         variant = parameter_value;
-    } else if (parameter_type == bool_type_name) {
+    } else if (parameter_type == "bool") {
         bool parameter_value =
             reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toInt();
         variant = parameter_value;
-    } else if (parameter_type == qstring_type_name) {
+    } else if (parameter_type == "QString") {
         QString parameter_value =
             reader->attributes().value(GUI::Session::XML::ParameterValueAttribute).toString();
         variant = parameter_value;
@@ -305,3 +314,14 @@ QString GUI::Session::XML::readProperty(QXmlStreamReader* reader, SessionItem* i
 
     return parameter_name;
 }
+
+bool GUI::Session::XML::readBoolAttribute(QXmlStreamReader* reader, const QString& attributeName)
+{
+    return reader->attributes().value(attributeName).toUInt() != 0;
+}
+
+unsigned GUI::Session::XML::readUIntAttribute(QXmlStreamReader* reader,
+                                              const QString& attributeName)
+{
+    return reader->attributes().value(attributeName).toUInt();
+}
diff --git a/GUI/Model/Session/SessionXML.h b/GUI/Model/Session/SessionXML.h
index 776c4162f05662d812e9e8b71a72a4978ebdea0b..e97bf7b2d3459bb9b4f778fe59a4f5cd1953a3a2 100644
--- a/GUI/Model/Session/SessionXML.h
+++ b/GUI/Model/Session/SessionXML.h
@@ -42,6 +42,7 @@ const QString ModelTypeAttribute("ModelType");
 const QString DisplayNameAttribute("DisplayName");
 const QString ParameterTag("Parameter");
 const QString BinaryData("BinaryData");
+const QString NonSessionItemData("NonSessionItemData");
 const QString Version("Version");
 const QString ParameterNameAttribute("ParName");
 const QString ParameterTypeAttribute("ParType");
@@ -54,13 +55,22 @@ const QString ExternalPropertyIdentifierAtt("Identifier");
 
 void writeTo(QXmlStreamWriter* writer, SessionItem* parent);
 void writeItemAndChildItems(QXmlStreamWriter* writer, const SessionItem* item);
+
+//! Write the variant as a complete tag, including the given role
 void writeVariant(QXmlStreamWriter* writer, QVariant variant, int role);
 
+//! Write the variant's value as an attribute
+void writeAttribute(QXmlStreamWriter* writer, const QString& attributeName,
+                    const QVariant& variant);
+
 void readItems(QXmlStreamReader* reader, SessionItem* parent, QString topTag = "",
                MessageService* messageService = nullptr);
 QString readProperty(QXmlStreamReader* reader, SessionItem* item,
                      MessageService* messageService = nullptr);
 
+bool readBoolAttribute(QXmlStreamReader* reader, const QString& attributeName);
+unsigned readUIntAttribute(QXmlStreamReader* reader, const QString& attributeName);
+
 } // namespace GUI::Session::XML
 
 #endif // BORNAGAIN_GUI_MODEL_SESSION_SESSIONXML_H
diff --git a/GUI/Model/Session/SimulationOptionsItem.cpp b/GUI/Model/Session/SimulationOptionsItem.cpp
index ba2bb9f55fb6bb40572b25dea237d4b477927cf0..516f863be28f4c76e7cbdb01e755434d0089ec9a 100644
--- a/GUI/Model/Session/SimulationOptionsItem.cpp
+++ b/GUI/Model/Session/SimulationOptionsItem.cpp
@@ -13,80 +13,47 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Session/SimulationOptionsItem.h"
-#include "GUI/Util/ComboProperty.h"
+#include "GUI/Model/Session/SessionXML.h"
+#include "GUI/Util/DeserializationException.h"
+#include <QXmlStreamWriter>
 #include <thread>
 
-// !! Attention !! Do not change the following texts, despite they are not matching the
-//                 constants! They are used for file loading => keep stable!
+namespace {
+namespace Tags {
+const QString RunImmediately("RunImmediately");
+const QString NumberOfThreads("NumberOfThreads");
+const QString Analytical("Analytical");
+const QString NumberOfMonteCarloPoints("NumberOfMonteCarloPoints");
+const QString UseAverageMaterials("UseAverageMaterials");
+const QString IncludeSpecularPeak("IncludeSpecularPeak");
+} // namespace Tags
+} // namespace
 
-SimulationOptionsItem::SimulationOptionsItem() : SessionItem(M_TYPE)
-{
-    addProperty(P_RUN_IMMEDIATELY, true);
-    addProperty(P_NTHREADS, static_cast<int>(std::thread::hardware_concurrency()));
-    addProperty(P_COMPUTATION_METHOD_ANALYTICAL, true);
-    addProperty(P_MC_POINTS, 100)->setEnabled(false);
-    addProperty(P_AVERAGE_MATERIAL, false);
-    addProperty(P_INCLUDE_SPECULAR_PEAK, false);
-
-    // -- add translators for legacy XML reading
-
-    getItem(P_RUN_IMMEDIATELY)
-        ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-            if (role == Qt::DisplayRole && value.canConvert<ComboProperty>())
-                return QVariant(value.value<ComboProperty>().currentIndex()
-                                == 0); // 0 was "immediately"
-            return value;
-        });
-
-    getItem(P_NTHREADS)->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-        if (role == Qt::DisplayRole && value.canConvert<ComboProperty>()) {
-            // first item was nThreads. Number of max threads has to be
-            // read from value, not from current machine's capabilities
-            const auto comboProperty = value.value<ComboProperty>();
-            const int nThreads = comboProperty.getValues().size();
-            const int selectedThreads = nThreads - comboProperty.currentIndex();
-            return QVariant(selectedThreads);
-        }
-        return value;
-    });
-
-    getItem(P_COMPUTATION_METHOD_ANALYTICAL)
-        ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-            if (role == Qt::DisplayRole && value.canConvert<ComboProperty>())
-                return QVariant(value.value<ComboProperty>().currentIndex()
-                                == 0); // 0 was "Analytical"
-            return value;
-        });
+using namespace GUI::Session::XML;
 
-    getItem(P_AVERAGE_MATERIAL)
-        ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-            if (role == Qt::DisplayRole && value.canConvert<ComboProperty>())
-                return QVariant(value.value<ComboProperty>().currentIndex()
-                                == 1); // 1 was "Average"
-            return value;
-        });
-
-    getItem(P_INCLUDE_SPECULAR_PEAK)
-        ->setTranslatorForRolePropertySetter([](int role, const QVariant& value) {
-            if (role == Qt::DisplayRole && value.canConvert<ComboProperty>())
-                return QVariant(value.value<ComboProperty>().currentIndex() == 1); // 1 was "Yes"
-            return value;
-        });
+SimulationOptionsItem::SimulationOptionsItem()
+{
+    m_runImmediately = true;
+    m_numberOfThreads = std::thread::hardware_concurrency();
+    m_computationMethodAnalytical = true;
+    m_numberOfMonteCarloPoints = 100;
+    m_useAverageMaterials = false;
+    m_includeSpecularPeak = false;
 }
 
-int SimulationOptionsItem::numberOfThreads() const
+unsigned SimulationOptionsItem::numberOfThreads() const
 {
-    return getItemValue(P_NTHREADS).toInt();
+    return m_numberOfThreads;
 }
 
-void SimulationOptionsItem::setNumberOfThreads(int number)
+void SimulationOptionsItem::setNumberOfThreads(unsigned number)
 {
-    setItemValue(P_NTHREADS, number);
+    m_numberOfThreads = number;
 }
 
 bool SimulationOptionsItem::runImmediately() const
 {
-    return getItemValue(P_RUN_IMMEDIATELY).toBool();
+    return m_runImmediately;
 }
 
 bool SimulationOptionsItem::runInBackground() const
@@ -96,18 +63,18 @@ bool SimulationOptionsItem::runInBackground() const
 
 void SimulationOptionsItem::setRunImmediately(bool runImmediately)
 {
-    setItemValue(P_RUN_IMMEDIATELY, runImmediately);
+    m_runImmediately = runImmediately;
 }
 
-void SimulationOptionsItem::setUseMonteCarloIntegration(int numberOfPoints)
+void SimulationOptionsItem::setUseMonteCarloIntegration(unsigned numberOfPoints)
 {
-    setItemValue(P_COMPUTATION_METHOD_ANALYTICAL, false);
-    setNumberOfMonteCarloPoints(numberOfPoints);
+    m_computationMethodAnalytical = false;
+    m_numberOfMonteCarloPoints = numberOfPoints;
 }
 
 void SimulationOptionsItem::setUseAnalytical()
 {
-    setItemValue(P_COMPUTATION_METHOD_ANALYTICAL, true);
+    m_computationMethodAnalytical = true;
 }
 
 bool SimulationOptionsItem::useMonteCarloIntegration() const
@@ -117,35 +84,59 @@ bool SimulationOptionsItem::useMonteCarloIntegration() const
 
 bool SimulationOptionsItem::useAnalytical() const
 {
-    return getItemValue(P_COMPUTATION_METHOD_ANALYTICAL).toBool();
-}
-
-int SimulationOptionsItem::numberOfMonteCarloPoints() const
-{
-    return getItemValue(P_MC_POINTS).toInt();
+    return m_computationMethodAnalytical;
 }
 
-void SimulationOptionsItem::setNumberOfMonteCarloPoints(int npoints)
+unsigned SimulationOptionsItem::numberOfMonteCarloPoints() const
 {
-    setItemValue(P_MC_POINTS, npoints);
+    return m_numberOfMonteCarloPoints;
 }
 
 void SimulationOptionsItem::setUseAverageMaterials(bool useAverageMaterials)
 {
-    setItemValue(P_AVERAGE_MATERIAL, useAverageMaterials);
+    m_useAverageMaterials = useAverageMaterials;
 }
 
 bool SimulationOptionsItem::useAverageMaterials() const
 {
-    return getItemValue(P_AVERAGE_MATERIAL).toBool();
+    return m_useAverageMaterials;
 }
 
 void SimulationOptionsItem::setIncludeSpecularPeak(bool includeSpecularPeak)
 {
-    setItemValue(P_INCLUDE_SPECULAR_PEAK, includeSpecularPeak);
+    m_includeSpecularPeak = includeSpecularPeak;
 }
 
 bool SimulationOptionsItem::includeSpecularPeak() const
 {
-    return getItemValue(P_INCLUDE_SPECULAR_PEAK).toBool();
+    return m_includeSpecularPeak;
+}
+
+void SimulationOptionsItem::writeContentTo(QXmlStreamWriter* writer) const
+{
+    writeAttribute(writer, GUI::Session::XML::Version, int(1));
+    writeAttribute(writer, Tags::RunImmediately, m_runImmediately);
+    writeAttribute(writer, Tags::NumberOfThreads, m_numberOfThreads);
+    writeAttribute(writer, Tags::Analytical, m_computationMethodAnalytical);
+    writeAttribute(writer, Tags::NumberOfMonteCarloPoints, m_numberOfMonteCarloPoints);
+    writeAttribute(writer, Tags::UseAverageMaterials, m_useAverageMaterials);
+    writeAttribute(writer, Tags::IncludeSpecularPeak, m_includeSpecularPeak);
+}
+
+void SimulationOptionsItem::readContentFrom(QXmlStreamReader* reader)
+{
+    const int version = reader->attributes().value(GUI::Session::XML::Version).toInt();
+
+    if (version < 1)
+        throw DeserializationException::tooOld();
+
+    if (version > 1)
+        throw DeserializationException::tooNew();
+
+    m_runImmediately = readBoolAttribute(reader, Tags::RunImmediately);
+    m_numberOfThreads = readUIntAttribute(reader, Tags::NumberOfThreads);
+    m_computationMethodAnalytical = readBoolAttribute(reader, Tags::Analytical);
+    m_numberOfMonteCarloPoints = readUIntAttribute(reader, Tags::NumberOfMonteCarloPoints);
+    m_useAverageMaterials = readBoolAttribute(reader, Tags::UseAverageMaterials);
+    m_includeSpecularPeak = readBoolAttribute(reader, Tags::IncludeSpecularPeak);
 }
diff --git a/GUI/Model/Session/SimulationOptionsItem.h b/GUI/Model/Session/SimulationOptionsItem.h
index 983351aca8e33a24a265cde7c5754f472afa90f8..50b27147e85d0355090c1b464ea2721ae626fc86 100644
--- a/GUI/Model/Session/SimulationOptionsItem.h
+++ b/GUI/Model/Session/SimulationOptionsItem.h
@@ -15,47 +15,47 @@
 #ifndef BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H
 #define BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H
 
-#include "GUI/Model/Session/SessionItem.h"
-#include <QMap>
+class QXmlStreamWriter;
+class QXmlStreamReader;
 
 //! The SimulationOptionsItem class holds simulation status (run policy, number of threads,
 //! integration flag). Used in SimulationView to define job settings. When job is started,
-//! item is copied to the job as a child.
-
-class BA_CORE_API_ SimulationOptionsItem : public SessionItem {
-private:
-    static constexpr auto P_RUN_IMMEDIATELY{"Run Policy"};
-    static constexpr auto P_NTHREADS{"Number of Threads"};
-    static constexpr auto P_COMPUTATION_METHOD_ANALYTICAL{"Computation method"};
-    static constexpr auto P_MC_POINTS{"Number of MC points"};
-    static constexpr auto P_AVERAGE_MATERIAL{"Material for Fresnel calculations"};
-    static constexpr auto P_INCLUDE_SPECULAR_PEAK{"Include specular peak"};
+//! item is copied to the job.
 
+class SimulationOptionsItem {
 public:
-    static constexpr auto M_TYPE{"SimulationOptions"};
-
     explicit SimulationOptionsItem();
 
-    void setNumberOfThreads(int n);
-    int numberOfThreads() const;
+    void setNumberOfThreads(unsigned n);
+    unsigned numberOfThreads() const;
 
     void setRunImmediately(bool runImmediately);
     bool runImmediately() const;
     bool runInBackground() const;
 
-    void setUseMonteCarloIntegration(int numberOfPoints);
+    void setUseMonteCarloIntegration(unsigned numberOfPoints);
     void setUseAnalytical();
     bool useMonteCarloIntegration() const;
     bool useAnalytical() const;
 
-    void setNumberOfMonteCarloPoints(int npoints);
-    int numberOfMonteCarloPoints() const;
+    unsigned numberOfMonteCarloPoints() const;
 
     void setUseAverageMaterials(bool useAverageMaterials);
     bool useAverageMaterials() const;
 
     void setIncludeSpecularPeak(bool includeSpecularPeak);
     bool includeSpecularPeak() const;
+
+    void writeContentTo(QXmlStreamWriter* writer) const;
+    void readContentFrom(QXmlStreamReader* reader);
+
+private:
+    bool m_runImmediately;
+    unsigned m_numberOfThreads;
+    bool m_computationMethodAnalytical;
+    unsigned m_numberOfMonteCarloPoints;
+    bool m_useAverageMaterials;
+    bool m_includeSpecularPeak;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_SESSION_SIMULATIONOPTIONSITEM_H
diff --git a/GUI/Model/To/DomainSimulationBuilder.cpp b/GUI/Model/To/DomainSimulationBuilder.cpp
index aa516add07cda1200334bc5dbc0686ade6f23103..a358a3812a23cc3d31f8c2b9aaef3cabfe0a49a9 100644
--- a/GUI/Model/To/DomainSimulationBuilder.cpp
+++ b/GUI/Model/To/DomainSimulationBuilder.cpp
@@ -21,20 +21,20 @@
 #include "Core/Simulation/includeSimulations.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/IFootprintFactor.h"
-#include "Param/Distrib/RangedDistributions.h"
-#include "Sample/Multilayer/MultiLayer.h"
-#include "Resample/Options/SimulationOptions.h"
 #include "GUI/Model/Data/AxesItems.h"
+#include "GUI/Model/Instrument/BackgroundItems.h"
 #include "GUI/Model/Instrument/BeamAngleItems.h"
 #include "GUI/Model/Instrument/BeamItems.h"
 #include "GUI/Model/Instrument/BeamWavelengthItem.h"
-#include "GUI/Model/Instrument/BackgroundItems.h"
 #include "GUI/Model/Instrument/FootprintItems.h"
 #include "GUI/Model/Instrument/InstrumentItems.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "GUI/Model/To/DomainObjectBuilder.h"
 #include "GUI/Util/Error.h"
+#include "Param/Distrib/RangedDistributions.h"
+#include "Resample/Options/SimulationOptions.h"
+#include "Sample/Multilayer/MultiLayer.h"
 
 
 namespace {
@@ -54,8 +54,7 @@ void setParameterDistributionToSimulation(ParameterDistribution::WhichParameter
 }
 
 //! adds DistributionParameters to the ISimulation
-void addDistributionParametersToSimulation(const BeamItem& beam_item,
-                                                                     GISASSimulation& simulation)
+void addDistributionParametersToSimulation(const BeamItem& beam_item, GISASSimulation& simulation)
 {
     if (beam_item.modelType() != GISASBeamItem::M_TYPE) {
         ASSERT(beam_item.modelType() == GISASBeamItem::M_TYPE);
@@ -113,34 +112,27 @@ void addBeamDivergencesToScan(const BeamItem& beam_item, AlphaScan& scan)
         scan.setAngleResolution(*resolution);
 }
 
-void setSimulationOptions(ISimulation* simulation, const SessionItem& item)
+void setSimulationOptions(ISimulation* simulation, const SimulationOptionsItem& optionItem)
 {
-    ASSERT(item.modelType() == SimulationOptionsItem::M_TYPE);
-
-    if (const auto* optionItem = dynamic_cast<const SimulationOptionsItem*>(&item)) {
-        simulation->options().setNumberOfThreads(optionItem->numberOfThreads());
-        if (optionItem->useMonteCarloIntegration())
-            simulation->options().setMonteCarloIntegration(true,
-                                                           optionItem->numberOfMonteCarloPoints());
-        simulation->options().setUseAvgMaterials(optionItem->useAverageMaterials());
-        simulation->options().setIncludeSpecular(optionItem->includeSpecularPeak());
-    }
+    simulation->options().setNumberOfThreads(optionItem.numberOfThreads());
+    if (optionItem.useMonteCarloIntegration())
+        simulation->options().setMonteCarloIntegration(true, optionItem.numberOfMonteCarloPoints());
+    simulation->options().setUseAvgMaterials(optionItem.useAverageMaterials());
+    simulation->options().setIncludeSpecular(optionItem.includeSpecularPeak());
 }
 
 std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLayer> multilayer,
                                                        const GISASInstrumentItem* instrumentItem,
-                                                       const SimulationOptionsItem* optionsItem)
+                                                       const SimulationOptionsItem& optionsItem)
 {
     std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument();
     std::unique_ptr<GISASSimulation> ret{
         new GISASSimulation(instrument->beam(), *multilayer, instrument->detector())};
 
-    addDistributionParametersToSimulation(*instrumentItem->beamItem(),
-                                                                    *ret);
+    addDistributionParametersToSimulation(*instrumentItem->beamItem(), *ret);
 
     // ISimulation options
-    if (optionsItem)
-        setSimulationOptions(ret.get(), *optionsItem);
+    setSimulationOptions(ret.get(), optionsItem);
 
     addBackgroundToSimulation(*instrumentItem, *ret);
 
@@ -150,7 +142,7 @@ std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLaye
 std::unique_ptr<OffSpecularSimulation>
 createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer,
                             const OffSpecularInstrumentItem* instrumentItem,
-                            const SimulationOptionsItem* optionsItem)
+                            const SimulationOptionsItem& optionsItem)
 {
     std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument();
     std::unique_ptr<OffSpecularSimulation> ret{
@@ -166,8 +158,7 @@ createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer,
     //                                                          gisas.get());
 
     // ISimulation options
-    if (optionsItem)
-        setSimulationOptions(ret.get(), *optionsItem);
+    setSimulationOptions(ret.get(), optionsItem);
 
     addBackgroundToSimulation(*instrumentItem, *ret);
 
@@ -177,7 +168,7 @@ createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer,
 std::unique_ptr<SpecularSimulation>
 createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
                          const SpecularInstrumentItem* instrument,
-                         const SimulationOptionsItem* options_item)
+                         const SimulationOptionsItem& optionsItem)
 {
     std::unique_ptr<SpecularSimulation> ret = std::make_unique<SpecularSimulation>();
     ret->setSample(*P_multilayer);
@@ -195,8 +186,7 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
     ret->setScan(scan);
 
     // ISimulation options
-    if (options_item)
-        setSimulationOptions(ret.get(), *options_item);
+    setSimulationOptions(ret.get(), optionsItem);
 
     addBackgroundToSimulation(*instrument, *ret);
 
@@ -206,13 +196,12 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
 std::unique_ptr<DepthProbeSimulation>
 createDepthProbeSimulation(std::unique_ptr<MultiLayer> multilayer,
                            const DepthProbeInstrumentItem* instrument,
-                           const SimulationOptionsItem* options_item)
+                           const SimulationOptionsItem& optionsItem)
 {
     std::unique_ptr<DepthProbeSimulation> ret = instrument->createSimulation();
     ret->setSample(*multilayer);
 
-    if (options_item)
-        setSimulationOptions(ret.get(), *options_item);
+    setSimulationOptions(ret.get(), optionsItem);
 
     return ret;
 }
@@ -223,7 +212,7 @@ createDepthProbeSimulation(std::unique_ptr<MultiLayer> multilayer,
 std::unique_ptr<ISimulation>
 GUI::Model::DomainSimulationBuilder::createSimulation(const MultiLayerItem* sampleItem,
                                                       const InstrumentItem* instrumentItem,
-                                                      const SimulationOptionsItem* optionsItem)
+                                                      const SimulationOptionsItem& optionsItem)
 {
     if (sampleItem == nullptr || instrumentItem == nullptr) {
         QString message(
diff --git a/GUI/Model/To/DomainSimulationBuilder.h b/GUI/Model/To/DomainSimulationBuilder.h
index 94b18d236689f8cdd26509fab4c17760408b1c4d..a3c30c6115dd1aef67d1535860b12d374a8efad4 100644
--- a/GUI/Model/To/DomainSimulationBuilder.h
+++ b/GUI/Model/To/DomainSimulationBuilder.h
@@ -30,7 +30,7 @@ namespace GUI::Model::DomainSimulationBuilder {
 
 std::unique_ptr<ISimulation> createSimulation(const MultiLayerItem* sampleItem,
                                               const InstrumentItem* instrumentItem,
-                                              const SimulationOptionsItem* optionsItem = nullptr);
+                                              const SimulationOptionsItem& optionsItem);
 } // namespace GUI::Model::DomainSimulationBuilder
 
 #endif // BORNAGAIN_GUI_MODEL_TO_DOMAINSIMULATIONBUILDER_H
diff --git a/GUI/Model/To/ToDomain.cpp b/GUI/Model/To/ToDomain.cpp
index 2f7511339f3b086448416c24a698807b7472575e..1d4d61e52b74e2f7df6e9cbc32fd3937f35421eb 100644
--- a/GUI/Model/To/ToDomain.cpp
+++ b/GUI/Model/To/ToDomain.cpp
@@ -21,7 +21,6 @@
 #include "GUI/Model/Sample/ParticleCoreShellItem.h"
 #include "GUI/Model/Sample/ParticleItem.h"
 #include "GUI/Model/Sample/ParticleLayoutItem.h"
-#include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "GUI/Model/Types/DoubleDescriptor.h"
 #include "GUI/Model/Types/UIntDescriptor.h"
 #include "Sample/Particle/MesoCrystal.h"
diff --git a/GUI/View/Script/PythonScriptWidget.cpp b/GUI/View/Script/PythonScriptWidget.cpp
index 8495a6aea040b2bf0dac6d7482c8aa2fcd002906..a2679968b82d026fe88e02ec5b1d26844bc9dac5 100644
--- a/GUI/View/Script/PythonScriptWidget.cpp
+++ b/GUI/View/Script/PythonScriptWidget.cpp
@@ -83,7 +83,7 @@ PythonScriptWidget::~PythonScriptWidget()
 
 void PythonScriptWidget::generatePythonScript(const MultiLayerItem* sampleItem,
                                               const InstrumentItem* instrumentItem,
-                                              const SimulationOptionsItem* optionItem,
+                                              const SimulationOptionsItem& optionItem,
                                               const QString& outputDir)
 {
     m_outputDir = outputDir;
diff --git a/GUI/View/Script/PythonScriptWidget.h b/GUI/View/Script/PythonScriptWidget.h
index 6acfca8101ab1ae7f1becac7ae1f0f2e090751a1..c2a69a1b00ee28ffb79ff243c4251f0e4192740a 100644
--- a/GUI/View/Script/PythonScriptWidget.h
+++ b/GUI/View/Script/PythonScriptWidget.h
@@ -35,7 +35,7 @@ public:
 
     void generatePythonScript(const MultiLayerItem* sampleItem,
                               const InstrumentItem* instrumentItem,
-                              const SimulationOptionsItem* optionItem = nullptr,
+                              const SimulationOptionsItem& optionItem,
                               const QString& outputDir = "");
 
 private slots:
diff --git a/GUI/View/Toplevel/SimulationView.cpp b/GUI/View/Toplevel/SimulationView.cpp
index a5d99b6a8e7b641d5c85497eb900994e486293d1..61ce8f530907819c6c290cdf1e9206d3f886e826 100644
--- a/GUI/View/Toplevel/SimulationView.cpp
+++ b/GUI/View/Toplevel/SimulationView.cpp
@@ -13,18 +13,18 @@
 //  ************************************************************************************************
 
 #include "GUI/View/Toplevel/SimulationView.h"
-#include "GUI/Model/Data/DocumentModel.h"
 #include "GUI/Model/Data/RealDataItem.h"
 #include "GUI/Model/Data/RealDataModel.h"
 #include "GUI/Model/Instrument/InstrumentItems.h"
+#include "GUI/Model/Instrument/InstrumentModel.h"
 #include "GUI/Model/Job/JobItem.h"
 #include "GUI/Model/Job/JobModel.h"
+#include "GUI/Model/Project/ProjectDocument.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Model/Sample/SampleModel.h"
 #include "GUI/Model/Sample/SampleValidator.h"
 #include "GUI/Model/Session/ModelUtils.h"
 #include "GUI/Model/Session/SimulationOptionsItem.h"
-#include "GUI/Model/State/SessionData.h"
 #include "GUI/View/Main/MainWindow.h"
 #include "GUI/View/Main/ProjectManager.h"
 #include "GUI/View/Script/PythonScriptWidget.h"
@@ -74,25 +74,21 @@ SimulationView::SimulationView(QWidget* parent, ProjectDocument* document)
             &SimulationView::updateEnabling);
 
     connect(m_ui->runPolicyImmediatelyRadio, &QRadioButton::toggled,
-            []() { gSessionData->projectDocument->setModified(true); });
+            [=]() { document->setModified(true); });
 
-    connect(m_ui->analyticalRadio, &QRadioButton::toggled,
-            []() { gSessionData->projectDocument->setModified(true); });
+    connect(m_ui->analyticalRadio, &QRadioButton::toggled, [=]() { document->setModified(true); });
 
     connect(m_ui->averageLayerRadio, &QRadioButton::toggled,
-            []() { gSessionData->projectDocument->setModified(true); });
+            [=]() { document->setModified(true); });
 
     connect(m_ui->numberOfThreadsCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
-            []() { gSessionData->projectDocument->setModified(true); });
+            [=]() { document->setModified(true); });
 
     connect(m_ui->numberOfMonteCarloPoints, QOverload<int>::of(&QSpinBox::valueChanged),
-            []() { gSessionData->projectDocument->setModified(true); });
+            [=]() { document->setModified(true); });
 
     connect(m_ui->includeSpecularCheck, &QCheckBox::toggled,
-            []() { gSessionData->projectDocument->setModified(true); });
-
-    connect(ProjectManager::instance(), &ProjectManager::documentOpenedOrClosed, this,
-            &SimulationView::writeOptionsToUI);
+            [=]() { document->setModified(true); });
 
     connect(m_document, &ProjectDocument::modified, this,
             &SimulationView::updateFunctionalityNarrowing);
@@ -152,8 +148,8 @@ void SimulationView::runSimulation()
         return;
     }
     JobModel* jobModel = m_document->jobModel();
-    JobItem* jobItem =
-        jobModel->addJob(selectedSample(), selectedInstrument(), selectedRealData(), optionsItem());
+    JobItem* jobItem = jobModel->addJob(selectedSample(), selectedInstrument(), selectedRealData(),
+                                        *optionsItem());
     jobModel->runJob(jobItem->index());
 }
 
@@ -168,7 +164,7 @@ void SimulationView::exportPythonScript()
     auto* pythonWidget = new PythonScriptWidget(baWin);
     pythonWidget->show();
     pythonWidget->raise();
-    pythonWidget->generatePythonScript(selectedSample(), selectedInstrument(), optionsItem(),
+    pythonWidget->generatePythonScript(selectedSample(), selectedInstrument(), *optionsItem(),
                                        ProjectManager::instance()->projectDir());
 }
 
diff --git a/Tests/Functional/GUI/Check.cpp b/Tests/Functional/GUI/Check.cpp
index 480d108d1a1c3af14a4f94fad949e0840f308c11..8a2a0ec5bf95d2543460726e38676a3b7ecddab7 100644
--- a/Tests/Functional/GUI/Check.cpp
+++ b/Tests/Functional/GUI/Check.cpp
@@ -19,13 +19,13 @@
 #include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
 #include "Device/Histo/SimulationResult.h"
-#include "GUI/Model/Data/DocumentModel.h"
+#include "GUI/Model/From/GUIDomainSampleVisitor.h"
 #include "GUI/Model/From/GUIObjectBuilder.h"
 #include "GUI/Model/Instrument/InstrumentItems.h"
 #include "GUI/Model/Instrument/InstrumentModel.h"
 #include "GUI/Model/Material/MaterialModel.h"
-#include "GUI/Model/From/GUIDomainSampleVisitor.h"
 #include "GUI/Model/Sample/SampleModel.h"
+#include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "GUI/Model/To/DomainSimulationBuilder.h"
 #include <iostream>
 
@@ -35,7 +35,7 @@ std::unique_ptr<OutputData<double>> domainData(const std::string& /*test_name*/,
                                                const ISimulation& direct_simulation)
 {
     // initializing necessary GUI
-    DocumentModel documentModel;
+    SimulationOptionsItem optionsItem;
     SampleModel sampleModel;
     InstrumentModel instrumentModel;
     MaterialModel materialModel;
@@ -44,12 +44,11 @@ std::unique_ptr<OutputData<double>> domainData(const std::string& /*test_name*/,
     GUIDomainSampleVisitor().populateSampleModel(&sampleModel, &materialModel,
                                                  *direct_simulation.sample());
     GUI::Model::ObjectBuilder::populateInstrumentModel(&instrumentModel, direct_simulation);
-    GUI::Model::ObjectBuilder::populateDocumentModel(&documentModel, direct_simulation);
+    GUI::Model::ObjectBuilder::populateSimulationOptions(&optionsItem, direct_simulation);
 
     std::unique_ptr<ISimulation> domain_simulation =
         GUI::Model::DomainSimulationBuilder::createSimulation(
-            sampleModel.multiLayerItem(), instrumentModel.instrumentItems().front(),
-            documentModel.simulationOptionsItem());
+            sampleModel.multiLayerItem(), instrumentModel.instrumentItems().front(), optionsItem);
 
     domain_simulation->runSimulation();
     return std::unique_ptr<OutputData<double>>(domain_simulation->result().data());
diff --git a/Tests/Unit/GUI/TestMapperCases.cpp b/Tests/Unit/GUI/TestMapperCases.cpp
index 03161be67212c0753c9084bea6d8d5e70543272c..e3d85696d86937c168ca7e59dbdee1350d0a040c 100644
--- a/Tests/Unit/GUI/TestMapperCases.cpp
+++ b/Tests/Unit/GUI/TestMapperCases.cpp
@@ -1,12 +1,8 @@
-#include "GUI/Model/Data/DocumentModel.h"
 #include "GUI/Model/Sample/LayerItem.h"
 #include "GUI/Model/Sample/MultiLayerItem.h"
 #include "GUI/Model/Sample/ParticleCompositionItem.h"
-#include "GUI/Model/Sample/ParticleItem.h"
 #include "GUI/Model/Sample/ParticleLayoutItem.h"
 #include "GUI/Model/Sample/SampleModel.h"
-#include "GUI/Model/Session/SessionItemUtils.h"
-#include "GUI/Model/Session/SimulationOptionsItem.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <QtTest>