diff --git a/Core/Algorithms/src/ProgressHandler.cpp b/Core/Algorithms/src/ProgressHandler.cpp
index 2728585b21043cd50acc0e8dd85bbb536d1f146c..69ded07d4a22150ef75bcb30158ba3dd65896261 100644
--- a/Core/Algorithms/src/ProgressHandler.cpp
+++ b/Core/Algorithms/src/ProgressHandler.cpp
@@ -58,10 +58,11 @@ bool ProgressHandler::update(int n)
     //std::cout << "ProgressHandler::update n:" << n << " m_nitems:" << m_nitems << " m_nitems_max:" << m_nitems_max << " progress:" << progress << std::endl;
     if(progress != m_current_progress) {
         m_current_progress = progress;
-        if(m_callback) {
-            continue_calculations = m_callback(m_current_progress); // report to gui
-        }
     }
+    if(m_callback) {
+        continue_calculations = m_callback(m_current_progress); // report to gui
+    }
+
     return continue_calculations;
 }
 
diff --git a/Fit/FitKernel/inc/FitKernel.h b/Fit/FitKernel/inc/FitKernel.h
index 7d1543f41c24dd04d6341b031f441b8f887a6602..6c9fc3ee4f7234ae99efb33b279b8d6b1df611cd 100644
--- a/Fit/FitKernel/inc/FitKernel.h
+++ b/Fit/FitKernel/inc/FitKernel.h
@@ -27,6 +27,7 @@
 #include <string>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/scoped_ptr.hpp>
+#include <atomic>
 
 class GISASSimulation;
 class ParameterPool;
@@ -100,7 +101,13 @@ class BA_CORE_API_ FitKernel
 
     void notifyObservers();
 
- private:
+    bool isInterrupted() const;
+
+    void interruptFitting();
+
+    void resetInterrupt();
+
+private:
     FitKernel& operator=(const FitKernel& );
     FitKernel(const FitKernel& );
 
@@ -115,6 +122,7 @@ class BA_CORE_API_ FitKernel
     FitSuiteChiSquaredFunction m_function_chi2;
     FitSuiteGradientFunction m_function_gradient;
     bool m_is_last_iteration;
+    std::atomic<bool> m_is_interrupted;
     boost::posix_time::ptime m_start_time;
     boost::posix_time::ptime m_end_time;
     FitSuite *m_fit_suite;
diff --git a/Fit/FitKernel/inc/FitSuite.h b/Fit/FitKernel/inc/FitSuite.h
index 5310d3b4090dd06d7985007a71f30124886e13f8..86d5bfa236f1fa878f6d3e451170d64f1112ae79 100644
--- a/Fit/FitKernel/inc/FitSuite.h
+++ b/Fit/FitKernel/inc/FitSuite.h
@@ -19,6 +19,7 @@
 #include "IObserver.h"
 #include "FitKernel.h"
 #include "IHistogram.h"
+#include "OutputData.h"
 
 
 //! @class FitSuite
@@ -135,6 +136,18 @@ public:
     //! Sets general setting of fit kernel
     void setOptions(const FitOptions &fit_options);
 
+    void interruptFitting();
+
+    void resetInterrupt();
+
+    bool isInterrupted();
+
+    const OutputData<double> *getRealOutputData(size_t i_item = 0) const;
+
+    const OutputData<double> *getSimulationOutputData(size_t i_item = 0) const;
+
+    const OutputData<double> *getChiSquaredOutputData(size_t i_item = 0) const;
+
 private:
     FitSuite& operator=(const FitSuite& );
     FitSuite(const FitSuite& );
diff --git a/Fit/FitKernel/src/FitKernel.cpp b/Fit/FitKernel/src/FitKernel.cpp
index d02b73ea7ba8445b7d73fbd4a1b3901cd8177f5b..bf2ff21a6d7df80716b639bb3b2bf79fca5d7354 100644
--- a/Fit/FitKernel/src/FitKernel.cpp
+++ b/Fit/FitKernel/src/FitKernel.cpp
@@ -26,6 +26,7 @@
 FitKernel::FitKernel(FitSuite *fit_suite)
     : m_minimizer(MinimizerFactory::createMinimizer("Minuit2", "Migrad"))
     , m_is_last_iteration(false)
+    , m_is_interrupted(false)
     , m_fit_suite(fit_suite)
 {
     m_function_chi2.init(this);
@@ -45,6 +46,7 @@ void FitKernel::clear()
     m_fit_parameters.clear();
     m_fit_strategies.clear();
     m_is_last_iteration = false;
+    m_is_interrupted = false;
 }
 
 //! Adds pair of (simulation, real data) for consecutive simulation
@@ -119,7 +121,9 @@ void FitKernel::minimize()
     m_fit_objects.setNfreeParameters((int)m_fit_parameters.getNfreeParameters());
 
     // minimizing
-    m_minimizer->minimize();
+    try {
+        m_minimizer->minimize();
+    } catch (int) {}
 
     // setting found values to the parameters
     m_fit_parameters.setValues(m_minimizer->getValueOfVariablesAtMinimum());
@@ -165,6 +169,20 @@ size_t FitKernel::getCurrentStrategyIndex() const
     return m_fit_strategies.getCurrentStrategyIndex();
 }
 
+bool FitKernel::isInterrupted() const
+{
+    return m_is_interrupted;
+}
+
+void FitKernel::interruptFitting()
+{
+    m_is_interrupted = true;
+}
+
+void FitKernel::resetInterrupt()
+{
+    m_is_interrupted = false;
+}
 
 // results to stdout
 void FitKernel::printResults() const
diff --git a/Fit/FitKernel/src/FitSuite.cpp b/Fit/FitKernel/src/FitSuite.cpp
index eeda74b1773dafcb4edc9aa2810c860e379557b3..39010541793c37ccae34c3d9f9ee2e98f8b9ac42 100644
--- a/Fit/FitKernel/src/FitSuite.cpp
+++ b/Fit/FitKernel/src/FitSuite.cpp
@@ -119,6 +119,22 @@ IHistogram *FitSuite::getChiSquaredMap(size_t i_item) const
     return IHistogram::createHistogram(*data);
 }
 
+const OutputData<double> *FitSuite::getRealOutputData(size_t i_item) const
+{
+    return m_kernel->getFitObjects()->getRealData(i_item);
+}
+
+const OutputData<double> *FitSuite::getSimulationOutputData(size_t i_item) const
+{
+    return m_kernel->getFitObjects()->getSimulationData(i_item);
+}
+
+const OutputData<double> *FitSuite::getChiSquaredOutputData(size_t i_item) const
+{
+    return m_kernel->getFitObjects()->getChiSquaredMap(i_item);
+}
+
+
 FitSuiteObjects *FitSuite::getFitObjects()
 {
     return m_kernel->getFitObjects();
@@ -159,14 +175,17 @@ double FitSuite::getChi2() const
     return m_kernel->getFitObjects()->getChiSquaredValue();
 }
 
-FitOptions &FitSuite::getOptions()
+void FitSuite::interruptFitting()
 {
-    return m_kernel->getOptions();
+    m_kernel->interruptFitting();
 }
 
-void FitSuite::setOptions(const FitOptions &fit_options)
+void FitSuite::resetInterrupt()
 {
-   m_kernel->setOptions(fit_options);
+    m_kernel->resetInterrupt();
 }
 
-
+bool FitSuite::isInterrupted()
+{
+    return m_kernel->isInterrupted();
+}
diff --git a/Fit/FitKernel/src/FitSuiteFunctions.cpp b/Fit/FitKernel/src/FitSuiteFunctions.cpp
index 08a17eb00209009470758c740818baa797f221d9..5fc4923ed6a5d35a1b140a65de972cf5e13c5558 100644
--- a/Fit/FitKernel/src/FitSuiteFunctions.cpp
+++ b/Fit/FitKernel/src/FitSuiteFunctions.cpp
@@ -23,6 +23,9 @@ double FitSuiteChiSquaredFunction::evaluate(const double *pars)
 {
     assert(m_fit_kernel != nullptr);
 
+    if (m_fit_kernel->isInterrupted())
+        throw 0;
+
     m_fit_kernel->getFitParameters()->setValues(pars);
     m_fit_kernel->getFitObjects()->runSimulations();
     double chi_squared = m_fit_kernel->getFitObjects()->getChiSquaredValue();
diff --git a/Fit/PythonAPI/src/FitSuite.pypp.cpp b/Fit/PythonAPI/src/FitSuite.pypp.cpp
index 3110569d09ca64b49aa2783505f578783204dd83..20780dc3bb105a576533831b951a4f86860b12e8 100644
--- a/Fit/PythonAPI/src/FitSuite.pypp.cpp
+++ b/Fit/PythonAPI/src/FitSuite.pypp.cpp
@@ -218,7 +218,7 @@ void register_FitSuite_class(){
                 , "Returns current number of minimization function calls." );
         
         }
-        { //::FitSuite::getOptions
+        /*{ //::FitSuite::getOptions
         
             typedef ::FitOptions & ( ::FitSuite::*getOptions_function_type)(  ) ;
             
@@ -228,7 +228,7 @@ void register_FitSuite_class(){
                 , bp::return_value_policy< bp::reference_existing_object >()
                 , "Returns general setting of fit kernel." );
         
-        }
+        }*/
         { //::FitSuite::getRealData
         
             typedef ::IHistogram * ( ::FitSuite::*getRealData_function_type)( ::std::size_t ) const;
@@ -326,7 +326,7 @@ void register_FitSuite_class(){
                 , "Sets minimizer with given name and algorithm type @param minimizer The name of the minimizer @param algorithm Optional name of the minimizer's algorithm @param options Optional string with additional minimizer settings \n\n:Parameters:\n  - 'minimizer' - The name of the minimizer\n  - 'algorithm' - Optional name of the minimizer's algorithm\n  - 'options' - Optional string with additional minimizer settings\n" );
         
         }
-        { //::FitSuite::setOptions
+        /*{ //::FitSuite::setOptions
         
             typedef void ( ::FitSuite::*setOptions_function_type)( ::FitOptions const & ) ;
             
@@ -336,7 +336,7 @@ void register_FitSuite_class(){
                 , ( bp::arg("fit_options") )
                 , "Sets general setting of fit kernel." );
         
-        }
+        }*/
         { //::FitSuite::setParametersFixed
         
             typedef void ( ::FitSuite::*setParametersFixed_function_type)( ::std::vector< std::string > const &,bool ) ;
diff --git a/GUI/coregui/Models/FitModel.cpp b/GUI/coregui/Models/FitModel.cpp
index 41b4c5188a6da5225d7c0c67c6a05e8041cf26d0..ee4d89bd68b38fbd577cf9e48609b0c9fb99374a 100644
--- a/GUI/coregui/Models/FitModel.cpp
+++ b/GUI/coregui/Models/FitModel.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      coregui/Models/FitModel.cpp
-//! @brief     Implements class FitModel
+//! @file      coregui/Models/NJobModel.cpp
+//! @brief     Implements class NJobModel
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -14,12 +14,128 @@
 // ************************************************************************** //
 
 #include "FitModel.h"
+#include "SampleModel.h"
+#include "InstrumentModel.h"
+#include "FitParameterItems.h"
+#include "ParameterizedItem.h"
+#include "SessionModel.h"
+#include "ComboProperty.h"
+#include <QStringList>
 
 
-FitModel::FitModel(QObject *parent)
+FitModel::FitModel(SampleModel *samples, InstrumentModel *instruments, QObject *parent)
     : SessionModel(SessionXML::FitModelTag, parent)
+    , m_sampleModel(samples)
+    , m_instrumentModel(instruments)
 {
 
 }
 
+FitParameterContainer *FitModel::getFitParameterContainer() {
+    return dynamic_cast<FitParameterContainer *>
+            (itemForIndex(QModelIndex())->getChildOfType(Constants::FitParameterContainerType));
+}
+
+FitSelectionItem *FitModel::getFitSelection() {
+    return dynamic_cast<FitSelectionItem *>
+            (itemForIndex(QModelIndex())->getChildOfType(Constants::FitSelectionType));
+}
+
+InputDataItem *FitModel::getInputData() {
+    return dynamic_cast<InputDataItem *>
+            (itemForIndex(QModelIndex())->getChildOfType(Constants::InputDataType));
+}
+
+QString FitModel::getSelectedSampleName () {
+    return getFitSelection()->getRegisteredProperty(FitSelectionItem::P_SAMPLE).toString();
+}
+
+QString FitModel::getSelectedInstrumentName(){
+    return getFitSelection()->getRegisteredProperty(FitSelectionItem::P_INSTRUMENT).toString();
+}
+
+QStringList FitModel::getSampleNames() {
+    return retrieveDisplayNames(m_sampleModel, Constants::MultiLayerType);
+}
+
+QStringList FitModel::getInstrumentNames() {
+    return retrieveDisplayNames(m_instrumentModel, Constants::InstrumentType);
+}
+
+QStringList FitModel::retrieveDisplayNames(SessionModel *model, const QString &type) {
+    QStringList list;
+    for (int i_row = 0; i_row < model->rowCount(QModelIndex()); ++i_row) {
+        QModelIndex itemIndex = model->index(i_row, 0, QModelIndex());
+        if (ParameterizedItem *item = model->itemForIndex(itemIndex)) {
+            if (item->modelType()  == type) {
+                list << item->displayName();
+            }
+        }
+    }
+    return list;
+}
+
+QString FitModel::getSampleItemNameForDisplayName(const QString &displayName) {
+    if (auto *item = m_sampleModel->itemForIndex(QModelIndex())->getChildByDisplayName(displayName)) {
+        return item->itemName();
+    }
+    return "";
+}
+
+QString FitModel::getInstrumentItemNameForDisplayName(const QString &displayName) {
+    if (auto *item = m_instrumentModel->itemForIndex(QModelIndex())->getChildByDisplayName(displayName)) {
+        return item->itemName();
+    }
+    return "";
+}
 
+ParameterizedItem *FitModel::getSelectedMultiLayerItem() {
+    ParameterizedItem *samplesRoot = m_sampleModel->itemForIndex(QModelIndex());
+    return samplesRoot->getChildByDisplayName(getSelectedSampleName());
+}
+
+ParameterizedItem *FitModel::getSelectedInstrumentItem() {
+    ParameterizedItem *instrumentRoot = m_instrumentModel->itemForIndex(QModelIndex());
+    return instrumentRoot->getChildByDisplayName(getSelectedInstrumentName());
+}
+
+void FitModel::setSelectedSample(const QString &displayName) {
+    ParameterizedItem *selection = getFitSelection();
+    selection->setRegisteredProperty(FitSelectionItem::P_SAMPLE, displayName);
+}
+
+void FitModel::setSelectedInstrument(const QString &displayName) {
+    ParameterizedItem *selection = getFitSelection();
+    selection->setRegisteredProperty(FitSelectionItem::P_INSTRUMENT, displayName);
+}
+
+MinimizerSettingsItem *FitModel::getMinimizerSettings() {
+    return dynamic_cast<MinimizerSettingsItem *>
+            (itemForIndex(QModelIndex())->getChildOfType(Constants::MinimizerSettingsType));
+}
+
+QString FitModel::getMinimizerAlgorithm() {
+    if (auto *item = getMinimizerSettings()) {
+        return item->getRegisteredProperty(MinimizerSettingsItem::P_ALGO).value<ComboProperty>()
+                .getValue();
+    }
+}
+
+QString FitModel::getInputDataPath() {
+    if (auto *item = getInputData()) {
+        return item->getRegisteredProperty(InputDataItem::P_PATH).toString();
+    }
+    return "";
+}
+
+void FitModel::setInputDataPath(const QString &path) {
+    if (auto *item = getInputData()) {
+        item->setRegisteredProperty(InputDataItem::P_PATH, path);
+    }
+}
+
+void FitModel::dataChangedProxy(const QModelIndex & topLeft, const QModelIndex & bottomRight,
+                           const QVector<int> & roles)
+{
+    emit dataChanged(topLeft, bottomRight, roles);
+}
diff --git a/GUI/coregui/Models/FitModel.h b/GUI/coregui/Models/FitModel.h
index c8a115f4c7ab923b0c90d97b986f311f1cfbcc9c..8cbe37f794ecd539cf14bdbcd5868195ee5585aa 100644
--- a/GUI/coregui/Models/FitModel.h
+++ b/GUI/coregui/Models/FitModel.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      coregui/Models/FitModel.h
-//! @brief     Defines class FitModel
+//! @file      coregui/Models/NJobModel.h
+//! @brief     Defines class NJobModel
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,24 +12,85 @@
 //! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
 //
 // ************************************************************************** //
-
 #ifndef FITMODEL_H
 #define FITMODEL_H
 
-
 #include "SessionModel.h"
+#include <QVector>
+
+class QModelIndex;
+class SampleModel;
+class InstrumentModel;
+class FitParameterContainer;
+class FitSelectionItem;
+class SessionModel;
+class MinimizerSettingsItem;
+class InputDataItem;
+
 
 class BA_CORE_API_ FitModel : public SessionModel
 {
     Q_OBJECT
 
 public:
-    explicit FitModel(QObject *parent = 0);
-    virtual ~FitModel(){}
+    //! constructs model with pointers to Sample- und InstrumentModels (read-only access)
+    explicit FitModel(SampleModel *samples, InstrumentModel *instruments, QObject *parent = 0);
 
-};
+    //! returns child of type FitParameterContainer
+    FitParameterContainer *getFitParameterContainer();
+
+    //! returns child fo type FitSelectionItem
+    FitSelectionItem *getFitSelection();
+
+    InputDataItem *getInputData();
+
+    //! returns displayName of currently selected sample, "" when nothing selected
+    QString getSelectedSampleName();
+
+    //! returns displayName of currently selected instrument
+    QString getSelectedInstrumentName();
+
+    //! returns a list of all sample displaynames
+    QStringList getSampleNames();
 
+    //! returns a list of all instrument displaynames
+    QStringList getInstrumentNames();
 
+    //! returning selected MultiLayerItem from SampleModel
+    ParameterizedItem *getSelectedMultiLayerItem();
 
+    //! returning selected InstrumentItem from InstrumentModel
+    ParameterizedItem *getSelectedInstrumentItem();
+
+    //! set sample selection
+    void setSelectedSample(const QString &displayName);
+
+    //! set instrument selection
+    void setSelectedInstrument(const QString &displayName);
+
+    //! get item name when display name is known
+    QString getSampleItemNameForDisplayName(const QString &displayName);
+    QString getInstrumentItemNameForDisplayName(const QString &displayName);
+
+    //! return minimizer settings item
+    MinimizerSettingsItem *getMinimizerSettings();
+
+    QString getMinimizerAlgorithm();
+
+    QString getInputDataPath();
+
+    void setInputDataPath(const QString &path);
+public slots:
+    //! callback for changes made on children of root_item, propagate forward
+    void dataChangedProxy(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+                          const QVector<int> &roles = QVector<int> ());
+
+private:
+    SampleModel *m_sampleModel;
+    InstrumentModel *m_instrumentModel;
+
+    //! get a list of display names for given model - we use them to identify items
+    QStringList retrieveDisplayNames(SessionModel *model, const QString &type);
+};
 
 #endif
diff --git a/GUI/coregui/Models/FitParameterItem.cpp b/GUI/coregui/Models/FitParameterItem.cpp
deleted file mode 100644
index be2591a218e11c7cbe7c7279179e764b064b7e89..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/FitParameterItem.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Models/FitParameterItem.cpp
-//! @brief     Implements class FitParameterItem
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "FitParameterItem.h"
-
-const QString FitParameterItem::P_MIN = "Min";
-const QString FitParameterItem::P_MAX = "Max";
-const QString FitParameterItem::P_VALUE = "Value";
-const QString FitParameterItem::P_USE = "Use";
-
-FitParameterItem::FitParameterItem(ParameterizedItem *parent)
-    : ParameterizedItem(Constants::FitParameterType, parent)
-{
-    registerProperty(P_NAME, Constants::FitParameterType);
-    registerProperty(P_MIN, 0.0);
-    registerProperty(P_MAX, 10.0);
-    registerProperty(P_VALUE, 5.0);
-    registerProperty(P_USE, true);
-}
-
-void FitParameterItem::setParNames(QStringList par_names)
-{
-    m_par_names = par_names;
-}
-
-QStringList FitParameterItem::getParNames()
-{
-    return m_par_names;
-}
-
-
diff --git a/GUI/coregui/Models/FitParameterItem.h b/GUI/coregui/Models/FitParameterItem.h
deleted file mode 100644
index f1b4980cc761b5f6e2b31755af9f7c382ebae0b0..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/FitParameterItem.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Models/FitParameterItem.h
-//! @brief     Defines class FitParameterItem
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef FITPARAMETERITEM_H
-#define FITPARAMETERITEM_H
-
-#include "ParameterizedItem.h"
-
-
-class BA_CORE_API_ FitParameterItem : public ParameterizedItem
-{
-    Q_OBJECT
-public:
-    static const QString P_MIN;
-    static const QString P_MAX;
-    static const QString P_VALUE;
-    static const QString P_USE;
-    explicit FitParameterItem(ParameterizedItem *parent=0);
-    virtual ~FitParameterItem(){}
-
-    void setParNames(QStringList par_names);
-    QStringList getParNames();
-private:
-    QStringList m_par_names;
-};
-
-
-// bool fixed, start_value, min, max, step
-
-#endif
-
diff --git a/GUI/coregui/Models/FitParameterItems.cpp b/GUI/coregui/Models/FitParameterItems.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94836f3af4050892c6d144053a712470a85e0296
--- /dev/null
+++ b/GUI/coregui/Models/FitParameterItems.cpp
@@ -0,0 +1,80 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Models/NJobModel.cpp
+//! @brief     Implements class NJobModel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FitParameterItems.h"
+#include "ComboProperty.h"
+
+FitParameterContainer::FitParameterContainer(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::FitParameterContainerType, parent)
+{
+    addToValidChildren(Constants::FitParameterType);
+}
+
+
+const QString FitParameterItem::P_USE = "Use";
+const QString FitParameterItem::P_INIT = "Starting Value";
+const QString FitParameterItem::P_MIN = "Min";
+const QString FitParameterItem::P_MAX = "Max";
+
+FitParameterItem::FitParameterItem(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::FitParameterType, parent)
+{
+    registerProperty(P_USE, true);
+    registerProperty(P_INIT, 0.0);
+    registerProperty(P_MIN, 0.0);
+    registerProperty(P_MAX, 0.0);
+    addToValidChildren(Constants::FitParameterLinkType);
+}
+
+
+
+const QString FitParameterLinkItem::P_LINK = "Link";
+
+FitParameterLinkItem::FitParameterLinkItem(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::FitParameterLinkType, parent)
+{
+    registerProperty(P_LINK, "");
+}
+
+
+const QString FitSelectionItem::P_SAMPLE = "Sample";
+const QString FitSelectionItem::P_INSTRUMENT = "Instrument";
+
+FitSelectionItem::FitSelectionItem(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::FitSelectionType, parent)
+{
+    registerProperty(P_SAMPLE, "");
+    registerProperty(P_INSTRUMENT, "");
+}
+
+const QString MinimizerSettingsItem::P_ALGO = "Algorithm";
+
+MinimizerSettingsItem::MinimizerSettingsItem(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::MinimizerSettingsType, parent)
+{
+    ComboProperty algo;
+    algo << "Migrad" << "Simplex" << "Combined" << "Scan" << "Fumili";
+    registerProperty(P_ALGO, algo.getVariant());
+}
+
+const QString InputDataItem::P_PATH = "Path";
+
+InputDataItem::InputDataItem(ParameterizedItem *parent)
+    : ParameterizedItem(Constants::InputDataType, parent)
+{
+    registerProperty(P_PATH, "");
+}
+
+
diff --git a/GUI/coregui/Models/FitParameterItems.h b/GUI/coregui/Models/FitParameterItems.h
new file mode 100644
index 0000000000000000000000000000000000000000..10d04df1d71bb3ce8f88cbf0359fab519e27364e
--- /dev/null
+++ b/GUI/coregui/Models/FitParameterItems.h
@@ -0,0 +1,73 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Models/NJobModel.h
+//! @brief     Defines class NJobModel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+#ifndef FITPARAMETERITEMS_H
+#define FITPARAMETERITEMS_H
+
+#include "ParameterizedItem.h"
+
+class BA_CORE_API_ FitParameterContainer : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    explicit FitParameterContainer(ParameterizedItem *parent=0);
+};
+
+class BA_CORE_API_ FitParameterItem : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    static const QString P_USE;
+    static const QString P_INIT;
+    static const QString P_MIN;
+    static const QString P_MAX;
+    explicit FitParameterItem(ParameterizedItem *parent=0);
+};
+
+
+class BA_CORE_API_ FitParameterLinkItem : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    static const QString P_LINK;
+    explicit FitParameterLinkItem(ParameterizedItem *parent=0);
+};
+
+
+class BA_CORE_API_ FitSelectionItem : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    static const QString P_SAMPLE;
+    static const QString P_INSTRUMENT;
+    explicit FitSelectionItem(ParameterizedItem *parent=0);
+};
+
+class BA_CORE_API_ MinimizerSettingsItem : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    static const QString P_ALGO;
+    explicit MinimizerSettingsItem(ParameterizedItem *parent=0);
+};
+
+class BA_CORE_API_ InputDataItem : public ParameterizedItem
+{
+    Q_OBJECT
+public:
+    static const QString P_PATH;
+    explicit InputDataItem(ParameterizedItem *parent=0);
+};
+
+#endif
diff --git a/GUI/coregui/Models/FitParameterModel.cpp b/GUI/coregui/Models/FitParameterModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cb8f12767abf03e3b8f81039056b9133cec49bae
--- /dev/null
+++ b/GUI/coregui/Models/FitParameterModel.cpp
@@ -0,0 +1,169 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Models/FitModel.cpp
+//! @brief     Implements class FitModel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FitParameterModel.h"
+#include "SessionModel.h"
+#include "FitModel.h"
+#include "FitParameterItems.h"
+#include "FitParameterWidget.h"
+
+#include <QMimeData>
+
+
+
+FitParameterModel::FitParameterModel(FitModel *fitmodel, QWidget *parent)
+    : SessionModel("FitParameterModel", parent)
+    , m_columnNames(new QMap<int, QString>())
+{
+    setRootItem(fitmodel->itemForIndex(QModelIndex())->
+            getChildOfType(Constants::FitParameterContainerType));
+    setMaxColumns(5);
+    m_columnNames->insert(0, FitParameterItem::P_NAME);
+    m_columnNames->insert(1, FitParameterItem::P_USE);
+    m_columnNames->insert(3, FitParameterItem::P_MIN);
+    m_columnNames->insert(2, FitParameterItem::P_INIT);
+    m_columnNames->insert(4, FitParameterItem::P_MAX);
+}
+
+FitParameterModel::~FitParameterModel()
+{
+    setRootItem(0);
+    delete m_columnNames;
+}
+
+ParameterizedItem *FitParameterModel::addParameter()
+{
+    return insertNewItem(Constants::FitParameterType, indexOfItem(itemForIndex(QModelIndex())));
+}
+
+QModelIndex FitParameterModel::itemForLink(const QString &link) const
+{
+    for (int i=0; i<rowCount(QModelIndex()); i++){
+        int rowcount = rowCount(index(i,0,QModelIndex()));
+        for (int j = 0; j < rowcount; j++) {
+            QModelIndex curIndex = index(j,0,index(i,0,QModelIndex()));
+            QString value = itemForIndex(curIndex)
+                    ->getRegisteredProperty(FitParameterLinkItem::P_LINK).toString();
+            if (value == link)
+                return curIndex;
+        }
+    }
+    return QModelIndex();
+}
+
+Qt::ItemFlags FitParameterModel::flags(const QModelIndex & index) const
+{
+    Qt::ItemFlags returnVal = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+    if (index.isValid() && index.parent() == QModelIndex()) {
+        if (index.column() == 0)
+            returnVal |= Qt::ItemIsDropEnabled;
+        else
+            returnVal |= Qt::ItemIsEditable;
+    } else if (!index.isValid()) {
+        returnVal |= Qt::ItemIsDropEnabled;
+    }
+    return returnVal;
+}
+
+QStringList FitParameterModel::mimeTypes() const
+{
+    QStringList types;
+    types << FitParameterWidget::MIME_TYPE;
+    return types;
+}
+
+bool FitParameterModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
+                                        int row, int column, const QModelIndex &parent) const
+{
+    Q_UNUSED(action);
+    Q_UNUSED(row);
+    Q_UNUSED(parent);
+    if (column > 0)
+        return false;
+    QString link = QString::fromLatin1(data->data(FitParameterWidget::MIME_TYPE)).split("#")[0];
+    QModelIndex cur = itemForLink(link);
+    return !cur.isValid();
+}
+
+Qt::DropActions FitParameterModel::supportedDropActions() const
+{
+    return Qt::CopyAction | Qt::MoveAction;
+}
+
+bool FitParameterModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
+                                     int column, const QModelIndex &parent)
+{
+    if (action == Qt::IgnoreAction) return true;
+    if (column > 0) return true;
+    QStringList parts = QString::fromLatin1(data->data(FitParameterWidget::MIME_TYPE))
+            .split("#");
+    if (parts.size() != 2) return true;
+    QModelIndex cur = parent;
+    if (!parent.isValid()) {
+        auto newlink = addParameter();
+        double value = parts[1].toDouble();
+        newlink->setRegisteredProperty(FitParameterItem::P_INIT, value);
+        cur = indexOfItem(newlink);
+    }
+    auto link = insertNewItem(Constants::FitParameterLinkType, cur, row);
+    if (link) link->setRegisteredProperty(FitParameterLinkItem::P_LINK, parts[0]);
+    emit dataChanged(cur, cur);
+    return true;
+}
+
+QVariant FitParameterModel::data(const QModelIndex & index, int role) const
+{
+    if ( !index.isValid() || index.column() < 0 || index.column() >= 5) {
+        return QVariant();
+    }
+    if (ParameterizedItem *item = itemForIndex(index)) {
+        if (role == Qt::DisplayRole || role == Qt::EditRole) {
+            if (item->parent() != itemForIndex(QModelIndex()))
+            {
+                if (index.column() == 0)
+                    return item->getRegisteredProperty(FitParameterLinkItem::P_LINK);
+                else
+                    return QVariant();
+            }
+            if (index.column() == 0)
+                return item->itemName();
+            else
+                return item->getRegisteredProperty(m_columnNames->value(index.column()));
+        }
+    }
+    return QVariant();
+}
+
+bool FitParameterModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (!index.isValid())
+        return false;
+    if (ParameterizedItem *item = itemForIndex(index)) {
+        if (role == Qt::EditRole && index.column() > 0 && index.column() < 5) {
+            item->setRegisteredProperty(m_columnNames->value(index.column()), value);
+            emit dataChanged(index, index);
+            return true;
+        }
+    }
+    return false;
+}
+
+QVariant FitParameterModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+        return m_columnNames->value(section);
+    }
+    return QVariant();
+}
diff --git a/GUI/coregui/Models/FitParameterModel.h b/GUI/coregui/Models/FitParameterModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1e30864a93d60f4468d7c27a628d6c42eee0ae3
--- /dev/null
+++ b/GUI/coregui/Models/FitParameterModel.h
@@ -0,0 +1,56 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Models/FitModel.h
+//! @brief     Defines class FitModel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef FITPARAMETERMODEL_H
+#define FITPARAMETERMODEL_H
+
+#include "WinDllMacros.h"
+#include "SessionModel.h"
+#include <QMap>
+
+class FitModel;
+class QModelIndex;
+class QParameterizedItem;
+
+
+class BA_CORE_API_ FitParameterModel : public SessionModel
+{
+    Q_OBJECT
+
+public:
+    explicit FitParameterModel(FitModel *fitmodel, QWidget *parent);
+    ~FitParameterModel();
+    QModelIndex itemForLink(const QString &link) const;
+
+    Qt::ItemFlags flags(const QModelIndex & index) const Q_DECL_OVERRIDE;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
+    bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE;
+    QStringList mimeTypes() const Q_DECL_OVERRIDE;
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
+    bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
+                             const QModelIndex &parent) const Q_DECL_OVERRIDE;
+    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+    Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE;
+
+public slots:
+    ParameterizedItem *addParameter();
+
+private:
+    QMap<int, QString> *m_columnNames;
+};
+
+
+
+#endif
diff --git a/GUI/coregui/Models/FitProxyModel.cpp b/GUI/coregui/Models/FitProxyModel.cpp
deleted file mode 100644
index 0bd54d2df4650127013cae7681723b5eaa742fd8..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/FitProxyModel.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Models/FitProxyModel.cpp
-//! @brief     Implements class FitProxyModel
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "FitProxyModel.h"
-#include "FitModel.h"
-#include "ParameterizedItem.h"
-#include "FitParameterItem.h"
-#include <QDebug>
-
-
-FitProxyModel::FitProxyModel(QObject *parent)
-    : QAbstractItemModel(parent)
-{
-
-}
-
-void FitProxyModel::setFitModel(FitModel *fitModel)
-{
-    m_fitModel = fitModel;
-}
-
-QVariant FitProxyModel::data(const QModelIndex &index, int role) const
-{
-
-//    if(role == Qt::DisplayRole) {
-//        return QVariant(index.column());
-//    }
-
-//    return QVariant();
-
-//    if (!index.isValid() || index.column() < 0
-//            || index.column() >= columnCount(index)) {
-
-//        qDebug() << "XXXXXXXXX FitProxyModel::data index.isValid(): " << index;
-
-//        return QVariant();
-//    }
-
-    if(!index.isValid())
-    {
-        return QVariant();
-    }
-
-
-    if(index.isValid() && !index.parent().isValid())
-    {
-        //ParameterizedItem
-        if (ParameterizedItem *item = itemForIndex(index)) {
-
-            if(role == Qt::DisplayRole || role == Qt::EditRole) {
-                switch (index.column()) {
-                case 0: return item->itemName();
-                case 1: return item->getRegisteredProperty(FitParameterItem::P_USE);
-                case 2: return item->getRegisteredProperty(FitParameterItem::P_VALUE);
-                case 3: return item->getRegisteredProperty(FitParameterItem::P_MIN);
-                case 4: return item->getRegisteredProperty(FitParameterItem::P_MAX);
-                default: return QVariant();
-                }
-            }
-        }
-    }
-
-    if(index.isValid() && index.parent().isValid())
-    {
-        //description
-        if (FitParameterItem *item = dynamic_cast<FitParameterItem *>(itemForIndex(index.parent()))) {
-            if(item->getParNames().size() >0)
-            {
-                return QVariant(item->getParNames().at(0));
-            }
-        }
-    }
-
-    return QVariant();
-}
-
-int FitProxyModel::rowCount(const QModelIndex &parentIndex) const
-{
-    if(parentIndex.isValid())
-    {
-        return 0;
-    }
-
-    if(parentIndex.isValid() && parentIndex.parent().isValid())
-    {
-//        if (FitParameterItem *item = dynamic_cast<FitParameterItem *>(itemForIndex(index.parent()))) {
-//            return item->getParNames().size();
-//        }
-
-        return 1;
-    }
-
-
-    int counter = 0;
-
-    if(m_fitModel)
-    {
-        for( int i_row = 0; i_row < m_fitModel->rowCount( parentIndex ); ++i_row) {
-            QModelIndex itemIndex = m_fitModel->index( i_row, 0, parentIndex );
-
-            if (ParameterizedItem *item = m_fitModel->itemForIndex(itemIndex)){
-                Q_UNUSED(item);
-                counter++;
-            }
-        }
-    }
-
-    return counter;
-}
-
-int FitProxyModel::columnCount(const QModelIndex &parentIndex) const
-{
-    if(!parentIndex.isValid())
-    {
-        return 5;
-    }
-
-    if(parentIndex.isValid() && !parentIndex.parent().isValid())
-    {
-        return 1;
-    }
-
-    return 0;
-}
-
-QModelIndex FitProxyModel::index(int row, int column,
-                                 const QModelIndex &parentIndex) const
-{
-    ParameterizedItem *parent_item = m_fitModel->itemForIndex(parentIndex);
-    if (ParameterizedItem *item = parent_item->childAt(row)) {
-        return createIndex(row, column, item);
-    }
-    return QModelIndex();
-}
-
-QModelIndex FitProxyModel::parent(const QModelIndex &/*child*/) const
-{
-    /*if (!child.isValid()) return QModelIndex();
-    if (ParameterizedItem *child_item = itemForIndex(child)) {
-        if (ParameterizedItem *parent_item = child_item->parent()) {
-
-            if (ParameterizedItem *grandparent_item = parent_item->parent())
-            {
-                int row = grandparent_item->rowOfChild(parent_item);
-                return createIndex(row, 0, parent_item);
-            }
-        }
-    }*/
-    return QModelIndex();
-
-}
-
-Qt::ItemFlags FitProxyModel::flags(const QModelIndex &index) const
-{
-    Qt::ItemFlags result_flags = QAbstractItemModel::flags(index);
-    if (index.isValid()) {
-        result_flags |= Qt::ItemIsEnabled |Qt::ItemIsEditable;
-    }
-    else {
-        result_flags |= Qt::ItemIsEditable;
-    }
-    return result_flags;
-}
-
-bool FitProxyModel::setData(const QModelIndex &index,
-                           const QVariant &value, int role)
-{
-    if (!index.isValid()) return false;
-
-
-    if (ParameterizedItem *item = itemForIndex(index)) {
-        if (role==Qt::EditRole) {
-            qDebug() << "FitProxyModel::setData ";
-
-            switch (index.column()) {
-            case 0:
-                item->setItemName(value.toString());
-                break;
-            case 1:
-                item->setRegisteredProperty(FitParameterItem::P_USE, value);
-                break;
-            case 2:
-                item->setRegisteredProperty(FitParameterItem::P_VALUE, value);
-                break;
-            case 3:
-                item->setRegisteredProperty(FitParameterItem::P_MIN, value);
-                break;
-            case 4:
-                item->setRegisteredProperty(FitParameterItem::P_MAX, value);
-                break;
-            default:
-                return false;
-
-            }
-            emit dataChanged(index, index);
-            return true;
-        }
-    }
-    return false;
-}
-
-ParameterizedItem *FitProxyModel::itemForIndex(const QModelIndex &index) const
-{
-    if (index.isValid()) {
-        if (ParameterizedItem *item = static_cast<ParameterizedItem *>(
-                    index.internalPointer()))
-            return item;
-    }
-
-    //ParameterizedItem *item = m_fitModel->itemForIndex(index);
-
-    return 0;
-}
-
-
-
diff --git a/GUI/coregui/Models/FitProxyModel.h b/GUI/coregui/Models/FitProxyModel.h
deleted file mode 100644
index 61c30c142fe46f12f08cde5958cee8ade51fc259..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/FitProxyModel.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Models/FitProxyModel.h
-//! @brief     Defines class FitProxyModel
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef FITPROXYMODEL_H
-#define FITPROXYMODEL_H
-
-
-#include <QAbstractItemModel>
-
-class FitModel;
-class ParameterizedItem;
-
-class BA_CORE_API_ FitProxyModel : public QAbstractItemModel
-{
-    Q_OBJECT
-
-public:
-    explicit FitProxyModel(QObject *parent = 0);
-    virtual ~FitProxyModel(){}
-
-    // overriden methods
-    virtual QVariant data(const QModelIndex &index, int role) const;
-    virtual int rowCount(const QModelIndex &parentIndex) const;
-    virtual int columnCount(const QModelIndex &parentIndex) const;
-    virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex) const;
-    virtual QModelIndex parent(const QModelIndex &child) const;
-    virtual Qt::ItemFlags flags(const QModelIndex &index) const;
-    virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
-    //end if overriden methods
-
-    void setFitModel(FitModel *fitModel);
-    FitModel *getFitModel()
-        { return m_fitModel; }
-
-    ParameterizedItem *itemForIndex(const QModelIndex &index) const;
-
-private:
-    FitModel *m_fitModel;
-
-};
-
-
-
-
-#endif
diff --git a/GUI/coregui/Models/FitSelectorModel.cpp b/GUI/coregui/Models/FitSelectorModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c053a0be6afc8657888bf80e98578faea430738
--- /dev/null
+++ b/GUI/coregui/Models/FitSelectorModel.cpp
@@ -0,0 +1,63 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Models/NJobModel.cpp
+//! @brief     Implements class NJobModel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FitSelectorModel.h"
+#include "FitParameterWidget.h"
+#include <QStandardItem>
+#include <QMimeData>
+#include <QModelIndexList>
+
+QMimeData *FitSelectorModel::mimeData(const QModelIndexList &indexes) const
+{
+    QMimeData *mimeData = new QMimeData();
+    QModelIndex index = indexes.first();
+    if (index.isValid()) {
+        QString path = getPathFromIndex(index);
+        path = path.append("#%1").arg(itemFromIndex(index.sibling(index.row(), 1))
+                                      ->data(Qt::EditRole).toDouble());
+        mimeData->setData(FitParameterWidget::MIME_TYPE, path.toLatin1());
+    }
+    return mimeData;
+}
+
+QString FitSelectorModel::getPathFromIndex(const QModelIndex &index) const
+{
+    if (index.isValid()) {
+        QStringList namePath;
+        QStandardItem *cur = itemFromIndex(index);
+        while (cur) {
+            namePath << cur->text();
+            cur = cur->parent();
+        }
+        std::reverse(namePath.begin(), namePath.end());
+        return namePath.join("/");
+    }
+    return QString();
+}
+
+QStandardItem *FitSelectorModel::getItemFromPath(const QString &path)
+{
+    QStringList parts = path.split("/");
+    QStandardItem *t = invisibleRootItem();
+    for(int i = 0; i < parts.length(); i++) {
+        for (int j = 0; j < t->rowCount(); j++) {
+            if (t->child(j,0)->text() == parts[i]) {
+                t = t->child(j,0);
+                break;
+            }
+        }
+    }
+    return t;
+}
diff --git a/GUI/coregui/Views/FitWidgets/RealDataWidget.h b/GUI/coregui/Models/FitSelectorModel.h
similarity index 54%
rename from GUI/coregui/Views/FitWidgets/RealDataWidget.h
rename to GUI/coregui/Models/FitSelectorModel.h
index 0fdc09feb37890070540ea99cfb05f9c1a67b1c7..ebacb274f19d1e1d46168d7d22db6d523898873a 100644
--- a/GUI/coregui/Views/FitWidgets/RealDataWidget.h
+++ b/GUI/coregui/Models/FitSelectorModel.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      coregui/Views/FitWidgets/RealDataWidget.h
-//! @brief     Defines class RealDataWidget
+//! @file      coregui/Models/NJobModel.h
+//! @brief     Defines class NJobModel
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,19 +12,23 @@
 //! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
 //
 // ************************************************************************** //
+#ifndef FITSELECTORMODEL_H
+#define FITSELECTORMODEL_H
 
-#ifndef REALDATAWIDGET_H
-#define REALDATAWIDGET_H
+#include "WinDllMacros.h"
+#include <QStandardItemModel>
 
-#include <QWidget>
+class QMimeData;
+class QStandardItem;
 
-
-class BA_CORE_API_ RealDataWidget : public QWidget
+class BA_CORE_API_ FitSelectorModel : public QStandardItemModel
 {
     Q_OBJECT
 
 public:
-    RealDataWidget(QWidget *parent = 0);
+    QMimeData *mimeData(const QModelIndexList &indexes) const;
+    QString getPathFromIndex(const QModelIndex &index) const;
+    QStandardItem *getItemFromPath(const QString &path);
 };
 
 #endif
diff --git a/GUI/coregui/Models/ItemFactory.cpp b/GUI/coregui/Models/ItemFactory.cpp
index 3717be0f25e70b8fa49ca8c20abde6db36c86ef3..076c59548c72a23b63fc10e64371cc14b6f45470 100644
--- a/GUI/coregui/Models/ItemFactory.cpp
+++ b/GUI/coregui/Models/ItemFactory.cpp
@@ -38,7 +38,6 @@
 #include "MaterialItem.h"
 #include "RefractiveIndexItem.h"
 #include "MagneticFieldItem.h"
-#include "FitParameterItem.h"
 #include "JobItem.h"
 #include "IntensityDataItem.h"
 #include "AxesItems.h"
@@ -47,6 +46,7 @@
 #include "BeamWavelengthItem.h"
 #include "BeamAngleItems.h"
 #include "MaskItems.h"
+#include "FitParameterItems.h"
 #include <QDebug>
 
 namespace {
@@ -143,8 +143,6 @@ ItemFactory::ItemMap_t initializeItemMap() {
 
     result[Constants::MagneticFieldType] = &createInstance<MagneticFieldItem>;
 
-    result[Constants::FitParameterType] = &createInstance<FitParameterItem>;
-
     result[Constants::JobItemType] = &createInstance<JobItem>;
 
     result[Constants::IntensityDataType] = &createInstance<IntensityDataItem>;
@@ -169,6 +167,13 @@ ItemFactory::ItemMap_t initializeItemMap() {
     result[Constants::EllipseMaskType] = &createInstance<EllipseItem>;
     result[Constants::MaskAllType] = &createInstance<MaskAllItem>;
 
+    result[Constants::FitParameterContainerType] = &createInstance<FitParameterContainer>;
+    result[Constants::FitParameterType] = &createInstance<FitParameterItem>;
+    result[Constants::FitParameterLinkType] = &createInstance<FitParameterLinkItem>;
+    result[Constants::FitSelectionType] = &createInstance<FitSelectionItem>;
+    result[Constants::MinimizerSettingsType] = &createInstance<MinimizerSettingsItem>;
+    result[Constants::InputDataType] = &createInstance<InputDataItem>;
+
     return result;
 }
 }
diff --git a/GUI/coregui/Models/ParameterModelBuilder.h b/GUI/coregui/Models/ParameterModelBuilder.h
index ea1c1df416bea5ac5fc9c62f275426d9259db735..3b57158f624c6c6fc1cf6ef90fbdda0f04171fed 100644
--- a/GUI/coregui/Models/ParameterModelBuilder.h
+++ b/GUI/coregui/Models/ParameterModelBuilder.h
@@ -39,9 +39,10 @@ class ParameterModelBuilder
 public:
 
     static QStandardItemModel *createParameterModel(JobModel *jobModel, JobItem *jobItem);
+    static QStandardItem *iterateSessionModel(SessionModel *sampleModel, const QModelIndex &parentIndex = QModelIndex(), QStandardItem *parentItem = 0);
 
 private:
-    static QStandardItem *iterateSessionModel(SessionModel *sampleModel, const QModelIndex &parentIndex = QModelIndex(), QStandardItem *parentItem = 0);
+
     static QStandardItem *iterateInstrumentModel(InstrumentModel *instrumentModel);
     static QStandardItem *iterateInstrumentItem(InstrumentItem *instrument);
 
diff --git a/GUI/coregui/Models/ParameterizedItem.cpp b/GUI/coregui/Models/ParameterizedItem.cpp
index 7625fbd6d2ff07260fc0587e1460216e35fd6742..2519edded23ebd481dcd8d32eb88e85c26224c59 100644
--- a/GUI/coregui/Models/ParameterizedItem.cpp
+++ b/GUI/coregui/Models/ParameterizedItem.cpp
@@ -37,7 +37,9 @@ ParameterizedItem::ParameterizedItem(QString model_type, ParameterizedItem *pare
     if (mp_parent) {
         mp_parent->insertChildItem(-1, this);
     }
+
     registerProperty(P_PORT, -1).setHidden();
+    setItemName(m_model_type);
 }
 
 ParameterizedItem::~ParameterizedItem()
@@ -421,6 +423,20 @@ QStringList ParameterizedItem::getParameterTreeList(QString prefix) const
     return result;
 }
 
+double ParameterizedItem::getParameterValue(const QString &name) const
+{
+    QString head = getFirstField(name);
+    auto p_child = getChildByDisplayName(head);
+    if (p_child) {
+        return p_child->getParameterValue(stripFirstField(name));
+    }
+    if (isRegisteredProperty(head)) {
+        return getRegisteredProperty(head).toDouble();
+    } else {
+        return 0.0;
+    }
+}
+
 std::string ParameterizedItem::translateParameterName(const QString &par_name) const
 {
     std::ostringstream result;
diff --git a/GUI/coregui/Models/ParameterizedItem.h b/GUI/coregui/Models/ParameterizedItem.h
index a1efb3444ee529924d5c193d425967215ee194aa..32e28d418579a5d7e7c58aa31aa77dc43f983284 100644
--- a/GUI/coregui/Models/ParameterizedItem.h
+++ b/GUI/coregui/Models/ParameterizedItem.h
@@ -85,6 +85,8 @@ public:
     //! Returns a pointer to the first child of the given type
     ParameterizedItem *getChildOfType(QString type) const;
 
+    ParameterizedItem* getChildByDisplayName(const QString &name) const;
+
     //! indicates if the passed item can be set as a child item
     bool acceptsAsChild(const QString &child_name) const;
 
@@ -141,6 +143,9 @@ public:
     //! with this node and prefixes them
     QStringList getParameterTreeList(QString prefix = "") const;
 
+    //! retrieve value of given parameter name
+    double getParameterValue(const QString &name) const;
+
     //! translates the given parameter name to a domain parameter name
     //! name should start with a child/subitem name or be a direct parameter name
     std::string translateParameterName(const QString &par_name) const;
@@ -181,8 +186,6 @@ protected:
 
     void addParameterTranslator(const IParameterTranslator &translator);
 
-    ParameterizedItem* getChildByDisplayName(const QString &name) const;
-
     QStringList m_registered_properties;
 
     QMap<QString, PropertyAttribute> m_property_attribute;
diff --git a/GUI/coregui/Models/SessionModel.cpp b/GUI/coregui/Models/SessionModel.cpp
index 3b571c59073881f38417ac60048d2c694f8973dc..a5697b8731a9374fea471d97cceac59a95923b1d 100644
--- a/GUI/coregui/Models/SessionModel.cpp
+++ b/GUI/coregui/Models/SessionModel.cpp
@@ -41,6 +41,7 @@ const QString NON_EXISTING_SUBITEM = "NON_EXISTING_SUBITEM";
 
 SessionModel::SessionModel(QString model_tag, QObject *parent)
     : QAbstractItemModel(parent), m_root_item(0), m_name("DefaultName"), m_model_tag(model_tag)
+    , m_maxColumns(MAX_COLUMNS)
     , m_iconProvider(0)
     , m_messageService(0)
 {
@@ -70,7 +71,7 @@ Qt::ItemFlags SessionModel::flags(const QModelIndex &index) const
 
 QVariant SessionModel::data(const QModelIndex &index, int role) const
 {
-    if (!m_root_item || !index.isValid() || index.column() < 0 || index.column() >= MAX_COLUMNS) {
+    if (!m_root_item || !index.isValid() || index.column() < 0 || index.column() >= m_maxColumns) {
         return QVariant();
     }
     if (ParameterizedItem *item = itemForIndex(index)) {
@@ -115,12 +116,12 @@ int SessionModel::columnCount(const QModelIndex &parent) const
 {
     if (parent.isValid() && parent.column() != 0)
         return 0;
-    return MAX_COLUMNS;
+    return m_maxColumns;
 }
 
 QModelIndex SessionModel::index(int row, int column, const QModelIndex &parent) const
 {
-    if (!m_root_item || row < 0 || column < 0 || column >= MAX_COLUMNS
+    if (!m_root_item || row < 0 || column < 0 || column >= m_maxColumns
         || (parent.isValid() && parent.column() != 0))
         return QModelIndex();
     ParameterizedItem *parent_item = itemForIndex(parent);
@@ -839,3 +840,7 @@ void SessionModel::report_error(const QString &error_type, const QString &messag
         throw GUIHelpers::Error(error_type + QString(" ") + message);
     }
 }
+
+ParameterizedItem* SessionModel::rootItem() const{
+    return m_root_item;
+}
diff --git a/GUI/coregui/Models/SessionModel.h b/GUI/coregui/Models/SessionModel.h
index e87c73899ac3ad7d8f2ac5903f4652bc09788947..22212ab4a55ff15c4eb037910d6693c4494c68cd 100644
--- a/GUI/coregui/Models/SessionModel.h
+++ b/GUI/coregui/Models/SessionModel.h
@@ -84,7 +84,7 @@ public:
                          const QModelIndex &parent) const;
     virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
                       const QModelIndex &parent);
-    // End overriden methods from QAbstractItemModel
+    // End overridden methods from QAbstractItemModel
 
     QModelIndex indexOfItem(ParameterizedItem *item) const;
     ParameterizedItem *insertNewItem(QString model_type, const QModelIndex &parent = QModelIndex(),
@@ -104,6 +104,7 @@ public:
     // Sets mimedata pointer of item being dragged
     void setDraggedItemType(const QString &type);
 
+    // Returns root item if index is not valid
     ParameterizedItem *itemForIndex(const QModelIndex &index) const;
 
     void readFrom(QXmlStreamReader *reader);
@@ -127,12 +128,19 @@ public:
 
     virtual void initFrom(SessionModel *model, ParameterizedItem *parent);
 
+
+
 public slots:
     void onItemPropertyChange(const QString &property_name, const QString &name = QString());
 
 protected:
+    // subclasses my wish to change the column count or the root item itself
+    void setMaxColumns(int maxColumns) {m_maxColumns = maxColumns;}
+    void setRootItem(ParameterizedItem *root) {m_root_item = root;}
 
 private:
+    ParameterizedItem* rootItem() const;
+
     ParameterizedItem *insertNewItem(QString model_type, ParameterizedItem *parent, int row = -1,
                                      ParameterizedItem::PortInfo::EPorts port
                                      = ParameterizedItem::PortInfo::DEFAULT);
@@ -151,6 +159,7 @@ private:
     QString m_dragged_item_type;
     QString m_name;      //!< model name
     QString m_model_tag; //!< model tag (SampleModel, InstrumentModel)
+    int m_maxColumns;
     IconProvider *m_iconProvider;
     WarningMessageService *m_messageService;
 };
diff --git a/GUI/coregui/Models/item_constants.h b/GUI/coregui/Models/item_constants.h
index 887a0e5ce7e92b7b9d49de31758b90b4b4d38d83..fc825bba1730d9add0d53bb213a0678b2ae054e7 100644
--- a/GUI/coregui/Models/item_constants.h
+++ b/GUI/coregui/Models/item_constants.h
@@ -115,7 +115,12 @@ const ModelType RefractiveIndexType = "RefractiveIndex";
 
 const ModelType MagneticFieldType = "MagneticField";
 
+const ModelType FitParameterContainerType = "FitParameterContainer";
 const ModelType FitParameterType = "FitParameter";
+const ModelType FitParameterLinkType = "FitParameterLink";
+const ModelType FitSelectionType = "FitSelection";
+const ModelType MinimizerSettingsType = "Minimizer Settings";
+const ModelType InputDataType = "Input Data";
 
 const ModelType JobItemType = "JobItem";
 const ModelType IntensityDataType = "IntensityData";
diff --git a/GUI/coregui/Views/FitView.cpp b/GUI/coregui/Views/FitView.cpp
index f4ff62029b4973f8f7dbe87097945835ba0c9243..98612201f309d85ba684bb4dae5fb1fe63ea68d5 100644
--- a/GUI/coregui/Views/FitView.cpp
+++ b/GUI/coregui/Views/FitView.cpp
@@ -14,46 +14,152 @@
 // ************************************************************************** //
 
 #include "FitView.h"
-#include "RealDataWidget.h"
-#include "FitParameterWidget.h"
 #include "RunFitWidget.h"
-#include "FitToolBar.h"
-#include "qdebug.h"
 #include "mainwindow.h"
-#include <QTabWidget>
+#include "FitSettingsWidget.h"
+#include "FitModel.h"
+#include "ImportDataWidget.h"
+#include "projectmanager.h"
 #include <QVBoxLayout>
+#include <QTabWidget>
+#include <QToolBar>
+#include <QListWidget>
 
+// REMARKS:
 
-FitView::FitView(FitProxyModel *fitProxyModel, MainWindow *mainWindow)
-    : QWidget(mainWindow)
-    , m_fitProxyModel(fitProxyModel)
-{
+// minimizer settings will come later
 
-    m_realDataWidget = new RealDataWidget();
-    m_fitParameterWidget = new FitParameterWidget(m_fitProxyModel);
-    m_runFitWidget = new RunFitWidget();
+// no narrow toolbar
 
-    m_tabWidget = new QTabWidget();
-    m_tabWidget->insertTab(REAL_DATA, m_realDataWidget, tr("Real Data"));
-    m_tabWidget->insertTab(FIT_PARAMETER, m_fitParameterWidget, tr("Fit Parameters"));
-    m_tabWidget->insertTab(RUN_FIT, m_runFitWidget, tr("Run Fit"));
 
-    connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onChangeTabWidget(int)));
 
 
-    m_toolBar = new FitToolBar(this);
 
-    QVBoxLayout *mainLayout = new QVBoxLayout;
-    mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
-    mainLayout->addWidget(m_toolBar);
-    mainLayout->addWidget(m_tabWidget);
-    mainLayout->setMargin(0);
-    mainLayout->setSpacing(0);
-    setLayout(mainLayout);
-}
+// ------------------------------------------------------------------------------------------------
+// FIXME_DAVID
+// ------------------------------------------------------------------------------------------------
+
+
+
+
+// FitParameterWidget --> Refactor ContextMenu part. m_contextMenu should not be member variable.
+// * It has to be dynamically generated on right click. See MaskEditorActions::onItemContextMenuRequest
+// * Think of creating separate class and isolating all actions activity there.
+//   See MaskEditor <--> MaskEditorActions (FitParameterWIdget <---> FitParameterWidgetActions ?)
+// * Context menu should be always the same --> if given action is not available for underlying item,
+//   the action should be disabled. See MaskEditorActions::initItemContextMenu(QMenu &menu)
+// * Use horizonal delimeter in context menu:
+// > Remove parameter   <---- this guy can be disabled(gray) if there is no appropriate item beneath
+// > ----------------   <---- horizontal delimeter
+// > Add parameter
+
+
+// FitParameterWidget --> Add context menu to right m_selectorTreeView
+// * There should be
+// > create fit parameter
+// > add to existing parameter --> and then dynamic menu of existing fit parameters
+
+
+
+
+
+// FitParameterWidget -> Refactor FitParameterWidget::buildTree and buildSelectorModel()
+// Part of code should be moved into separate class with static method, similar to
+// GUI/coregui/Models/ParameterModelBuilder; you can create there SelectorModelBuilder class
+// which will act on QStringList (for example) and return QStandardItemModel
+
+
+// FitParameterItem and its TreeView -> Additional functionality --> TO DISCUSS
+// So we need following parameters
+// Name  |  Use  |  Starting Value | Min | Max
+// Could you please try to do the following:
+// * Use should be QComboBox with values "free", "fixed", "limited"
+// When the user selects "fixed" -> than Min,Max fields become disabled (gray and non-editable)
+// When the user selects "free" -> the same
+// When the user selects "limited" -> than Min,Max fields become active
+
 
+// FitParameterItem and its TreeView -> Additional functionality --> TO DISCUSS
+// Please make tooltips for tree header
+// "parameter name", "parameter mode: fixed, limited in the interval or free", "starting value of the parameter", "lower parameter bound", "upper parameter bound"
 
-void FitView::onChangeTabWidget(int /*index*/)
+
+// ------------------------------------------------------------------------------------------------
+
+// RunFitWidget --> Refactoring -> It should not act on observer, always address to FitProgressWidget
+// * For example, m_interval_slider should be connected with FitProgressWidget, and not observer
+// * In the method RunFitWidget::onStartClicked() something like m_fitprogress->attachFitSuite() should be used
+
+
+// void RunFitManager::runFitting() -> Please do not use short variables FittingWorker *fw = new FittingWorker(m_fitSuite);
+// Use fittingWorker for variable name
+
+// FitProgressWidget --> m_guifitobserver , may be it should be unique_ptr instead of shared_ptr?
+
+// FitProgressWidget, FitObserver --> signal refactoring, ownership --> TO DISCUSS
+// > I fill myself not very comfortable with the idea of heavy OutputData's flying around, especially if they are flying separately (real data, chi_squared)
+// Possible solution:
+// FitObserver reports through signal:
+// - There is a log String ready
+// - There is data to plot ready (they seats in unique_pt, owned by FitObserver)
+// --> And then FitSuite, take it out (throgh std::move, or some other trick) and permits FitObserver to conrinue
+
+
+// RunFitWidget -> intervalSlider -> TO DISCUSS
+// * I agree that slider is very nice and impressive, but
+// * What if I have very fast simulation (simple model), and I want to update every 1000 iteration?
+//   It's not nice to have a slider up to 1000.
+// * Can we replace a slider with some DropDownBox (every 1 iteration, every 5, 10 and 1000)
+//   Such boxes also have possibility to type inside any custom number too
+// * What if I want to update plotting every 100 iterations, and output every 10. Do I need this actually? :)
+// Alternatives ?
+
+
+// ------------------------------------------------------------------------------------------------
+// ImportExperimentalData --> To discuss
+
+
+
+
+
+// ------------------------------------------------------------------------------------------------
+
+
+FitView::FitView(MainWindow *mainWindow)
+    : QWidget(mainWindow)
+    , m_tabs(new QTabWidget)
+    , m_importDataWidget(new ImportDataWidget(mainWindow->getFitModel(), this))
+    , m_fitSettingsWidget(new FitSettingsWidget(mainWindow->getFitModel(), this))
+    , m_runFitWidget(new RunFitWidget(mainWindow->getFitModel(), this))
 {
+    QVBoxLayout *layout = new QVBoxLayout;
+    m_tabs->setStyleSheet("QTabBar::tab { height: 40px; }");
+    m_tabs->addTab(m_importDataWidget ,QIcon(":/images/main_home.png"), "Import Experimental Data");
+    m_tabs->addTab(m_fitSettingsWidget, "Fit Settings");
+    m_tabs->addTab(m_runFitWidget, "Run Fit");
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    QToolBar *toolBar = new QToolBar();
+    toolBar->addAction("Add Fit Workspace");
+    toolBar->addSeparator();
+    toolBar->addAction("Fit Selection");
+    toolBar->addSeparator();
+    QListWidget *list = new QListWidget();
+    list->setMinimumSize(100, 400);
+    list->setMaximumWidth(128);
+    list->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+    m_tabs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+    QHBoxLayout *horizontalLayout = new QHBoxLayout;
+    horizontalLayout->addWidget(list);
+    horizontalLayout->addWidget(m_tabs);
+    layout->addWidget(toolBar);
+    layout->addLayout(horizontalLayout);
+    setLayout(layout);
+
+    connect(mainWindow->getProjectManager(), SIGNAL(projectOpened()),
+            m_fitSettingsWidget, SLOT(onUpdateGUI()));
+    connect(mainWindow->getProjectManager(), SIGNAL(projectOpened()),
+            m_importDataWidget, SLOT(onUpdateGUI()));
 
+    m_tabs->setCurrentIndex(1);
 }
diff --git a/GUI/coregui/Views/FitView.h b/GUI/coregui/Views/FitView.h
index d7cb1989fa3f131a346ac961eb3743e2df0e87c2..bc775507a4e5ec8050d26e43d3b9c27c10688485 100644
--- a/GUI/coregui/Views/FitView.h
+++ b/GUI/coregui/Views/FitView.h
@@ -16,41 +16,29 @@
 #ifndef FITVIEW_H
 #define FITVIEW_H
 
-#include "FitProxyModel.h"
-#include "WinDllMacros.h"
+#include <WinDllMacros.h>
 #include <QWidget>
 
-
 class MainWindow;
 class QTabWidget;
-class RealDataWidget;
-class FitParameterWidget;
+class ImportDataWidget;
+class FitSettingsWidget;
 class RunFitWidget;
-class FitToolBar;
 
 class BA_CORE_API_ FitView : public QWidget
 {
     Q_OBJECT
 
 public:
-    enum ETabViewId { REAL_DATA, FIT_PARAMETER, RUN_FIT};
-    FitView(FitProxyModel *fitProxyModel, MainWindow *mainWindow);
-
-
-public slots:
-    void onChangeTabWidget(int index);
+    //! View containing tabs for fitting
+    FitView(MainWindow *window);
 
 private:
-
-    QTabWidget *m_tabWidget;
-    RealDataWidget *m_realDataWidget;
-    FitParameterWidget *m_fitParameterWidget;
+    QTabWidget *m_tabs;
+    ImportDataWidget *m_importDataWidget;
+    FitSettingsWidget *m_fitSettingsWidget;
     RunFitWidget *m_runFitWidget;
-    FitToolBar *m_toolBar;
-
-    FitProxyModel *m_fitProxyModel;
 
 };
 
-
-#endif // SIMULATIONVIEW_H
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp b/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp
index 158c1aa006d9aec8dc24b5ae292987feac57a777..504db660fbdd480a85f638a66bec1bd67ec2eec0 100644
--- a/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp
@@ -14,201 +14,334 @@
 // ************************************************************************** //
 
 #include "FitParameterWidget.h"
-#include "FitParameterItem.h"
-#include <QDebug>
+#include "FitModel.h"
+#include "FitParameterItems.h"
+#include "FitParameterModel.h"
+#include "FitSelectorModel.h"
+#include "DeleteEventFilter.h"
+#include "MinimizerSettingsWidget.h"
+#include "minisplitter.h"
 #include <QVBoxLayout>
-
-
-
-FitParameterWidget::FitParameterWidget(FitProxyModel *fitProxyModel, QWidget *parent)
+#include <QTreeView>
+#include <QSplitter>
+#include <QStringList>
+#include <QStandardItemModel>
+#include <QStandardItem>
+#include <QModelIndex>
+#include <QMenu>
+#include <QAction>
+#include <QItemSelection>
+#include <QItemSelectionModel>
+
+#include <QMimeData>
+#include <QDragEnterEvent>
+
+const QString FitParameterWidget::MIME_TYPE = "application/org.bornagainproject.fittinglink";
+
+FitParameterWidget::FitParameterWidget(FitModel *fitModel, QWidget *parent)
     : QWidget(parent)
-    , m_treeView(0)
-    , m_fitProxyModel(fitProxyModel)
+    , m_fitModel(fitModel)
+    , m_selectorTreeView(new QTreeView())
+    , m_parameterTreeview(new QTreeView())
+    , m_selectorModel(nullptr)
+    , m_parameterModel(nullptr)
+    , m_contextMenu(new QMenu())
+    , m_splitter(new Manhattan::MiniSplitter(this))
+    , m_keyboardFilter(new DeleteEventFilter(this))
 {
 
-    QColor bgColor(255,255,255,255);
-    QPalette palette;
-    palette.setColor(QPalette::Background, bgColor);
-    setAutoFillBackground(true);
-    setPalette(palette);
-
-
-    initFitModel();
-
-    m_fitProxyModel->setFitModel(m_fitModel);
-    m_fitProxyModel->setHeaderData(0, Qt::Horizontal,"Title");
-
-    /*if(m_fitModel)
-    {
-        ParameterizedItem *item1 = m_fitModel->insertNewItem(Constants::FitParameterType);
-        item1->setItemName("par1");
-        item1->setRegisteredProperty(FitParameterItem::P_MIN, 1.0);
-
-        FitParameterItem *item2 = dynamic_cast<FitParameterItem *>(m_fitModel->insertNewItem(Constants::FitParameterType));
-        item2->setItemName("par2");
-
-//        ParameterizedItem *old_item = m_fitModel->itemForIndex(m_fitModel->index(0,0, QModelIndex()));
-//        qDebug() << "FitModel: " << old_item->getRegisteredProperty(FitParameterItem::P_MIN);
-
-//        FitParameterItem *fit_item = dynamic_cast<FitParameterItem *>(m_fitModel->itemForIndex(m_fitModel->index(1,0, QModelIndex())));
-//        qDebug() << "FitModel: " << fit_item->getRegisteredProperty(FitParameterItem::P_MAX);
-
-
-
-    }*/
-
-
-    m_treeView = new QTreeView();
-    m_treeView->setStyleSheet("QTreeView::branch {background: palette(base);}QTreeView::branch:has-siblings:!adjoins-item {border-image: url(:/images/treeview-vline.png) 0;}QTreeView::branch:has-siblings:adjoins-item {border-image: url(:/images/treeview-branch-more.png) 0;}QTreeView::branch:!has-children:!has-siblings:adjoins-item {border-image: url(:/images/treeview-branch-end.png) 0;}QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url(:/images/treeview-branch-closed.png);}QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings  {border-image: none;image: url(:/images/treeview-branch-open.png);}");
-
-
-    //m_parameterModel = createParameterModel(m_fitModel);
-    //connect(m_parameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onModelChanged(QModelIndex,QModelIndex)));
-
-
-
-//    FitProxyModel *fitProxyModel = new FitProxyModel;
-//    qDebug() << fitProxyModel;
-
-
-    int height = this->height();
-    m_treeView->setModel(m_fitProxyModel);
-    m_treeView->setFixedHeight(height);
-    m_treeView->setColumnWidth(0,170);
-    m_treeView->expandAll();
-
+    m_parameterModel = new FitParameterModel(m_fitModel, this);
+
+    QString style(
+    "QTreeView::branch {background: palette(base);}QTreeView::branch:has-siblings:!adjoins-item "
+    "{border-image: url(:/images/treeview-vline.png) 0;}QTreeView::branch:has-siblings:"
+    "adjoins-item {border-image: url(:/images/treeview-branch-more.png) 0;}QTreeView::branch:"
+    "!has-children:!has-siblings:adjoins-item {border-image: "
+    "url(:/images/treeview-branch-end.png) 0;}QTreeView::branch:has-children:!has-siblings:closed"
+    ",QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: "
+    "url(:/images/treeview-branch-closed.png);}QTreeView::branch:open:has-children:!has-siblings,"
+    "QTreeView::branch:open:has-children:has-siblings  {border-image: none;image: "
+    "url(:/images/treeview-branch-open.png);}");
+
+    m_selectorTreeView->setStyleSheet(style);
+    m_selectorTreeView->setDragEnabled(true);
+    m_selectorTreeView->setDragDropMode(QAbstractItemView::DragOnly);
+
+    m_parameterTreeview->setStyleSheet(style);
+    m_parameterTreeview->setAcceptDrops(true);
+    m_parameterTreeview->setDragDropMode(QAbstractItemView::DropOnly);
+    m_parameterTreeview->setModel(m_parameterModel);
+    m_parameterTreeview->setColumnWidth(0, 300);
+    m_parameterTreeview->setColumnWidth(2, 120);
+    m_parameterTreeview->setContextMenuPolicy(Qt::CustomContextMenu);
+    m_parameterTreeview->installEventFilter(m_keyboardFilter);
+
+    m_removeAction =  m_contextMenu->addAction("Remove", this, SLOT(onRemoveParameter()));
+    m_addAction = m_contextMenu->addAction("Add Parameter", m_parameterModel, SLOT(addParameter()));
+
+    /*QSplitter *rightWindow = new QSplitter;
+    rightWindow->setOrientation(Qt::Vertical);
+    rightWindow->addWidget(m_parameterTreeview);
+    m_parameterTreeview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+    auto *minimizersettings = new MinimizerSettingsWidget(m_fitModel, this);
+    rightWindow->addWidget(minimizersettings);
+    rightWindow->setSizes(QList<int>() << 3000 << 1000);*/
+
+    m_splitter->addWidget(m_selectorTreeView);
+    m_splitter->addWidget(m_parameterTreeview);
+    m_splitter->setSizes(QList<int>() << 10000 << 20000);
 
     QVBoxLayout *vlayout = new QVBoxLayout(this);
     vlayout->setMargin(0);
     vlayout->setSpacing(0);
-    vlayout->addWidget(m_treeView);
-    vlayout->addStretch();
+    vlayout->addWidget(m_splitter);
     this->setLayout(vlayout);
 
+    // update selector when sample model changes - more jobs to be done here
+    //connect(m_sampleModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+    //        this, SLOT(updateSelector()));
 
-//    QModelIndex idx = m_parameterModel->invisibleRootItem()->index();
-//    for (int i=0; i<m_parameterModel->rowCount(); i++){
-//    if (m_parameterModel->item(i,0)->hasChildren()){
+    connect(m_parameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+            m_fitModel, SLOT(dataChangedProxy(QModelIndex,QModelIndex,QVector<int>)));
 
-//            m_treeView->setFirstColumnSpanned(0, m_parameterModel->item(i,0)->index(), true);
-//            m_treeView->setFirstColumnSpanned(1, m_parameterModel->item(i,0)->index(), true);
-//        }
-//    }
+    // setup firstcolumnspanning
+    connect(m_parameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+            this, SLOT(spanParameters()));
 
+    // make context menu availabe
+    connect(m_parameterTreeview, SIGNAL(customContextMenuRequested(const QPoint &)),
+            this, SLOT(onCustomContextMenu(const QPoint &)));
 
-}
+    // event from keyeventfilter
+    connect(m_keyboardFilter, SIGNAL(removeItem()), this, SLOT(removeSelectedItem()));
 
-QStandardItemModel *FitParameterWidget::createParameterModel(FitModel *fitModel)
-{
-    QStandardItemModel *result(0);
-    result = new QStandardItemModel();
-    result->setHorizontalHeaderItem( 0, new QStandardItem( "Property" ) );
-    result->setHorizontalHeaderItem( 1, new QStandardItem( "Use" ) );
-    result->setHorizontalHeaderItem( 2, new QStandardItem( "Value" ) );
-    result->setHorizontalHeaderItem( 3, new QStandardItem( "Min" ) );
-    result->setHorizontalHeaderItem( 4, new QStandardItem( "Max" ) );
-
-
-    iterateSessionModel(fitModel, QModelIndex(), result);
-//    if(standardItem)
-//    {
-//        result->appendRow(standardItem);
-//    }
-
-    return result;
-}
+    // select by doubleclick
+    connect(m_selectorTreeView, SIGNAL(doubleClicked(QModelIndex)),
+            this, SLOT(onDoubleclick(QModelIndex)));
 
-QStandardItemModel *FitParameterWidget::iterateSessionModel(FitModel *fitModel, const QModelIndex &parentIndex, QStandardItemModel *parentItem)
-{
-    Q_ASSERT(fitModel);
-
-    if(!parentIndex.isValid()) {
-        qDebug() << "Dumping model";
-    }
-
-
-    for( int i_row = 0; i_row < fitModel->rowCount( parentIndex ); ++i_row) {
-        QModelIndex itemIndex = fitModel->index( i_row, 0, parentIndex );
 
+    connectParameterView();
 
+}
 
-        if (ParameterizedItem *item = fitModel->itemForIndex(itemIndex)){
-
-
-            qDebug() << "FitParameterWidget::iterateSessionModel: " << item->itemName() << item->getRegisteredProperty(FitParameterItem::P_MIN)<<  item->getRegisteredProperty(FitParameterItem::P_MAX);
+void FitParameterWidget::updateSelector()
+{
+    m_parameterModel = new FitParameterModel(m_fitModel, this);
+    m_parameterTreeview->setModel(m_parameterModel);
+    connect(m_parameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+            m_fitModel, SLOT(dataChangedProxy(QModelIndex,QModelIndex,QVector<int>)));
+
+    // setup firstcolumnspanning
+    connect(m_parameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+            this, SLOT(spanParameters()));
+    spanParameters();
+    buildSelectorModel();
+
+    m_selectorTreeView->setModel(m_selectorModel);
+    m_selectorTreeView->expandAll();
+    m_selectorTreeView->resizeColumnToContents(0);
+    m_selectorTreeView->setColumnWidth(0, m_selectorTreeView->columnWidth(0) * 1.2);
+
+    connectSelectorView();
+}
 
-            insertRowIntoItem(parentItem, item->itemName(), item->getRegisteredProperty(FitParameterItem::P_VALUE), item->getRegisteredProperty(FitParameterItem::P_MIN), item->getRegisteredProperty(FitParameterItem::P_MAX), item->getRegisteredProperty(FitParameterItem::P_USE));
+void FitParameterWidget::clearParameter() {
+    while (m_parameterModel->rowCount(QModelIndex())) {
+        m_parameterModel->removeRow(0, QModelIndex());
+    }
+}
 
+void FitParameterWidget::buildTree(QStandardItem *root, ParameterizedItem *top)
+{
+    QStringList parameterTree = top->getParameterTreeList();
+
+    foreach (const QString &str, parameterTree) {
+        QStringList parts = str.split("/");
+        QStandardItem *cur = root;
+        for (int partIndex = 0; partIndex < parts.size(); partIndex++) {
+            bool insertItem = true;
+
+            // search for existing child
+            for (int childIndex = 0; childIndex < cur->rowCount(); childIndex++) {
+                if (cur->child(childIndex, 0)->text() == parts[partIndex]) {
+                    cur = cur->child(childIndex, 0);
+                    insertItem = false;
+                    break;
+                }
+            }
+            if (insertItem) {
+                QStandardItem *item = new QStandardItem(parts[partIndex]);
+                QStandardItem *data = new QStandardItem();
+                item->setEditable(false);
+                data->setEditable(false);
+                if (partIndex == parts.size() - 1) { // arrived at the end
+                    double value = top->getParameterValue(str);
+                    data->setData(QVariant(value), Qt::EditRole);
+                } else {
+                    item->setDragEnabled(false);
+                    data->setDragEnabled(false);
+                }
+                cur->appendRow(QList<QStandardItem *>() << item << data);
+                cur = item;
+            }
         }
-
     }
+}
 
-    return parentItem;
+void FitParameterWidget::buildSelectorModel() {
+
+    m_selectorModel = new FitSelectorModel();
+    m_selectorModel->setHorizontalHeaderItem(0, new QStandardItem("Property"));
+    m_selectorModel->setHorizontalHeaderItem(1, new QStandardItem("Value"));
+    QStandardItem *root = m_selectorModel->invisibleRootItem();
+
+    ParameterizedItem *topSample = m_fitModel->getSelectedMultiLayerItem();
+    ParameterizedItem *topInst = m_fitModel->getSelectedInstrumentItem();
+    if (topSample && topInst) {
+        QStandardItem *multilayer = new QStandardItem("MultiLayer");
+        root->appendRow(multilayer);
+        buildTree(multilayer, topSample);
+        QStandardItem *instrument = new QStandardItem("Instrument");
+        root->appendRow(instrument);
+        buildTree(instrument, topInst);
+        spanParameters();
+    }
 }
 
-void FitParameterWidget::insertRowIntoItem(QStandardItemModel *parentItem, QString title, QVariant value, QVariant min, QVariant max, QVariant isUse)
+void FitParameterWidget::spanParameters()
 {
+    m_parameterTreeview->expandAll();
+    for (int i = 0; i < m_parameterModel->rowCount(QModelIndex()); i++){
+        QModelIndex parameter = m_parameterModel->index(i,0,QModelIndex());
+        if (!parameter.isValid())
+            break;
+        int childRowCount = m_parameterModel->rowCount(parameter);
+        if (childRowCount > 0){
+            for (int j = 0; j < childRowCount; j++) {
+                m_parameterTreeview->setFirstColumnSpanned(j, parameter, true);
+            }
+        }
+    }
+}
 
-    QStandardItem *titleItem = new QStandardItem(title);
-
-    QStandardItem *useItem = new QStandardItem();
-    useItem->setData(isUse, Qt::EditRole);
-    useItem->setEditable(true);
+void FitParameterWidget::onCustomContextMenu(const QPoint &point) {
+    m_removeAction->setEnabled(false);
+    QModelIndex index = m_parameterTreeview->indexAt(point);
+    if (index.isValid()) {
+        ParameterizedItem *cur = m_parameterModel->itemForIndex(index);
+        if (cur->itemName().startsWith("FitParameter")) {
+            m_parameterTreeview->setCurrentIndex(index);
+            m_removeAction->setEnabled(true);
+        }
+    }
+    m_contextMenu->exec(m_parameterTreeview->mapToGlobal(point + QPoint(2, 22)));
+}
 
-    QStandardItem *valueItem = new QStandardItem();
-    valueItem->setData(value, Qt::EditRole);
-    valueItem->setEditable(true);
+void FitParameterWidget::onRemoveParameter() {
+    QModelIndex index = m_parameterTreeview->currentIndex();
+    if (index.isValid()) {
+        m_parameterModel->removeRow(index.row(), index.parent());
+    }
+}
 
-    QStandardItem *minItem = new QStandardItem();
-    minItem->setData(min, Qt::EditRole);
-    minItem->setEditable(true);
+void FitParameterWidget::onParameterSelectionChanged(const QItemSelection &selection)
+{
+    if (selection.indexes().isEmpty())
+        return;
+    QModelIndex index = selection.indexes().first();
+    QModelIndex newSelection = QModelIndex();
+    if (index.isValid() && index.parent().isValid()) {
+        ParameterizedItem *val = m_fitModel->itemForIndex(index);
+        QString link = val->getRegisteredProperty(FitParameterLinkItem::P_LINK).toString();
+        QStandardItem *t = m_selectorModel->getItemFromPath(link);
+        newSelection = m_selectorModel->indexFromItem(t);
+    }
+    connectSelectorView(false);
+    m_selectorTreeView->selectionModel()
+            ->select(newSelection, QItemSelectionModel::ClearAndSelect);
+    if (newSelection.isValid()) {
+        newSelection = newSelection.sibling(newSelection.row(), 1);
+        m_selectorTreeView->selectionModel()
+                ->select(newSelection, QItemSelectionModel::Select);
+    }
+    connectSelectorView();
+}
 
-    QStandardItem *maxItem = new QStandardItem();
-    maxItem->setData(max, Qt::EditRole);
-    maxItem->setEditable(true);
+void FitParameterWidget::onSelectorSelectionChanged(const QItemSelection &selection)
+{
+    if (selection.indexes().isEmpty())
+        return;
+    QModelIndex index = selection.indexes().first();
+    index = index.sibling(index.row(), 0);
+    QModelIndex newSelection = QModelIndex();
+    if (index.isValid()) {
+        QString link = m_selectorModel->getPathFromIndex(index);
+        newSelection = m_parameterModel->itemForLink(link);
+    }
+    connectParameterView(false);
+    m_parameterTreeview->selectionModel()->
+            select(newSelection, QItemSelectionModel::ClearAndSelect);
+    connectParameterView();
+}
 
+void FitParameterWidget::connectSelectorView(bool active) {
+    if (active) {
+        connect(m_selectorTreeView->selectionModel(),
+                SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                this, SLOT(onSelectorSelectionChanged(QItemSelection)));
+    } else {
+        disconnect(m_selectorTreeView->selectionModel(),
+                   SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                   this, SLOT(onSelectorSelectionChanged(QItemSelection)));
+    }
+}
 
-    QStandardItem *subItem1 = new QStandardItem("this is the description 1 this is the description 1 this is the description 1");
-    QStandardItem *subItem2 = new QStandardItem("this is the description 2 this is the description 2 this is the description 2");
-    titleItem->appendRow(QList<QStandardItem *>() << subItem1 << new QStandardItem << new QStandardItem <<new QStandardItem <<new QStandardItem);
-    titleItem->appendRow(subItem2);
+void FitParameterWidget::connectParameterView(bool active) {
+    if (active) {
+        connect(m_parameterTreeview->selectionModel(),
+                SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                this, SLOT(onParameterSelectionChanged(QItemSelection)));
+    } else {
+        disconnect(m_parameterTreeview->selectionModel(),
+                   SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                   this, SLOT(onParameterSelectionChanged(QItemSelection)));
+    }
+}
 
-    parentItem->appendRow(QList<QStandardItem *>()  << titleItem << useItem << valueItem << minItem << maxItem);
+void FitParameterWidget::removeEmptyParameter() {
+    bool finished = false;
+    while (!finished) {
+        int rowCount = m_parameterModel->rowCount(QModelIndex());
+        if (rowCount == 0)
+            break;
+        for (int i=0; i<rowCount; i++) {
+            QModelIndex child = m_parameterModel->index(i,0,QModelIndex());
+            if (child.isValid() && m_parameterModel->rowCount(child) == 0) {
+                m_parameterModel->removeRow(i, QModelIndex());
+                break;
+            }
+            if (i + 1 == rowCount) {
+                finished = true;
+            }
+        }
+    }
+}
 
+void FitParameterWidget::removeSelectedItem() {
+    QModelIndex selection = m_parameterTreeview->currentIndex();
+    if (selection.isValid()) {
+        m_parameterModel->removeRow(selection.row(), selection.parent());
+    }
+    removeEmptyParameter();
 }
 
-void FitParameterWidget::initFitModel()
-{
-    m_fitModel = new FitModel;
-
-//    ParameterizedItem *item1 = m_fitModel->insertNewItem(Constants::FitParameterType);
-//    item1->setItemName("Par1");
-//    item1->setRegisteredProperty(FitParameterItem::P_USE, true);
-//    item1->setRegisteredProperty(FitParameterItem::P_VALUE, 3.0);
-//    item1->setRegisteredProperty(FitParameterItem::P_MIN, 1.0);
-//    item1->setRegisteredProperty(FitParameterItem::P_MAX, 5.0);
-//    //item1->setRegisteredProperty(FitParameterItem::P_NAME, tr("Par1"));
-
-    FitParameterItem *item1 = dynamic_cast<FitParameterItem *>(m_fitModel->insertNewItem(Constants::FitParameterType));
-    item1->setItemName("Par1");
-    QStringList descList1;
-    descList1 << "This is description 1" << "This is description 2" << "This is description 3";
-    item1->setParNames(descList1);
-
-    FitParameterItem *item2 = dynamic_cast<FitParameterItem *>(m_fitModel->insertNewItem(Constants::FitParameterType));
-    item2->setItemName("Par2");
-    QStringList descList2;
-    descList2 << "This is description 1" << "This is description 2" << "This is description 3";
-    item2->setParNames(descList2);
-
-    FitParameterItem *item3 = dynamic_cast<FitParameterItem *>(m_fitModel->insertNewItem(Constants::FitParameterType));
-    item3->setItemName("Par3");
-    QStringList descList3;
-    descList3 << "This is description 1" << "This is description 2" << "This is description 3";
-    item3->setParNames(descList3);
-
-
-    m_fitModel->save("fitmodel.xml");
-
-    //ParameterizedItem *old_item = m_fitModel->itemForIndex(m_fitModel->index(0,0, QModelIndex()));
+void FitParameterWidget::onDoubleclick(const QModelIndex index) {
+    QModelIndex entryIndex = index.sibling(index.row(), 0);
+    if (m_selectorModel->itemFromIndex(entryIndex)->isDragEnabled()) {
+        QMimeData *data = m_selectorModel->mimeData(QModelIndexList() << entryIndex);
+        if (m_parameterModel->canDropMimeData(data,Qt::CopyAction,0,0,QModelIndex())) {
+            m_parameterModel->dropMimeData(data,Qt::CopyAction,-1,-1,QModelIndex());
+        }
+        data->deleteLater();
+    }
 }
diff --git a/GUI/coregui/Views/FitWidgets/FitParameterWidget.h b/GUI/coregui/Views/FitWidgets/FitParameterWidget.h
index 39f5d93f67f14685a595f7406b9b4c395851c835..83672f4328d489ae8cf9adc775e9a9abf4f5ecaf 100644
--- a/GUI/coregui/Views/FitWidgets/FitParameterWidget.h
+++ b/GUI/coregui/Views/FitWidgets/FitParameterWidget.h
@@ -16,38 +16,67 @@
 #ifndef FITPARAMETERWIDGET_H
 #define FITPARAMETERWIDGET_H
 
+#include "WinDllMacros.h"
+#include "SessionModel.h"
 #include <QWidget>
-#include <QTreeView>
-#include <QAction>
-#include <QTableWidget>
-
-#include "FitProxyModel.h"
-#include "FitModel.h"
+#include <QStandardItemModel>
+#include <QAbstractItemModel>
 
+class QTreeView;
+class MainWindow;
+class FitSelectorModel;
+class QMenu;
+class SampleModel;
+class InstrumentModel;
 class FitModel;
-
-
+class ParameterizedItem;
+class FitParameterModel;
+class QItemSelection;
+class QSplitter;
+class DeleteEventFilter;
 
 class BA_CORE_API_ FitParameterWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    FitParameterWidget(FitProxyModel *fitProxyModel, QWidget *parent = 0);
+    static const QString MIME_TYPE;
+    FitParameterWidget(FitModel *fitModel, QWidget *parent = 0);
 
-private:
-    FitModel *m_fitModel;
-    QStandardItemModel *m_parameterModel;
-    QTreeView *m_treeView;
-    FitProxyModel *m_fitProxyModel;
+    void clearParameter();
+public slots:
+    void updateSelector();
+    void spanParameters();
+    void removeSelectedItem();
 
+    void onCustomContextMenu(const QPoint &point);
+    void onRemoveParameter();
 
-    QStandardItemModel *createParameterModel(FitModel *fitModel);
-    QStandardItemModel *iterateSessionModel(FitModel *fitModel, const QModelIndex &parentIndex = QModelIndex(), QStandardItemModel *parentItem = 0);
-    void insertRowIntoItem(QStandardItemModel *parentItem, QString title, QVariant value, QVariant min, QVariant max, QVariant isUse);
+    void onParameterSelectionChanged(const QItemSelection&selection);
+    void onSelectorSelectionChanged(const QItemSelection &selection);
 
+    void onDoubleclick(const QModelIndex index);
 
-    void initFitModel();
+private:
+    void buildSelectorModel();
+    void connectSelectorView(bool active = true);
+    void connectParameterView(bool active = true);
+    void buildTree(QStandardItem *root, ParameterizedItem *top);
+    void removeEmptyParameter();
+
+    FitModel *m_fitModel;
+    QTreeView *m_selectorTreeView;
+    QTreeView *m_parameterTreeview;
+    FitSelectorModel *m_selectorModel;
+    FitParameterModel *m_parameterModel;
+    QMenu *m_contextMenu;
+    QAction *m_removeAction;
+    QAction *m_addAction;
+    QSplitter *m_splitter;
+    DeleteEventFilter *m_keyboardFilter;
 };
 
+
+
+
 #endif
diff --git a/GUI/coregui/Views/FitWidgets/FitProgressWidget.cpp b/GUI/coregui/Views/FitWidgets/FitProgressWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8e5d083b0fb6addfb48f81b1245137700e85450
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitProgressWidget.cpp
@@ -0,0 +1,145 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.h
+//! @brief     Defines class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FitProgressWidget.h"
+#include "ColorMapPlot.h"
+#include "IntensityDataItem.h"
+#include "GUIFitObserver.h"
+#include "FitSuite.h"
+#include "qcustomplot.h"
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPlainTextEdit>
+#include <QSplitter>
+#include <QScrollBar>
+#include <QFont>
+#include <QSlider>
+
+FitProgressWidget::FitProgressWidget(QWidget *parent)
+    : QWidget(parent)
+    , m_status(new QLabel(this))
+    , m_realdataplot(new ColorMapPlot(this))
+    , m_simulatedplot(new ColorMapPlot(this))
+    , m_chi2plot(new ColorMapPlot(this))
+    , m_realdata(new IntensityDataItem())
+    , m_simulated(new IntensityDataItem())
+    , m_chi2(new IntensityDataItem())
+    , m_log(new QPlainTextEdit(this))
+    , m_splitter(new QSplitter())
+{
+    m_guifitobserver = boost::shared_ptr<GUIFitObserver>(new GUIFitObserver(this));
+
+    connect(m_guifitobserver.get(), SIGNAL(updateStatus(const QString&)),
+            this, SLOT(updateStatus(const QString&)));
+    connect(m_guifitobserver.get(), SIGNAL(updatePlots(OutputData<double>*, OutputData<double>*)),
+            this, SLOT(updatePlots(OutputData<double>*, OutputData<double>*)));
+    connect(m_guifitobserver.get(), SIGNAL(updateLog(const QString&)),
+            this, SLOT(updateLog(const QString&)));
+    connect(m_guifitobserver.get(), SIGNAL(startFitting(OutputData<double>*)),
+            this, SLOT(startFitting(OutputData<double>*)));
+
+    // chi2 is the last plot to finish, so we wait for it
+    connect(m_chi2plot->getCustomPlot(), SIGNAL(afterReplot()),
+            this, SLOT(afterReplot()));
+
+    m_realdataplot->setItem(m_realdata);
+    m_simulatedplot->setItem(m_simulated);
+    m_chi2plot->setItem(m_chi2);
+    m_chi2->setProperty("Gradient", "Hot");
+
+    QHBoxLayout *plots = new QHBoxLayout();
+    plots->addWidget(m_realdataplot);
+    plots->addWidget(m_simulatedplot);
+    plots->addWidget(m_chi2plot);
+    QWidget *plotsWidget = new QWidget();
+    plotsWidget->setLayout(plots);
+
+    m_splitter->setOrientation(Qt::Vertical);
+    m_splitter->addWidget(plotsWidget);
+    m_splitter->addWidget(m_log);
+
+    QVBoxLayout *layout = new QVBoxLayout();
+    layout->addWidget(m_status);
+    layout->addWidget(m_splitter);
+    m_log->setReadOnly(true);
+    m_log->setMaximumBlockCount(100000);
+    QFont f("unexistent");
+    f.setStyleHint(QFont::Monospace);
+    m_log->setFont(f);
+    m_status->setText("");
+    setLayout(layout);
+}
+
+void FitProgressWidget::startFitting(OutputData<double> *real)
+{
+    m_realdata->setOutputData(real);
+    m_simulated->setOutputData(real->clone());
+    m_simulated->setZAxisLocked(true);
+    disableInteractions();
+    m_log->clear();
+}
+
+void FitProgressWidget::connectSlider(QSlider *slider)
+{
+    connect(slider, SIGNAL(valueChanged(int)),
+                m_guifitobserver.get(), SLOT(setInterval(int)));
+}
+
+void FitProgressWidget::setObserverToSuite(FitSuite *suite)
+{
+    suite->attachObserver(m_guifitobserver);
+}
+
+void FitProgressWidget::updateStatus(const QString &text)
+{
+    m_status->setText(text);
+}
+
+void FitProgressWidget::updateLog(const QString &msg)
+{
+    QScrollBar *scrollbar = m_log->verticalScrollBar();
+    bool autoscroll = scrollbar->value() == scrollbar->maximum();
+    m_log->appendPlainText(msg);
+    if (autoscroll) {
+        QTextCursor c = m_log->textCursor();
+        c.movePosition(QTextCursor::End);
+        m_log->setTextCursor(c);
+    }
+}
+
+void FitProgressWidget::updatePlots(OutputData<double> *sim, OutputData<double> *chi)
+{
+    m_simulated->setOutputData(sim);
+    m_simulated->setLowerAndUpperZ(m_realdata->getLowerZ(), m_realdata->getUpperZ());
+    m_chi2->setOutputData(chi);
+    disableInteractions();
+}
+
+void FitProgressWidget::afterReplot()
+{
+    m_guifitobserver->finishedPlotting();
+}
+
+void FitProgressWidget::disableInteractions()
+{
+    // as ColorMapPlot enables Interactions every time, we must disenable them as well
+    m_realdataplot->getCustomPlot()->setInteraction(QCP::iRangeDrag, false);
+    m_realdataplot->getCustomPlot()->setInteraction(QCP::iRangeZoom, false);
+    m_simulatedplot->getCustomPlot()->setInteraction(QCP::iRangeDrag, false);
+    m_simulatedplot->getCustomPlot()->setInteraction(QCP::iRangeZoom, false);
+    m_chi2plot->getCustomPlot()->setInteraction(QCP::iRangeDrag, false);
+    m_chi2plot->getCustomPlot()->setInteraction(QCP::iRangeZoom, false);
+}
diff --git a/GUI/coregui/Views/FitWidgets/FitProgressWidget.h b/GUI/coregui/Views/FitWidgets/FitProgressWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..c20eb04b3680e137475d2de8e697cba3f8115277
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitProgressWidget.h
@@ -0,0 +1,77 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.h
+//! @brief     Defines class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef FITPROGRESSWIDGET_H
+#define FITPROGRESSWIDGET_H
+
+#include "WinDllMacros.h"
+#include "OutputData.h"
+#include <boost/shared_ptr.hpp>
+#include <QWidget>
+
+class QLabel;
+class ColorMapPlot;
+class IntensityDataItem;
+class QPlainTextEdit;
+class QSplitter;
+class GUIFitObserver;
+class QSlider;
+class FitSuite;
+
+class BA_CORE_API_ FitProgressWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    FitProgressWidget(QWidget *parent = 0);
+
+    void connectSlider(QSlider *slider);
+
+    void setObserverToSuite(FitSuite *suite);
+
+public slots:
+
+    void updateStatus(const QString &text);
+
+    void updateLog(const QString &msg);
+
+    void updatePlots(OutputData<double> *sim, OutputData<double> *chi);
+
+    void startFitting(OutputData<double> *real);
+
+    void afterReplot();
+
+private:
+
+    QLabel *m_status;
+    ColorMapPlot *m_realdataplot;
+    ColorMapPlot *m_simulatedplot;
+    ColorMapPlot *m_chi2plot;
+    IntensityDataItem *m_realdata;
+    IntensityDataItem *m_simulated;
+    IntensityDataItem *m_chi2;
+    QPlainTextEdit *m_log;
+    QSplitter *m_splitter;
+    boost::shared_ptr<GUIFitObserver> m_guifitobserver;
+
+    void disableInteractions();
+};
+
+
+
+
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/FitSettingsWidget.cpp b/GUI/coregui/Views/FitWidgets/FitSettingsWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfd29c8ba46431832b2b075c34f7ded14d6f290f
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitSettingsWidget.cpp
@@ -0,0 +1,119 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.h
+//! @brief     Defines class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FitSettingsWidget.h"
+#include "FitParameterWidget.h"
+#include "FitModel.h"
+
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QComboBox>
+#include <QLabel>
+
+
+FitSettingsWidget::FitSettingsWidget(FitModel *fitModel, QWidget *parent)
+    : QWidget(parent)
+    , m_fitModel(fitModel)
+    , m_fitParameter(new FitParameterWidget(m_fitModel, this))
+    , m_sampleCombo(new QComboBox())
+    , m_instrumentCombo(new QComboBox())
+{
+    m_sampleCombo->setMinimumWidth(200);
+    m_instrumentCombo->setMinimumWidth(200);
+
+    QVBoxLayout *mainLayout = new QVBoxLayout();
+    QHBoxLayout *topLayout = new QHBoxLayout();
+    topLayout->addWidget(new QLabel("Select Sample:"));
+    topLayout->addWidget(m_sampleCombo);
+    topLayout->addSpacing(30);
+    topLayout->addWidget(new QLabel("Select Instrument:"));
+    topLayout->addWidget(m_instrumentCombo);
+    topLayout->addStretch();
+    QWidget *topWidget = new QWidget();
+    topWidget->setLayout(topLayout);
+    topWidget->setContentsMargins(0,0,0,0);
+    topWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+    mainLayout->addWidget(topWidget);
+    mainLayout->addWidget(m_fitParameter);
+    m_fitParameter->setSizePolicy(QSizePolicy::MinimumExpanding,
+                                  QSizePolicy::MinimumExpanding);
+    connectCombos();
+    setLayout(mainLayout);
+}
+
+void FitSettingsWidget::showEvent(QShowEvent *)
+{
+    onUpdateGUI();
+}
+
+void FitSettingsWidget::onUpdateGUI()
+{
+    m_fitParameter->updateSelector();
+
+    disconnectCombos();
+    m_sampleCombo->clear();
+    m_instrumentCombo->clear();
+
+    foreach (QString v, m_fitModel->getSampleNames()) {
+        m_sampleCombo->addItem(m_fitModel->getSampleItemNameForDisplayName(v),
+                               v);
+    }
+
+    foreach (QString v, m_fitModel->getInstrumentNames()) {
+        m_instrumentCombo->addItem(m_fitModel->getInstrumentItemNameForDisplayName(v),
+                                   v);
+    }
+    m_sampleCombo->setCurrentIndex(-1);
+    m_instrumentCombo->setCurrentIndex(-1);
+    connectCombos();
+
+    m_instrumentCombo->setCurrentIndex(m_instrumentCombo->findData
+                                      (m_fitModel->getSelectedInstrumentName()));
+    m_sampleCombo->setCurrentIndex(m_sampleCombo->findData(m_fitModel->getSelectedSampleName()));
+}
+
+void FitSettingsWidget::onSampleChanged(int index)
+{
+    QString data = m_sampleCombo->itemData(index).toString();
+    if (data != m_fitModel->getSelectedSampleName()) {
+        m_fitModel->setSelectedSample(data);
+        m_fitParameter->updateSelector();
+        // when sample changed, discard all fit parameters
+        m_fitParameter->clearParameter();
+    }
+}
+
+void FitSettingsWidget::onInstrumentChanged(int index)
+{
+    QString data = m_instrumentCombo->itemData(index).toString();
+    if (data != m_fitModel->getSelectedInstrumentName()) {
+        m_fitModel->setSelectedInstrument(data);
+        m_fitParameter->updateSelector();
+        // when sample changed, discard all fit parameters
+        m_fitParameter->clearParameter();
+    }
+}
+
+void FitSettingsWidget::connectCombos() {
+    connect(m_sampleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSampleChanged(int)));
+    connect(m_instrumentCombo, SIGNAL(currentIndexChanged(int)),
+            this, SLOT(onInstrumentChanged(int)));
+}
+
+void FitSettingsWidget::disconnectCombos() {
+    disconnect(m_sampleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSampleChanged(int)));
+    disconnect(m_instrumentCombo, SIGNAL(currentIndexChanged(int)),
+               this, SLOT(onInstrumentChanged(int)));
+}
diff --git a/GUI/coregui/Views/FitWidgets/FitSettingsWidget.h b/GUI/coregui/Views/FitWidgets/FitSettingsWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..8953daa2b1e750cf4f739b8e398e14769079fb26
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitSettingsWidget.h
@@ -0,0 +1,56 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.h
+//! @brief     Defines class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef FITSETTINGSWIDGET_H
+#define FITSETTINGSWIDGET_H
+
+#include "WinDllMacros.h"
+#include <QWidget>
+
+class FitModel;
+class FitParameterWidget;
+class QComboBox;
+
+
+class BA_CORE_API_ FitSettingsWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    FitSettingsWidget(FitModel *fitModel, QWidget *parent);
+
+    //! we update GUI when widget is shown
+    void showEvent(QShowEvent *);
+
+    //! connect and disconnect signals for comboboxes
+    void connectCombos();
+    void disconnectCombos();
+
+public slots:
+    //! call this slot to refresh comboboxes and fitparameters
+    void onUpdateGUI();
+
+    //! slots for sample/instrument changes
+    void onSampleChanged(int index);
+    void onInstrumentChanged(int index);
+
+private:
+    FitModel *m_fitModel;
+    FitParameterWidget *m_fitParameter;
+    QComboBox *m_sampleCombo;
+    QComboBox *m_instrumentCombo;
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/FitToolBar.cpp b/GUI/coregui/Views/FitWidgets/FitToolBar.cpp
deleted file mode 100644
index 2cfb42679fbbdf807e4e62059e7e2184868c65d1..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/FitWidgets/FitToolBar.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Views/FitWidgets/FitToolBar.cpp
-//! @brief     Implements class FitToolBar
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "FitToolBar.h"
-#include "styledbar.h"
-
-#include <QIcon>
-#include <QAction>
-#include <QToolButton>
-#include <QToolBar>
-#include <QStyle>
-#include <iostream>
-
-
-FitToolBar::FitToolBar(QWidget *parent)
-    : QToolBar(parent)
-{
-    setMovable(false);
-
-    const int size = style()->pixelMetric(QStyle::PM_SmallIconSize);
-    setIconSize(QSize(size, size));
-    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
-
-    setContentsMargins(0,0,0,0);
-
-    this->addAction(new QAction(0));
-
-}
diff --git a/GUI/coregui/Views/FitWidgets/FittingWorker.cpp b/GUI/coregui/Views/FitWidgets/FittingWorker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5a1e7176b36192fbd61f141a7c69f971f97d397b
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FittingWorker.cpp
@@ -0,0 +1,37 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/FittingWorker.cpp
+//! @brief     Implements class FittingWorker
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "FittingWorker.h"
+#include "FitSuite.h"
+
+void FittingWorker::startFit()
+{
+    m_fitsuite->resetInterrupt();
+    emit started();
+    try {
+        m_fitsuite->runFit();
+    } catch(const std::exception& ex) {
+        emit error(QString::fromLatin1(ex.what()));
+    }
+    emit finished();
+}
+
+void FittingWorker::interruptFitting()
+{
+    if (m_fitsuite) {
+        m_fitsuite->interruptFitting();
+    }
+}
+
diff --git a/GUI/coregui/Views/FitWidgets/FittingWorker.h b/GUI/coregui/Views/FitWidgets/FittingWorker.h
new file mode 100644
index 0000000000000000000000000000000000000000..a88f5b020970b8276d308502880295d47205ee47
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FittingWorker.h
@@ -0,0 +1,53 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/FittingWorker.h
+//! @brief     Implements class FittingWorker
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef FITTINGWORKER_H
+#define FITTINGWORKER_H
+
+#include "WinDllMacros.h"
+#include <QObject>
+#include <boost/shared_ptr.hpp>
+
+class FitSuite;
+
+class BA_CORE_API_ FittingWorker : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    FittingWorker(boost::shared_ptr<FitSuite> suite) {m_fitsuite = suite;}
+
+public slots:
+
+    void startFit();
+
+    void interruptFitting();
+
+signals:
+
+    void started();
+
+    void finished();
+
+    void error(const QString &message);
+
+private:
+
+    boost::shared_ptr<FitSuite> m_fitsuite;
+
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..69c30e435443524dc74dc2643185b0b51983c609
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp
@@ -0,0 +1,71 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/FittingWorker.h
+//! @brief     Implements class FittingWorker
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "GUIFitObserver.h"
+#include "FitSuite.h"
+#include "IntensityDataItem.h"
+#include <boost/scoped_ptr.hpp>
+
+void GUIFitObserver::update(FitSuite *subject)
+{
+    // discard data after interruption
+    if (subject->isInterrupted())
+        return;
+
+    // update log every time
+    std::stringstream buffer;
+    std::streambuf *old = std::cout.rdbuf(buffer.rdbuf());
+    subject->getFitParameters()->printParameters();
+    std::string text = buffer.str();
+    std::cout.rdbuf(old);
+
+    emit updateLog(QString("NCalls: %1 Chi: %2\n%3").
+                      arg(QString::number(subject->getNumberOfIterations()),
+                          QString::number(subject->getChi2()),
+                          QString::fromStdString(text)));
+
+    if (subject->isLastIteration()) {
+        std::stringstream buffer;
+        std::streambuf *old = std::cout.rdbuf(buffer.rdbuf());
+        subject->printResults();
+        std::string text = buffer.str();
+        emit updateLog(QString::fromStdString(text));
+        std::cout.rdbuf(old);
+    }
+
+    int curIteration = subject->getNumberOfIterations();
+
+    if (curIteration == 0) {
+        emit startFitting(subject->getRealOutputData()->clone());
+    }
+    if (curIteration % m_update_interval == 0 && !m_block_update_plots) {
+        m_block_update_plots = true;
+
+        emit updateStatus(QString("Iteration: %1").arg(subject->getNumberOfIterations()));
+
+        emit updatePlots(subject->getSimulationOutputData()->clone(),
+                         subject->getChiSquaredOutputData()->clone());
+    }
+}
+
+void GUIFitObserver::setInterval(int val)
+{
+    m_update_interval = val;
+}
+
+void GUIFitObserver::finishedPlotting()
+{
+    m_block_update_plots = false;
+}
diff --git a/GUI/coregui/Views/FitWidgets/GUIFitObserver.h b/GUI/coregui/Views/FitWidgets/GUIFitObserver.h
new file mode 100644
index 0000000000000000000000000000000000000000..af35a9f357118ef3fae18cd91103ef9ad405c91b
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/GUIFitObserver.h
@@ -0,0 +1,63 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/FittingWorker.h
+//! @brief     Implements class FittingWorker
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef GUIFITOBSERVER_H
+#define GUIFITOBSERVER_H
+
+#include "WinDllMacros.h"
+#include "IFitObserver.h"
+#include "OutputData.h"
+#include <QObject>
+#include <atomic>
+
+class FitSuite;
+class IntensityDataItem;
+
+class BA_CORE_API_ GUIFitObserver : public QObject, public IFitObserver
+{
+    Q_OBJECT
+
+public:
+
+    GUIFitObserver(QObject *parent = 0)
+        : QObject(parent)
+        , IFitObserver(1)
+        , m_update_interval(1)
+    {}
+
+    void update(FitSuite *subject);
+
+    void finishedPlotting();
+
+public slots:
+
+    void setInterval(int val);
+
+signals:
+
+    void updateStatus(const QString &);
+
+    void updatePlots(OutputData<double>*, OutputData<double>*);
+
+    void updateLog(const QString &);
+
+    void startFitting(OutputData<double>*);
+
+private:
+    std::atomic<bool> m_block_update_plots;
+    int m_update_interval;
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/ImportDataWidget.cpp b/GUI/coregui/Views/FitWidgets/ImportDataWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f813fc48ddc2c35fe2635fb46974c2425b11c151
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/ImportDataWidget.cpp
@@ -0,0 +1,61 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.cpp
+//! @brief     Implements class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ImportDataWidget.h"
+#include "ColorMapPlot.h"
+#include "IHistogram.h"
+#include "IntensityDataIOFactory.h"
+#include "IntensityDataItem.h"
+#include "FitParameterItems.h"
+#include "FitModel.h"
+#include <QLineEdit>
+#include <QVBoxLayout>
+
+ImportDataWidget::ImportDataWidget(FitModel *fitModel, QWidget *parent)
+    : QWidget(parent)
+    , m_line(new QLineEdit())
+    , m_plot(new ColorMapPlot(this))
+    , m_fitModel(fitModel)
+{
+    QVBoxLayout *mainLayout = new QVBoxLayout();
+    mainLayout->addWidget(m_line);
+    mainLayout->addWidget(m_plot);
+    connect(m_line, SIGNAL(textChanged(QString)), this, SLOT(onTextUpdate()));
+    setLayout(mainLayout);
+}
+
+void ImportDataWidget::onTextUpdate() {
+    QFileInfo chk(m_line->text());
+    if (chk.exists() && chk.isFile()) {
+        try {
+            IHistogram *data = IntensityDataIOFactory::readIntensityData(m_line->text().toStdString());
+            IntensityDataItem *item = new IntensityDataItem();
+            item->setOutputData(data->createOutputData());
+            m_plot->setItem(item);
+            m_fitModel->setInputDataPath(m_line->text());
+        } catch (...) { }
+    }
+}
+
+void ImportDataWidget::showEvent(QShowEvent *)
+{
+    onUpdateGUI();
+}
+
+void ImportDataWidget::onUpdateGUI()
+{
+
+    m_line->setText(m_fitModel->getInputDataPath());
+}
diff --git a/GUI/coregui/Views/FitWidgets/ImportDataWidget.h b/GUI/coregui/Views/FitWidgets/ImportDataWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2f76aaa8abd73cf62d0b3b40d5e7ce05b038045
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/ImportDataWidget.h
@@ -0,0 +1,49 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitWidget.h
+//! @brief     Defines class RunFitWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef IMPORTDATAWIDGET_H
+#define IMPORTDATAWIDGET_H
+
+#include "WinDllMacros.h"
+#include <QWidget>
+
+class QLineEdit;
+class ColorMapPlot;
+class FitModel;
+
+class BA_CORE_API_ ImportDataWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    //! TOY: loads file from path and plot data
+    ImportDataWidget(FitModel *fitModel, QWidget *parent = 0);
+
+    void showEvent(QShowEvent *);
+
+
+public slots:
+    //! when the text points to existing file, then plot file
+    void onTextUpdate();
+
+    void onUpdateGUI();
+
+private:
+    QLineEdit *m_line;
+    ColorMapPlot *m_plot;
+    FitModel *m_fitModel;
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.cpp b/GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2da6ee2d1d70a74e73f698c5cd0ab2be9accbdcc
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.cpp
@@ -0,0 +1,31 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/FitParameterWidget.cpp
+//! @brief     Implements class FitParameterWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "MinimizerSettingsWidget.h"
+#include "AwesomePropertyEditor.h"
+#include "FitModel.h"
+#include "FitParameterItems.h"
+#include <QHBoxLayout>
+#include <QSplitter>
+
+MinimizerSettingsWidget::MinimizerSettingsWidget(FitModel *fitModel, QWidget *parent)
+    : QWidget(parent)
+{
+    QHBoxLayout *layout = new QHBoxLayout;
+    AwesomePropertyEditor *editor = new AwesomePropertyEditor(this);
+    editor->setItem(fitModel->getMinimizerSettings());
+    layout->addWidget(editor);
+    setLayout(layout);
+}
diff --git a/GUI/coregui/Views/FitWidgets/FitToolBar.h b/GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.h
similarity index 63%
rename from GUI/coregui/Views/FitWidgets/FitToolBar.h
rename to GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.h
index fe2e56a7ce25736cf7b04179a23cd0526b33f049..418256e78062e8cb63ca5a770c3ffa0c6a81d893 100644
--- a/GUI/coregui/Views/FitWidgets/FitToolBar.h
+++ b/GUI/coregui/Views/FitWidgets/MinimizerSettingsWidget.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      coregui/Views/FitWidgets/FitToolBar.h
-//! @brief     Defines class FitToolBar
+//! @file      coregui/Views/FitWidgets/FitParameterWidget.h
+//! @brief     Defines class FitParameterWidget
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -13,25 +13,23 @@
 //
 // ************************************************************************** //
 
-#ifndef FITTOOLBAR_H
-#define FITTOOLBAR_H
+#ifndef MINIMIZERSETTTINGSWIDGET_H
+#define MINIMIZERSETTTINGSWIDGET_H
 
 #include "WinDllMacros.h"
-#include <QToolBar>
+#include <QWidget>
 
-class QAction;
-class QToolButton;
-class QToolBar;
+class FitModel;
 
-
-class BA_CORE_API_ FitToolBar : public QToolBar
+class BA_CORE_API_ MinimizerSettingsWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit FitToolBar(QWidget *parent = 0);
-
+    MinimizerSettingsWidget(FitModel *fitModel, QWidget *parent = 0);
 };
 
 
-#endif // SIMULATIONTOOLBAR_H
+
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/RealDataWidget.cpp b/GUI/coregui/Views/FitWidgets/RealDataWidget.cpp
deleted file mode 100644
index 93f4ab0e4ad3960a7e6b3f377be7138ac43c0bc1..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/FitWidgets/RealDataWidget.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      coregui/Views/FitWidgets/RealDataWidget.cpp
-//! @brief     Implements class RealDataWidget
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2015
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include "RealDataWidget.h"
-#include <QDebug>
-#include <QVBoxLayout>
-
-
-
-RealDataWidget::RealDataWidget(QWidget *parent)
-    : QWidget(parent)
-{
-
-    QColor bgColor(255,255,255,255);
-    QPalette palette;
-    palette.setColor(QPalette::Background, bgColor);
-    setAutoFillBackground(true);
-    setPalette(palette);
-
-
-    QVBoxLayout *vlayout = new QVBoxLayout(this);
-    vlayout->setMargin(0);
-    vlayout->setSpacing(0);
-    //vlayout->addWidget(m_treeView);
-    //vlayout->addStretch();
-    this->setLayout(vlayout);
-
-}
diff --git a/GUI/coregui/Views/FitWidgets/RunFitManager.cpp b/GUI/coregui/Views/FitWidgets/RunFitManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0af4fee77b5b8f164c58950a8524b24066cd781b
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/RunFitManager.cpp
@@ -0,0 +1,84 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitManager.cpp
+//! @brief     Implements class RunFitManager
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "RunFitManager.h"
+#include "FittingWorker.h"
+#include "FitSuite.h"
+#include <QThread>
+
+RunFitManager::RunFitManager(QObject *parent)
+    : QObject(parent)
+    , m_fitSuite(nullptr)
+    , m_is_fit_running{false}
+{
+}
+
+void RunFitManager::setFitSuite(boost::shared_ptr<FitSuite> suite)
+{
+    m_fitSuite = suite;
+}
+
+// start fitting in separate thread
+void RunFitManager::runFitting()
+{
+    if (!m_fitSuite || m_is_fit_running)
+        return;
+
+    QThread *thread = new QThread();
+    FittingWorker *fw = new FittingWorker(m_fitSuite);
+    fw->moveToThread(thread);
+
+    // start fitting when thread starts
+    connect(thread, SIGNAL(started()), fw, SLOT(startFit()));
+    connect(fw, SIGNAL(started()), this, SLOT(intern_workerStarted()));
+
+    connect(this, SIGNAL(intern_interruptFittingWorker()), fw, SLOT(interruptFitting()),
+            Qt::DirectConnection);
+
+    connect(fw, SIGNAL(error(QString)), this, SLOT(intern_error(QString)));
+
+    connect(fw, SIGNAL(finished()), this, SLOT(intern_workerFinished()));
+
+    // delete fitting worker and thread when done
+    connect(fw, SIGNAL(finished()), fw, SLOT(deleteLater()));
+    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+
+    m_is_fit_running = true;
+    thread->start();
+}
+
+void RunFitManager::interruptFitting()
+{
+    if (m_is_fit_running) {
+        emit intern_interruptFittingWorker();
+    }
+}
+
+void RunFitManager::intern_workerFinished()
+{
+    m_is_fit_running = false;
+    m_fitSuite.reset();
+    emit finishedFitting();
+}
+
+void RunFitManager::intern_workerStarted()
+{
+    emit startedFitting();
+}
+
+void RunFitManager::intern_error(const QString &mesg)
+{
+    emit error(mesg);
+}
diff --git a/GUI/coregui/Views/FitWidgets/RunFitManager.h b/GUI/coregui/Views/FitWidgets/RunFitManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..f602da4b6fc40f67b1bcdfce5696eb26b16640f5
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/RunFitManager.h
@@ -0,0 +1,72 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Views/FitWidgets/RunFitManager.h
+//! @brief     Implements class RunFitManager
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef RUNFITMANAGER_H
+#define RUNFITMANAGER_H
+
+#include "WinDllMacros.h"
+#include <atomic>
+#include <boost/shared_ptr.hpp>
+#include <QObject>
+
+class FitSuite;
+
+class BA_CORE_API_ RunFitManager : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    RunFitManager(QObject *parent);
+
+    void setFitSuite(boost::shared_ptr<FitSuite> suite);
+
+    void runFitting();
+
+public slots:
+
+    void interruptFitting();
+
+signals:
+
+    void finishedFitting();
+
+    void startedFitting();
+
+    void error(const QString &message);
+
+
+// only used by manager for communication with FittingWorker
+private slots:
+
+    void intern_workerFinished();
+
+    void intern_workerStarted();
+
+    void intern_error(const QString &mesg);
+
+signals:
+
+    void intern_interruptFittingWorker();
+
+
+private:
+
+    boost::shared_ptr<FitSuite> m_fitSuite;
+    std::atomic<bool> m_is_fit_running;
+
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/RunFitWidget.cpp b/GUI/coregui/Views/FitWidgets/RunFitWidget.cpp
index 49687c66d6cb204c8da9f0112796a7aadd81f98b..56eea7ae427dd0938e1035145e772d600c754f26 100644
--- a/GUI/coregui/Views/FitWidgets/RunFitWidget.cpp
+++ b/GUI/coregui/Views/FitWidgets/RunFitWidget.cpp
@@ -14,27 +14,195 @@
 // ************************************************************************** //
 
 #include "RunFitWidget.h"
-#include <QDebug>
+#include "RunFitManager.h"
+#include "SampleBuilderFactory.h"
+#include "SimulationRegistry.h"
+#include "FitSuite.h"
+#include "GUIFitObserver.h"
+#include "FitProgressWidget.h"
+#include "SampleModel.h"
+#include "InstrumentModel.h"
+#include "FitModel.h"
+#include "DomainSimulationBuilder.h"
+#include "FitParameterItems.h"
+#include "ParameterizedItem.h"
+#include "MultiLayerItem.h"
+#include "InstrumentItem.h"
+#include "SessionModel.h"
+#include "IntensityDataIOFactory.h"
+#include <QWidget>
+#include <QPushButton>
+#include <QSlider>
+#include <QLabel>
 #include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QFileInfo>
+#include <QDebug>
+
+RunFitWidget::RunFitWidget(FitModel *fitModel, QWidget *parent)
+    : QWidget(parent)
+    , m_start_button(new QPushButton())
+    , m_stop_button(new QPushButton())
+    , m_interval_label(new QLabel())
+    , m_interval_slider(new QSlider())
+    , m_runfitmanager(new RunFitManager(this))
+    , m_fitprogress(new FitProgressWidget(this))
+    , m_fitModel(fitModel)
+{
+    // setup ui
+    m_start_button->setText(tr("Start"));
+    m_stop_button->setText(tr("Stop"));
+    m_stop_button->setEnabled(false);
+    m_interval_slider->setOrientation(Qt::Horizontal);
+    m_interval_slider->setRange(1,20);
+    m_interval_slider->setMaximumWidth(150);
+    m_interval_slider->setMinimumWidth(150);
+    m_interval_slider->setFocusPolicy(Qt::NoFocus);
 
+    QVBoxLayout *mainLayout = new QVBoxLayout();
+    QHBoxLayout *topLayout = new QHBoxLayout();
+    topLayout->addWidget(m_start_button);
+    topLayout->addWidget(m_stop_button);
+    topLayout->addStretch();
+    topLayout->addWidget(m_interval_label);
+    topLayout->addWidget(m_interval_slider);
+    QWidget *topWidget = new QWidget();
+    topWidget->setLayout(topLayout);
+    mainLayout->addWidget(topWidget);
+    mainLayout->addWidget(m_fitprogress);
 
+    // connect everything
+    connect(m_start_button, SIGNAL(clicked()), this, SLOT(onStartClicked()));
+    connect(m_stop_button, SIGNAL(clicked()), this, SLOT(onStopClicked()));
+    connect(m_runfitmanager, SIGNAL(startedFitting()), this, SLOT(onFittingStarted()));
+    connect(m_runfitmanager, SIGNAL(finishedFitting()), this, SLOT(onFittingFinished()));
+    connect(m_runfitmanager, SIGNAL(error(QString)), m_fitprogress, SLOT(updateLog(QString)));
 
-RunFitWidget::RunFitWidget(QWidget *parent)
-    : QWidget(parent)
+    connect(m_interval_slider, SIGNAL(valueChanged(int)), this, SLOT(onIntervalChanged(int)));
+    m_fitprogress->connectSlider(m_interval_slider);
+
+    setLayout(mainLayout);
+    m_interval_slider->setValue(10);
+}
+
+void RunFitWidget::onIntervalChanged(int value)
+{
+    m_interval_label->setText(QString("Update every %1th iteration").arg(value));
+}
+
+void RunFitWidget::onStartClicked()
+{
+    // used for test purposes
+    boost::shared_ptr<FitSuite> suite = init_test_fitsuite();
+    m_fitprogress->setObserverToSuite(suite.get());
+
+    m_runfitmanager->setFitSuite(suite);
+    m_runfitmanager->runFitting();
+}
+
+void RunFitWidget::onStopClicked()
+{
+    m_runfitmanager->interruptFitting();
+}
+
+void RunFitWidget::onFittingStarted()
+{
+    m_start_button->setEnabled(false);
+    m_stop_button->setEnabled(true);
+}
+
+void RunFitWidget::onFittingFinished()
 {
+    m_stop_button->setEnabled(false);
+    m_start_button->setEnabled(true);
+}
+
+
+
+// test only
+boost::shared_ptr<FitSuite> RunFitWidget::init_test_fitsuite()
+{
+    ParameterizedItem *multilayer = m_fitModel->getSelectedMultiLayerItem();
+    ParameterizedItem *instrument = m_fitModel->getSelectedInstrumentItem();
+
+    DomainSimulationBuilder builder;
+     boost::shared_ptr<FitSuite> m_fitsuite = boost::shared_ptr<FitSuite>(new FitSuite());
+
+    try {
+
+    boost::scoped_ptr<GISASSimulation> simulation(builder.getSimulation(dynamic_cast<MultiLayerItem*>
+                                                                          (multilayer),
+                                                                          dynamic_cast<InstrumentItem*>
+                                                                          (instrument)));
+
+
+
+        QString path = m_fitModel->getInputDataPath();
+    QFileInfo checkFile(path);
+
+    OutputData<double> *data = 0;
+
+    if (checkFile.exists() && checkFile.isFile()) {
+        data = IntensityDataIOFactory::readOutputData(path.toStdString());
+        qDebug() << data->totalSum();
+        //Q_ASSERT(0);
+    } else {
+
+        simulation->runSimulation();
+        data = simulation->getOutputData()->clone();
+    }
+
+
+
+
+
+    m_fitsuite->addSimulationAndRealData(*simulation.get(), *data);
+
+
+    ParameterizedItem *container = m_fitModel->getFitParameterContainer();
+
 
-    QColor bgColor(255,255,255,255);
-    QPalette palette;
-    palette.setColor(QPalette::Background, bgColor);
-    setAutoFillBackground(true);
-    setPalette(palette);
 
+    QModelIndex c_index = m_fitModel->indexOfItem(container);
+    for (int i = 0; i < m_fitModel->rowCount(c_index); i++) {
+        QModelIndex child = m_fitModel->index(i,0,c_index);
+        ParameterizedItem *parameter = m_fitModel->itemForIndex(child);
+        for (int j = 0; j < m_fitModel->rowCount(child); j++) {
+            ParameterizedItem *link = m_fitModel->itemForIndex(m_fitModel->index(j,0,child));
+            QString value = link->getRegisteredProperty(FitParameterLinkItem::P_LINK).toString();
+            value = value.replace("Position Offset/X", "PositionX");
+            value = value.replace("Position Offset/Y", "PositionY");
+            value = value.replace("Position Offset/Z", "PositionZ");
+            value = value.replace("Rotation/ZRotation", "ZRotation");
+            value = value.replace("Wavelength/DistributionNone/Value", "Wavelength");
+            value = value.replace("Hurst parameter", "Hurst");
+            value = value.replace("Lateral corr length", "CorrelationLength");
+            value = value.replace(" ", "");
+            std::string translated = "*" + value.toStdString();
+            std::cout << translated;
+            std::cout.flush();
+            double min = parameter->getRegisteredProperty(FitParameterItem::P_MIN).toDouble();
+            double max = parameter->getRegisteredProperty(FitParameterItem::P_MAX).toDouble();
+            double init = parameter->getRegisteredProperty(FitParameterItem::P_INIT).toDouble();
+            AttLimits limits;
+            if (min==max && min < init) {
+                limits = AttLimits::lowerLimited(min);
+            } else if (min==max && max > init) {
+                limits = AttLimits::upperLimited(max);
+            } else if (min < init && max > init) {
+                limits = AttLimits::limited(min, max);
+            } else {
+                limits = AttLimits::limitless();
+            }
+            m_fitsuite->addFitParameter(translated, init, limits);
+        }
+    }
 
-    QVBoxLayout *vlayout = new QVBoxLayout(this);
-    vlayout->setMargin(0);
-    vlayout->setSpacing(0);
-    //vlayout->addWidget(m_treeView);
-    //vlayout->addStretch();
-    this->setLayout(vlayout);
+    m_fitsuite->setMinimizer("Minuit2", m_fitModel->getMinimizerAlgorithm().toStdString());
 
+} catch(const std::exception& ex) {
+        QString message = QString::fromLatin1(ex.what());
+            m_fitprogress->updateLog(message);
+    }
+    return m_fitsuite;
 }
diff --git a/GUI/coregui/Views/FitWidgets/RunFitWidget.h b/GUI/coregui/Views/FitWidgets/RunFitWidget.h
index 730654046c53930db612fcc03791df6f43f35a42..00e4aae9505e6e28b15b1a4aa00e3e3a3c10733a 100644
--- a/GUI/coregui/Views/FitWidgets/RunFitWidget.h
+++ b/GUI/coregui/Views/FitWidgets/RunFitWidget.h
@@ -16,15 +16,56 @@
 #ifndef RUNFITWIDGET_H
 #define RUNFITWIDGET_H
 
+#include "WinDllMacros.h"
 #include <QWidget>
+#include <boost/shared_ptr.hpp>
 
+class QSlider;
+class QLabel;
+class QPushButton;
+class RunFitManager;
+class FitSuite;
+class FitProgressWidget;
+class FitModel;
+class SampleModel;
+class InstrumentModel;
+class ParameterizedItem;
+class SessionModel;
 
 class BA_CORE_API_ RunFitWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    RunFitWidget(QWidget *parent = 0);
+
+    RunFitWidget(FitModel *fitModel, QWidget *parent = 0);
+
+    // test only
+    boost::shared_ptr<FitSuite> init_test_fitsuite();
+
+public slots:
+
+    void onIntervalChanged(int value);
+
+    void onStartClicked();
+
+    void onStopClicked();
+
+    void onFittingStarted();
+
+    void onFittingFinished();
+
+private:
+
+    QPushButton *m_start_button;
+    QPushButton *m_stop_button;
+    QLabel *m_interval_label;
+    QSlider *m_interval_slider;
+    RunFitManager *m_runfitmanager;
+    FitProgressWidget *m_fitprogress;
+    FitModel *m_fitModel;
+
+    ParameterizedItem *getTopItemFromSelection(SessionModel *model, const QString &itemType, const QString &selectionType);
 };
 
 #endif
diff --git a/GUI/coregui/Views/TestView.cpp b/GUI/coregui/Views/TestView.cpp
index d2a5a3e524c3acf9d699cc108a6c786941452c64..f839ed73407cec1b9f6b5f8717417e947d398bb2 100644
--- a/GUI/coregui/Views/TestView.cpp
+++ b/GUI/coregui/Views/TestView.cpp
@@ -14,23 +14,56 @@
 // ************************************************************************** //
 #include "TestView.h"
 #include "MaskEditor.h"
+#include "RunFitWidget.h"
+#include "FitView.h"
+#include "mainwindow.h"
+#include "FitParameterWidget.h"
+#include "JobModel.h"
+#include <QMimeData>
 #include <QVBoxLayout>
 #include <AccordionWidget.h>
 #include <QLineEdit>
 #include <QCheckBox>
+#include <QTabWidget>
 
-TestView::TestView(QWidget *parent)
+
+
+// FIXME_DAVID Rename Ivona's FitView into ObsoleteFitView. And use nice name FitView for own purpose.
+//  -- suggestion: for consistency use prefix Obsolete for all classes you are goind to throw soon
+//  -- you may want to add to all Ivona's classes prefix Obsolete. Don't forget about 'ifndef' header guards
+
+// FIXME_DAVID Move your activity from TestView to FitView.
+// - FitView should contain QTabWidget with 3 tabs:
+// - 1) ImportDataWidget (empty for the moment) 2) FitSettingsWidget 3) RunFitWidget
+
+// FIXME_DAVID FitSettingsWidget should contain
+// - FitParametersWidget (for the moment), and later sample/instrument selector + MinimizerSettingsWidgert
+
+
+TestView::TestView(MainWindow *window, QWidget *parent)
     : QWidget(parent)
+    , m_mainWindow(window)
 {
-//    MaskEditor *maskEditor = new MaskEditor();
-//    QVBoxLayout *layout = new QVBoxLayout;
-//    layout->setMargin(0);
-//    layout->setSpacing(0);
-//    layout->addWidget(maskEditor);
-//    setLayout(layout);
+//    test_MaskEditor();
+//    test_AccordionWidget();
+    test_RunFitWidget();
 
-//    maskEditor->init_test_model();
+}
+
+void TestView::test_MaskEditor()
+{
+    MaskEditor *maskEditor = new MaskEditor();
+    QVBoxLayout *layout = new QVBoxLayout;
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    layout->addWidget(maskEditor);
+    setLayout(layout);
 
+    maskEditor->init_test_model();
+}
+
+void TestView::test_AccordionWidget()
+{
     AccordionWidget *myAccordion = new AccordionWidget();
     myAccordion->setMultiActive(true);
     // add the Accordion to your layout
@@ -101,5 +134,24 @@ TestView::TestView(QWidget *parent)
         contentFrame->layout()->addWidget(cb7);
 
     }
+}
+
+void TestView::test_RunFitWidget()
+{
+    // FIXME_DAVID Use consistent variable names: not 'maskEditor', but runFitWidget
+
+    //RunFitWidget *maskEditor = new RunFitWidget();
+    //FitView *fw = new FitView(m_mainWindow->getSampleModel(), m_mainWindow->getInstrumentModel());
+
+    //FitParameterWidget *fitting = new FitParameterWidget(m_mainWindow);
+    QVBoxLayout *layout = new QVBoxLayout;
+    QTabWidget *tabs = new QTabWidget;
+    //tabs->addTab(maskEditor, "Run Fit");
+    //tabs->addTab(fw, "FitView by Ivonna");
+    //tabs->addTab(fitting, "Test TreeView");
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    layout->addWidget(tabs);
+    setLayout(layout);
 
 }
diff --git a/GUI/coregui/Views/TestView.h b/GUI/coregui/Views/TestView.h
index 562ac072a9c97006f9c9f59218293592f58d95f0..eebc37c0dc61df4fe365cfb6a8db7bae6175a02c 100644
--- a/GUI/coregui/Views/TestView.h
+++ b/GUI/coregui/Views/TestView.h
@@ -18,12 +18,19 @@
 
 #include <QWidget>
 
+class MainWindow;
+
 class TestView : public QWidget
 {
     Q_OBJECT
 public:
-    TestView(QWidget *parent = 0);
+    TestView(MainWindow *window, QWidget *parent = 0);
 
+private:
+    void test_MaskEditor();
+    void test_AccordionWidget();
+    void test_RunFitWidget();
+    MainWindow *m_mainWindow;
 };
 
 #endif
diff --git a/GUI/coregui/mainwindow/UpdateNotifier.cpp b/GUI/coregui/mainwindow/UpdateNotifier.cpp
index 896d57d1959648bccd497e173029af117703335b..ada6ad2554419af207ad2e8d39d9627b0a2eaf0e 100644
--- a/GUI/coregui/mainwindow/UpdateNotifier.cpp
+++ b/GUI/coregui/mainwindow/UpdateNotifier.cpp
@@ -15,19 +15,15 @@
 
 #include "UpdateNotifier.h"
 #include "mainwindow_constants.h"
+#include "GUIHelpers.h"
 #include <QtNetwork>
-#include <GUIHelpers.h>
 #include <QMessageBox>
 
-
 UpdateNotifier::UpdateNotifier(QObject *parent)
-    : QObject(parent)
-    , m_networkAccessManager(new QNetworkAccessManager(parent))
+    : QObject(parent), m_networkAccessManager(new QNetworkAccessManager(parent))
 {
-    connect(m_networkAccessManager,
-            SIGNAL(finished(QNetworkReply*)),
-            this,
-            SLOT(replyFinished(QNetworkReply*)));
+    connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply *)), this,
+            SLOT(replyFinished(QNetworkReply *)));
 }
 
 void UpdateNotifier::checkForUpdates()
@@ -37,8 +33,7 @@ void UpdateNotifier::checkForUpdates()
         settings.beginGroup(Constants::S_UPDATES);
         if (settings.value(Constants::S_CHECKFORUPDATES).toBool()) {
             m_networkAccessManager->get(QNetworkRequest(QUrl(Constants::S_VERSION_URL)));
-        }
-        else
+        } else
             emit onUpdateNotification(QString(""));
     }
 }
@@ -46,11 +41,9 @@ void UpdateNotifier::checkForUpdates()
 void UpdateNotifier::replyFinished(QNetworkReply *reply)
 {
     QString replyString;
-    if(reply->error() == QNetworkReply::NoError)
-    {
-        if (reply->isReadable())
-        {
-            //Reading the first line of ChangeLog
+    if (reply->error() == QNetworkReply::NoError) {
+        if (reply->isReadable()) {
+            // Reading the first line of ChangeLog
             replyString = QString::fromUtf8(reply->readLine().data());
             int versionIndex = replyString.indexOf("-") + 1;
             int versionIndexEnd = replyString.indexOf(",", versionIndex);
@@ -58,7 +51,7 @@ void UpdateNotifier::replyFinished(QNetworkReply *reply)
             QString myVersion = GUIHelpers::getBornAgainVersionString();
 
             // Testwise degrade version
-            //QString myVersion = QString("1.3.0");
+            // QString myVersion = QString("1.3.0");
 
             int compareResult = versionString.compare(myVersion);
             if (compareResult > 0) {
diff --git a/GUI/coregui/mainwindow/UpdateNotifier.h b/GUI/coregui/mainwindow/UpdateNotifier.h
index 05511755f2d536cfc5c3f352bb8716a3b0d4039c..fdb505ec0b254209fa854c4e8134b9f5c362b014 100644
--- a/GUI/coregui/mainwindow/UpdateNotifier.h
+++ b/GUI/coregui/mainwindow/UpdateNotifier.h
@@ -16,8 +16,8 @@
 #ifndef UPDATENOTIFIER_H
 #define UPDATENOTIFIER_H
 
-#include <QObject>
 #include "WinDllMacros.h"
+#include <QObject>
 
 class QNetworkAccessManager;
 class QNetworkReply;
diff --git a/GUI/coregui/mainwindow/mainwindow.cpp b/GUI/coregui/mainwindow/mainwindow.cpp
index d5d871976575b8c531abeafa544269c8e6246ee8..5e58dca33cb064906d34fe76aae893b806af85fd 100644
--- a/GUI/coregui/mainwindow/mainwindow.cpp
+++ b/GUI/coregui/mainwindow/mainwindow.cpp
@@ -56,12 +56,12 @@
 #include "SampleModel.h"
 #include "JobView.h"
 #include "aboutapplicationdialog.h"
-#include "FitModel.h"
-#include "FitProxyModel.h"
 #include "FitView.h"
 #include "TestView.h"
 #include "GUIHelpers.h"
 #include "UpdateNotifier.h"
+#include "FitModel.h"
+#include "FitParameterItems.h"
 
 #include <boost/scoped_ptr.hpp>
 
@@ -89,9 +89,9 @@ MainWindow::MainWindow(QWidget *parent)
     , m_sampleModel(0)
     , m_instrumentModel(0)
     , m_materialModel(0)
+    , m_fitModel(0)
     , m_materialEditor(0)
     , m_toolTipDataBase(new ToolTipDataBase(this))
-    , m_fitProxyModel(0)
     , m_updateNotifier(new UpdateNotifier(this))
 {
     QCoreApplication::setApplicationName(QLatin1String(Constants::APPLICATION_NAME));
@@ -124,21 +124,15 @@ MainWindow::MainWindow(QWidget *parent)
     m_sampleView = new SampleView(m_sampleModel, m_instrumentModel);
     m_simulationView = new SimulationView(this);
 
-//    TestView *testView = new TestView(this);
-    //m_fitView = new FitView(m_fitProxyModel, this);
-
     m_jobView = new JobView(m_jobModel, m_projectManager);
-
+    //m_fitView = new FitView(this);
 
     m_tabWidget->insertTab(WELCOME, m_welcomeView, QIcon(":/images/main_home.png"), "Welcome");
     m_tabWidget->insertTab(INSTRUMENT, m_instrumentView, QIcon(":/images/main_instrument.png"), "Instrument");
     m_tabWidget->insertTab(SAMPLE, m_sampleView, QIcon(":/images/main_sample.png"), "Sample");
-    //m_tabWidget->insertTab(3, m_scriptView, QIcon(":/images/mode_script.png"), "Python scripts");
     m_tabWidget->insertTab(SIMULATION, m_simulationView, QIcon(":/images/main_simulation.png"), "Simulation");
     m_tabWidget->insertTab(JOB, m_jobView, QIcon(":/images/main_jobqueue.png"), "Jobs");
-//    m_tabWidget->insertTab(TEST_VIEW, testView, QIcon(":/images/main_simulation.png"), "Test");
-    //m_tabWidget->insertTab(FitViewTab, m_fitView, QIcon(":/images/main_simulation.png"), "Fit");
-    //m_tabWidget->insertTab(FIT_VIEW, new TestView(this), QIcon(":/images/main_simulation.png"), "Test");
+    //m_tabWidget->insertTab(FIT, m_fitView, QIcon(":/images/main_jobqueue.png"), "Fit");
 
     m_tabWidget->setCurrentIndex(WELCOME);
 
@@ -158,9 +152,6 @@ MainWindow::MainWindow(QWidget *parent)
             m_welcomeView, SLOT(setNotificationText(const QString &)));
 
     m_projectManager->createNewProject();
-
-//    testGUIObjectBuilder();
-
 }
 
 MainWindow::~MainWindow()
@@ -302,7 +293,8 @@ void MainWindow::createInstrumentModel()
 
 void MainWindow::createFitModel()
 {
-    m_fitProxyModel = new FitProxyModel;
+    delete m_fitModel;
+    m_fitModel = new FitModel(m_sampleModel, m_instrumentModel, this);
 }
 
 //! reset all models to initial state
@@ -323,6 +315,15 @@ void MainWindow::resetModels()
     instrument->setItemName("Default GISAS");
     m_instrumentModel->insertNewItem(Constants::DetectorType, m_instrumentModel->indexOfItem(instrument));
     m_instrumentModel->insertNewItem(Constants::BeamType, m_instrumentModel->indexOfItem(instrument));
+
+    /*m_fitModel->clear();
+    m_fitModel->insertNewItem(Constants::FitParameterContainerType, QModelIndex());
+    ParameterizedItem *selection = m_fitModel->insertNewItem(Constants::FitSelectionType, QModelIndex());
+    selection->setRegisteredProperty(FitSelectionItem::P_SAMPLE, "MultiLayer");
+    selection->setRegisteredProperty(FitSelectionItem::P_INSTRUMENT, "Instrument0");
+    m_fitModel->insertNewItem(Constants::MinimizerSettingsType, QModelIndex());
+    m_fitModel->insertNewItem(Constants::InputDataType, QModelIndex());*/
+
 }
 
 void MainWindow::testGUIObjectBuilder()
diff --git a/GUI/coregui/mainwindow/mainwindow.h b/GUI/coregui/mainwindow/mainwindow.h
index bdc0bcd58d420a95b65f68a8b365ea6ff6de80a5..cfdbf9044f19a27f3aaf5e5550f4bd6e7bf6148d 100644
--- a/GUI/coregui/mainwindow/mainwindow.h
+++ b/GUI/coregui/mainwindow/mainwindow.h
@@ -43,18 +43,17 @@ class MaterialEditor;
 class ToolTipDataBase;
 class MaterialModel;
 class SampleModel;
-class FitProxyModel;
 class FitView;
 class JobModel;
 class UpdateNotifier;
-
+class FitModel;
 
 class BA_CORE_API_ MainWindow : public Manhattan::FancyMainWindow
 {
     Q_OBJECT
 
 public:
-    enum ETabViewId { WELCOME, INSTRUMENT, SAMPLE, SIMULATION, JOB, TEST_VIEW};
+    enum ETabViewId { WELCOME, INSTRUMENT, SAMPLE, SIMULATION, JOB, FIT};
 
     explicit MainWindow(QWidget *parent = 0);
     virtual ~MainWindow();
@@ -63,6 +62,7 @@ public:
     InstrumentModel *getInstrumentModel() { return m_instrumentModel; }
     SampleModel *getSampleModel() { return m_sampleModel; }
     JobModel *getJobModel() { return m_jobModel; }
+    FitModel *getFitModel() { return m_fitModel; }
     Manhattan::ProgressBar *getProgressBar() { return m_progressBar; }
     ActionManager *getActionManager() { return m_actionManager; }
     ProjectManager *getProjectManager() { return m_projectManager; }
@@ -100,9 +100,9 @@ private:
     SampleModel *m_sampleModel; //!< model for all samples
     InstrumentModel *m_instrumentModel; //!< model for all instruments
     MaterialModel *m_materialModel; //!< model for all materials
+    FitModel *m_fitModel; //!< model for fitting
     MaterialEditor *m_materialEditor;
     ToolTipDataBase *m_toolTipDataBase;
-    FitProxyModel *m_fitProxyModel;
     UpdateNotifier *m_updateNotifier;
 
     void createModels();
diff --git a/GUI/coregui/mainwindow/projectdocument.cpp b/GUI/coregui/mainwindow/projectdocument.cpp
index 861683781388b08f2349470aed709f8964d648b3..e56cd02e0c5e4e474081dca90a592193eece93a6 100644
--- a/GUI/coregui/mainwindow/projectdocument.cpp
+++ b/GUI/coregui/mainwindow/projectdocument.cpp
@@ -18,6 +18,7 @@
 #include "InstrumentModel.h"
 #include "JobQueueData.h"
 #include "JobModel.h"
+#include "FitModel.h"
 #include "JobItem.h"
 #include "IntensityDataItem.h"
 #include "SampleModel.h"
@@ -43,7 +44,7 @@ const QString XML_FORMAT_ERROR = "XML_FORMAT_ERROR";
 }
 
 ProjectDocument::ProjectDocument()
-    : m_materialModel(0), m_instrumentModel(0), m_sampleModel(0), m_jobModel(0)
+    : m_materialModel(0), m_instrumentModel(0), m_sampleModel(0), m_jobModel(0), m_fitModel(0)
     , m_modified(false), m_documentStatus(STATUS_OK), m_messageService(0)
 {
     setObjectName("ProjectDocument");
@@ -132,6 +133,15 @@ void ProjectDocument::setJobModel(JobModel *jobModel)
     }
 }
 
+void ProjectDocument::setFitModel(FitModel *fitModel)
+{
+    if (fitModel != m_fitModel) {
+        disconnectModel(m_fitModel);
+        m_fitModel = fitModel;
+        connectModel(m_fitModel);
+    }
+}
+
 bool ProjectDocument::save()
 {
     reviseOutputData();
@@ -251,6 +261,7 @@ void ProjectDocument::readFrom(QIODevice *device)
     disconnectModel(m_instrumentModel);
     disconnectModel(m_sampleModel);
     disconnectModel(m_jobModel);
+    //disconnectModel(m_fitModel);
 
     QXmlStreamReader reader(device);
 
@@ -274,8 +285,9 @@ void ProjectDocument::readFrom(QIODevice *device)
 
             } else if (reader.name() == SessionXML::JobModelTag) {
                 readModel(m_jobModel, &reader);
-
-            }
+            } /*else if (reader.name() == SessionXML::FitModelTag) {
+                readModel(m_fitModel, &reader);
+            }*/
         }
     }
 
@@ -289,6 +301,7 @@ void ProjectDocument::readFrom(QIODevice *device)
     connectModel(m_instrumentModel);
     connectModel(m_sampleModel);
     connectModel(m_jobModel);
+    //connectModel(m_fitModel);
 }
 
 void ProjectDocument::writeTo(QIODevice *device)
@@ -308,6 +321,7 @@ void ProjectDocument::writeTo(QIODevice *device)
     m_instrumentModel->writeTo(&writer);
     m_sampleModel->writeTo(&writer);
     m_jobModel->writeTo(&writer);
+    //m_fitModel->writeTo(&writer);
 
     writer.writeEndElement(); // BornAgain tag
     writer.writeEndDocument();
diff --git a/GUI/coregui/mainwindow/projectdocument.h b/GUI/coregui/mainwindow/projectdocument.h
index 8ad115f8e0a20a0e6026c5d95a765bec60c3e9b9..7d138c4e5bf402373a2ef3268ab8039412b6074b 100644
--- a/GUI/coregui/mainwindow/projectdocument.h
+++ b/GUI/coregui/mainwindow/projectdocument.h
@@ -28,6 +28,7 @@ class InstrumentModel;
 class MaterialModel;
 class SampleModel;
 class JobModel;
+class FitModel;
 class QXmlStreamReader;
 class WarningMessageService;
 
@@ -76,6 +77,7 @@ public:
     void setInstrumentModel(InstrumentModel *instrumentModel);
     void setSampleModel(SampleModel *sampleModel);
     void setJobModel(JobModel *jobModel);
+    void setFitModel(FitModel *fitModel);
 
     bool save();
     bool load(const QString &project_file_name);
@@ -122,6 +124,7 @@ private:
     InstrumentModel *m_instrumentModel;
     SampleModel *m_sampleModel;
     JobModel *m_jobModel;
+    FitModel *m_fitModel;
     bool m_modified;
     EDocumentStatus m_documentStatus;
     WarningMessageService *m_messageService;
diff --git a/GUI/coregui/mainwindow/projectmanager.cpp b/GUI/coregui/mainwindow/projectmanager.cpp
index d154262e814179ae92af1c737e9a89a3fc5ee7b6..38d32bbc8847508a8e585ed0b5a9296667ff2571 100644
--- a/GUI/coregui/mainwindow/projectmanager.cpp
+++ b/GUI/coregui/mainwindow/projectmanager.cpp
@@ -97,6 +97,7 @@ void ProjectManager::createNewProject()
     m_project_document->setInstrumentModel(m_mainWindow->getInstrumentModel());
     m_project_document->setSampleModel(m_mainWindow->getSampleModel());
     m_project_document->setJobModel(m_mainWindow->getJobModel());
+    m_project_document->setFitModel(m_mainWindow->getFitModel());
     m_project_document->setMessageService(m_messageService);
 }
 
@@ -208,6 +209,7 @@ void ProjectManager::openProject(QString fileName)
         addToRecentProjects();
     }
 
+    emit projectOpened();
     emit modified();
 }
 
diff --git a/GUI/coregui/mainwindow/projectmanager.h b/GUI/coregui/mainwindow/projectmanager.h
index 4c74dd25348268a9aaa10c4ccc0229b1f1b5c03a..c521b6cf9a2440e39badd34732a29aac9371b5d5 100644
--- a/GUI/coregui/mainwindow/projectmanager.h
+++ b/GUI/coregui/mainwindow/projectmanager.h
@@ -46,6 +46,7 @@ public:
 
 signals:
     void modified();
+    void projectOpened();
 
 public slots:
     void clearRecentProjects();
diff --git a/GUI/coregui/utils/DeleteEventFilter.cpp b/GUI/coregui/utils/DeleteEventFilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f351c9aa06ed52c64f2ff7fcf43f2460a2cb97d0
--- /dev/null
+++ b/GUI/coregui/utils/DeleteEventFilter.cpp
@@ -0,0 +1,31 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/utils/CustomEventFilters.cpp
+//! @brief     Defines classes releted to event filtering
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "DeleteEventFilter.h"
+#include <QEvent>
+#include <QKeyEvent>
+
+bool DeleteEventFilter::eventFilter( QObject *dist, QEvent *event )
+{
+    Q_UNUSED(dist);
+    if( event->type() == QEvent::KeyPress )
+    {
+        QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
+        if( keyEvent->key() == Qt::Key_Delete ) {
+            emit removeItem();
+        }
+    }
+    return QObject::eventFilter(dist, event);
+}
diff --git a/GUI/coregui/utils/DeleteEventFilter.h b/GUI/coregui/utils/DeleteEventFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2941592e5ec1ef9ffe20de4155063fc449c7310
--- /dev/null
+++ b/GUI/coregui/utils/DeleteEventFilter.h
@@ -0,0 +1,39 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/utils/CustomEventFilters.h
+//! @brief     Defines classes releted to event filtering
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef DELETEEVENTFILTERS_H
+#define DELETEEVENTFILTERS_H
+
+#include "WinDllMacros.h"
+#include <QObject>
+
+class QEvent;
+
+//! Filter out space bar key events, which is special case for dialog windows
+
+class DeleteEventFilter : public QObject
+{
+    Q_OBJECT
+public:
+  DeleteEventFilter( QObject *parent = 0 ) : QObject( parent ) {}
+
+protected:
+  bool eventFilter( QObject *dist, QEvent *event );
+
+signals:
+  void removeItem();
+};
+
+#endif
diff --git a/GUI/coregui/utils/ItemIDFactory.cpp b/GUI/coregui/utils/ItemIDFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..81fecfeaf655f666f80945df4f0320d4d4e4da24
--- /dev/null
+++ b/GUI/coregui/utils/ItemIDFactory.cpp
@@ -0,0 +1,46 @@
+#include "ItemIDFactory.h"
+
+
+ItemIDFactory& ItemIDFactory::instance()
+{
+    static ItemIDFactory instance;
+    return instance;
+}
+
+QString ItemIDFactory::createID(ParameterizedItem *toBeInsertedItem){
+
+    QUuid id = QUuid::createUuid();
+    QString id_String = id.toString();
+
+    // prevent duplicates (very improbable that this ever happens though)
+    while(instance().IDtoItemMap.contains(id_String)) {
+        id = QUuid::createUuid();
+        id_String = id.toString();
+    }
+    instance().ItemtoIDMap.insert(toBeInsertedItem, id_String);
+    instance().IDtoItemMap.insert(id_String, toBeInsertedItem);
+
+    return id_String;
+}
+
+QString ItemIDFactory::getID(ParameterizedItem *existingItem)
+{
+    if(instance().ItemtoIDMap.contains(existingItem))
+        return instance().ItemtoIDMap.value(existingItem);
+    else
+        return QString();
+}
+
+ParameterizedItem* ItemIDFactory::getItem(QString existingID)
+{
+    if(instance().IDtoItemMap.contains(existingID))
+        return instance().IDtoItemMap.value(existingID);
+    else
+        return nullptr;
+}
+
+int ItemIDFactory::IDSize()
+{
+    static QUuid id = QUuid::createUuid();
+    return id.toString().size();
+}
diff --git a/GUI/coregui/utils/ItemIDFactory.h b/GUI/coregui/utils/ItemIDFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..f259fbe48e0feb21b232c604b49215615b498091
--- /dev/null
+++ b/GUI/coregui/utils/ItemIDFactory.h
@@ -0,0 +1,48 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      coregui/Util/ItemIDFactory.h
+//! @brief     Defines class ItemIDFactory
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+#ifndef ItemIDFactory_H
+#define ItemIDFactory_H
+
+#include <QUuid>
+#include <QMap>
+
+class ParameterizedItem;
+
+class ItemIDFactory {
+public:
+    // delete copy/move constructor/assignment:
+    ItemIDFactory(const ItemIDFactory&) = delete;
+    ItemIDFactory(ItemIDFactory&&) = delete;
+    ItemIDFactory& operator=(const ItemIDFactory&) = delete;
+    ItemIDFactory& operator=(ItemIDFactory&&) = delete;
+
+    static ItemIDFactory& instance();
+
+    static QString createID(ParameterizedItem* toBeInsertedItem);
+
+    static QString getID(ParameterizedItem* existingItem);
+
+    static ParameterizedItem* getItem(QString existingID);
+
+    static int IDSize();
+
+private:
+    ItemIDFactory() = default;
+
+    QMap<QString, ParameterizedItem*> IDtoItemMap;
+    QMap<ParameterizedItem*, QString> ItemtoIDMap;
+};
+
+#endif