diff --git a/App/inc/TestFittingModule4.h b/App/inc/TestFittingModule4.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9a01eddd2cd04ae7d825e99c46779924fdeb262
--- /dev/null
+++ b/App/inc/TestFittingModule4.h
@@ -0,0 +1,54 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      App/inc/TestFittingModule4.h
+//! @brief     Defines class TestFittingModule4.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef TESTFITTINGMODULE4_H_
+#define TESTFITTINGMODULE4_H_
+
+#include "IApplicationTest.h"
+#include "OutputData.h"
+#include "ISample.h"
+#include "Simulation.h"
+#include "ISampleBuilder.h"
+
+class FitSuite;
+
+//! Testing Genetic and SimmulatedAnnealing minimizers
+//!
+//! Cylinders on top of substrate without interference. Combination of two
+//! minimizers is used: Genetic algorithm to run quickly through parameter space
+//! to identify most promising local minima and then Migrad to explore it.
+
+class TestFittingModule4 : public IApplicationTest
+{
+public:
+    TestFittingModule4();
+    virtual ~TestFittingModule4();
+    virtual void execute();
+
+private:
+    void initializeSample();
+    void initializeSimulation();
+    void initializeRealData();
+
+    OutputData<double> *mp_real_data;
+    OutputData<double> *mp_simulated_data;
+    Simulation *mp_simulation;
+    ISample *mp_sample;
+    FitSuite *m_fitSuite;
+};
+
+#endif /* TESTFITTINGMODULE4_H_ */
+
+
diff --git a/App/inc/TestFumiliLMA.h b/App/inc/TestFumiliLMA.h
index 8f17bea550934a9b478b35762aec786cc44bf299..f1f975dbd40233804d15929500054cad9aeb6647 100644
--- a/App/inc/TestFumiliLMA.h
+++ b/App/inc/TestFumiliLMA.h
@@ -32,7 +32,7 @@ class IFunctionObject;
 class IChiSquaredModule;
 class TCanvas;
 
-//! Test of ROOT's LMA-based minimizers Fumili and GSLMultiFit
+//! Test of ROOT's LMA-based minimizers Fumili and GSLLMA(GSLMultiFit)
 
 class TestFumiliLMA : public IApplicationTest
 {
diff --git a/App/inc/TestPerformance.h b/App/inc/TestPerformance.h
index 2b8abe9e7aa5e59c8ce8a21d215455c9d4b556e2..7eb3a6ec6c1b28a21aa086fa1ec20a4cde5b2568 100644
--- a/App/inc/TestPerformance.h
+++ b/App/inc/TestPerformance.h
@@ -2,9 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      App/inc/TestPerformance.h
-//! @brief     Defines classes TestPerformance, PerfTest_SpecularMatrix,
-//!            PerfTest_Pyramid, PerfTest_RotatedPyramid, PerfTest_MesoCrystal
+//! @file      App/inc/TestPerformance2.h
+//! @brief     Defines classe TestPerformance2 for logging performance changes
 //
 //! Homepage:  apps.jcns.fz-juelich.de/BornAgain
 //! License:   GNU General Public License v3 or higher (see COPYING)
@@ -18,107 +17,74 @@
 #define TESTPERFORMANCE_H
 
 #include "IApplicationTest.h"
-#include "ISample.h"
-#include "Simulation.h"
+#include "INamed.h"
 
 #include <string>
 #include <vector>
 #include <map>
 #include <iostream>
 
+class PerformanceTest;
+
 //! Run standard tests to trace changes in the performance.
 
 class TestPerformance : public IApplicationTest
 {
 public:
-    //! class to hold performance information over functional test
-    class PerformanceTestInfo {
-    public:
-        PerformanceTestInfo(IApplicationTest *test, int nrepetitions)
-            : m_test(test), m_nrepetitions(nrepetitions), m_results(0){}
-        virtual ~PerformanceTestInfo(){ delete m_test; }
-        IApplicationTest *m_test;
-        double m_nrepetitions;
-        double m_results;
-    };
-
-    typedef std::vector<PerformanceTestInfo *> performance_tests_t;
-
     TestPerformance();
     virtual ~TestPerformance();
-
     virtual void execute();
 private:
-    //! fill system information
-    void get_sysinfo();
-
-    //! save performance information on disk
-    void write_performance();
-
-    //! Returns delimeter between columns.
-    std::string get_delimeter() { return std::string(" | "); }
-
-    std::map<std::string, std::string > m_performance_info; //!< holds system information
-    performance_tests_t m_tests; //!< list of tests for performance measurements
-
+    void write_results();
+    void write_header(std::ofstream &file);
+    void write_performance(std::ofstream &file);
+    void set_sysinfo(PerformanceTest *test);
+    std::vector<PerformanceTest *> m_tests;
 };
 
 
-//! @class PerfTest_SpecularMatrix
-//! measurement of the performance in specular matrix calculation
-class PerfTest_SpecularMatrix : public IApplicationTest
-{
+//! class for performance measurements
+class PerformanceTest : public IApplicationTest {
 public:
-    PerfTest_SpecularMatrix() : IApplicationTest("SpecularMatrix"), m_sample(0){}
-    virtual ~PerfTest_SpecularMatrix() { }
-    void initialise(ProgramOptions *p_options);
-    void execute();
-    ISample *m_sample;
-};
+    PerformanceTest(const std::string &name, int nrepetitions)
+        : IApplicationTest(name)
+        , m_nrepetitions(nrepetitions)
+        , m_nthreads(0)
+        , m_cpu_time(0)
+        , m_real_time(0){}
 
-//! @class PerfTest_Pyramid
-//! measurement of the performance in pyramid form factor calculations
-class PerfTest_Pyramid : public IApplicationTest
-{
-public:
-    PerfTest_Pyramid()
-        : IApplicationTest("Pyramid"), m_sample(0), m_simulation(0) {}
-    virtual ~PerfTest_Pyramid() { delete m_simulation; }
-    void initialise(ProgramOptions *p_options);
-    void execute();
-    ISample *m_sample;
-    Simulation *m_simulation;
+    virtual ~PerformanceTest(){}
+
+    virtual void execute();
+    virtual void runTests();
+
+    double m_nrepetitions;
+    int m_nthreads;
+    double m_cpu_time;
+    double m_real_time;
+    std::string m_datime;
+    std::string m_hostname;
+    std::string m_sysinfo;
 };
 
-//! @class PerfTest_RotatedPyramid
-//! measurement of the performance in pyramid formfactor and in rotation mechanism
-class PerfTest_RotatedPyramid : public IApplicationTest
+
+//! custom test for specular matrix
+class SpecularMatrixPerformanceTest : public PerformanceTest
 {
 public:
-    PerfTest_RotatedPyramid()
-        : IApplicationTest("RotatedPyramid"), m_sample(0), m_simulation(0) {}
-    virtual ~PerfTest_RotatedPyramid() { delete m_simulation; }
-    void initialise(ProgramOptions *p_options);
-    void execute();
-    ISample *m_sample;
-    Simulation *m_simulation;
+    SpecularMatrixPerformanceTest(const std::string &name, int nrepetitions)
+        : PerformanceTest(name, nrepetitions){}
+    virtual void runTests();
 };
 
-
-//! @class PerfTest_MesoCrystal
-//! measurement of the performance iof meso crystal
-class PerfTest_MesoCrystal : public IApplicationTest
+//! custom test for specular magnetic
+class SpecularMagneticPerformanceTest : public PerformanceTest
 {
 public:
-    PerfTest_MesoCrystal()
-        : IApplicationTest("MesoCrystal"), m_sample(0), m_simulation(0) {}
-    virtual ~PerfTest_MesoCrystal() { delete m_simulation; }
-    void initialise(ProgramOptions *p_options);
-    void execute();
-    ISample *m_sample;
-    Simulation *m_simulation;
+    SpecularMagneticPerformanceTest(const std::string &name, int nrepetitions)
+        : PerformanceTest(name, nrepetitions){}
+    virtual void runTests();
 };
 
-#endif // TESTPERFORMANCE_H
-
 
+#endif
diff --git a/App/inc/TestPerformance2.h b/App/inc/TestPerformance2.h
deleted file mode 100644
index 73227075e904c3a6bfdcac95ce502b0554c71867..0000000000000000000000000000000000000000
--- a/App/inc/TestPerformance2.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      App/inc/TestPerformance2.h
-//! @brief     Defines classe TestPerformance2 for logging performance changes
-//
-//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
-//! License:   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2013
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef TESTPERFORMANCE2_H
-#define TESTPERFORMANCE2_H
-
-#include "IApplicationTest.h"
-#include "INamed.h"
-
-#include <string>
-#include <vector>
-#include <map>
-#include <iostream>
-
-class PerformanceTest;
-
-//! Run standard tests to trace changes in the performance.
-
-class TestPerformance2 : public IApplicationTest
-{
-public:
-    TestPerformance2();
-    virtual ~TestPerformance2();
-    virtual void execute();
-private:
-    void write_results();
-    void write_header(std::ofstream &file);
-    void write_performance(std::ofstream &file);
-    void set_sysinfo(PerformanceTest *test);
-    std::vector<PerformanceTest *> m_tests;
-};
-
-
-//! class for performance measurements
-class PerformanceTest : public IApplicationTest {
-public:
-    PerformanceTest(const std::string &name, int nrepetitions)
-        : IApplicationTest(name)
-        , m_nrepetitions(nrepetitions)
-        , m_nthreads(0)
-        , m_cpu_time(0)
-        , m_real_time(0){}
-
-    virtual ~PerformanceTest(){}
-
-    virtual void execute();
-    virtual void runTests();
-
-    double m_nrepetitions;
-    int m_nthreads;
-    double m_cpu_time;
-    double m_real_time;
-    std::string m_datime;
-    std::string m_hostname;
-    std::string m_sysinfo;
-};
-
-
-//! custom test for specular matrix
-class SpecularMatrixPerformanceTest : public PerformanceTest
-{
-public:
-    SpecularMatrixPerformanceTest(const std::string &name, int nrepetitions)
-        : PerformanceTest(name, nrepetitions){}
-    virtual void runTests();
-};
-
-//! custom test for specular magnetic
-class SpecularMagneticPerformanceTest : public PerformanceTest
-{
-public:
-    SpecularMagneticPerformanceTest(const std::string &name, int nrepetitions)
-        : PerformanceTest(name, nrepetitions){}
-    virtual void runTests();
-};
-
-
-#endif
diff --git a/App/src/ApplicationTestFactory.cpp b/App/src/ApplicationTestFactory.cpp
index abdcd8d2a371d27094ff3a43c841671a696ef710..e087a449658ad214ae31267f882044b2122f3511 100644
--- a/App/src/ApplicationTestFactory.cpp
+++ b/App/src/ApplicationTestFactory.cpp
@@ -21,6 +21,7 @@
 #include "TestFittingModule1.h"
 #include "TestFittingModule2.h"
 #include "TestFittingModule3.h"
+#include "TestFittingModule4.h"
 #include "TestFormFactor.h"
 #include "TestFormFactors.h"
 #include "TestFourier.h"
@@ -33,7 +34,6 @@
 #include "TestMiscellaneous.h"
 #include "TestMultiLayerRoughness.h"
 #include "TestPerformance.h"
-#include "TestPerformance2.h"
 #include "TestPolarizedDWBA.h"
 #include "TestPolarizedDWBATerms.h"
 #include "TestPolarizedMeso.h"
@@ -193,22 +193,22 @@ void RegisterApplicationTests(ApplicationTestFactory *p_test_factory)
     p_test_factory->registerItem(
         "fitting1",
         IFactoryCreateFunction<TestFittingModule1, IApplicationTest>,
-        "functional test: fit module 2 params");
+        "functional test: basing fitting 2 params");
     p_test_factory->registerItem(
         "fitting2",
         IFactoryCreateFunction<TestFittingModule2, IApplicationTest>,
-        "functional test: fit module 5 params");
+        "functional test: fitting with strategies");
     p_test_factory->registerItem(
         "fitting3",
         IFactoryCreateFunction<TestFittingModule3, IApplicationTest>,
-        "functional test: fit module 4 params, 1d scans");
+        "functional test: fitting via 1D cuts");
     p_test_factory->registerItem(
-        "performance1",
-        IFactoryCreateFunction<TestPerformance, IApplicationTest>,
-        "functional test: run performance test for several predefined tasks");
+        "fitting4",
+        IFactoryCreateFunction<TestFittingModule4, IApplicationTest>,
+        "functional test: testing genetic minimizer");
     p_test_factory->registerItem(
-        "performance2",
-        IFactoryCreateFunction<TestPerformance2, IApplicationTest>,
+        "performance",
+        IFactoryCreateFunction<TestPerformance, IApplicationTest>,
         "functional test: run performance test for several predefined tasks");
     p_test_factory->registerItem(
         "roughdwba",
@@ -226,7 +226,7 @@ void RegisterApplicationTests(ApplicationTestFactory *p_test_factory)
         "fumili",
         IFactoryCreateFunction<TestFumiliLMA, IApplicationTest>,
         "functional test: test of ROOT's LMA-based minimizers Fumili and "
-        "GSLMultiFit");
+        "GSLLMA");
     p_test_factory->registerItem(
         "toyexp",
         IFactoryCreateFunction<TestToySimulation, IApplicationTest>,
diff --git a/App/src/TestFittingModule1.cpp b/App/src/TestFittingModule1.cpp
index 78ffa9bbf7604198a7baaac532dd110198ce0d69..93208858b058986faf213154af3b7ad90194c481 100644
--- a/App/src/TestFittingModule1.cpp
+++ b/App/src/TestFittingModule1.cpp
@@ -78,7 +78,7 @@ void TestFittingModule1::execute()
 
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") );
-    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") ); // LMA
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") );
@@ -141,10 +141,10 @@ void TestFittingModule1::initializeSample1()
         throw NullPointerException("TestFittingModule::initializeSample() -> Error! No FitSuite is defined");
     }
 
-    m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::lowerLimited(0.01) );
-    m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::lowerLimited(0.01) );
-//    m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 10.) );
-//    m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 10.) );
+//    m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::lowerLimited(0.01) );
+//    m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::lowerLimited(0.01) );
+    m_fitSuite->addFitParameter("*height", 4.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 10.) );
+    m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 10.) );
 }
 
 
diff --git a/App/src/TestFittingModule4.cpp b/App/src/TestFittingModule4.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86fff6c6b6449aecb719b442468bbec279e5b1c9
--- /dev/null
+++ b/App/src/TestFittingModule4.cpp
@@ -0,0 +1,178 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      App/src/TestFittingModule4.cpp
+//! @brief     Implements class TestFittingModule4.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "TestFittingModule4.h"
+#include "FitSuite.h"
+#include "MinimizerFactory.h"
+#include "Units.h"
+#include "FitSuiteObserverFactory.h"
+#include "HomogeneousMaterial.h"
+#include "MultiLayer.h"
+#include "FormFactors.h"
+#include "MaterialManager.h"
+#include "IsGISAXSTools.h"
+#include "ROOTMinimizer.h"
+#include "Math/GeneticMinimizer.h"
+#include "Math/GenAlgoOptions.h"
+#include "FitStrategyAdjustMinimizer.h"
+
+TestFittingModule4::TestFittingModule4()
+    : mp_real_data(0)
+    , mp_simulated_data(0)
+    , mp_simulation(0)
+    , mp_sample(0)
+    , m_fitSuite(0)
+{
+    m_fitSuite = new FitSuite();
+}
+
+
+TestFittingModule4::~TestFittingModule4()
+{
+    delete mp_real_data;
+    delete mp_simulated_data;
+    delete mp_simulation;
+    delete mp_sample;
+}
+
+
+void TestFittingModule4::execute()
+{
+    // initializing data
+    initializeSample();
+    initializeSimulation();
+    initializeRealData();
+
+    ChiSquaredModule chiModule;
+    //chiModule.setChiSquaredFunction( SquaredFunctionSimError() );
+    chiModule.setChiSquaredFunction( SquaredFunctionDefault() );
+
+    m_fitSuite->addSimulationAndRealData(*mp_simulation, *mp_real_data, chiModule);
+
+    m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") );
+
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") );
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") );
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") );
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") );
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") );
+
+
+    //m_fitSuite->getMinimizer()->getOptions().setPrintLevel(10);
+
+    // Genetic
+//    m_fitSuite->getMinimizer()->getOptions().setMaxIterations(5);
+//    m_fitSuite->getMinimizer()->getOptions().setValue("Steps",5);
+//    m_fitSuite->getMinimizer()->getOptions().setValue("PopSize",100);
+//    m_fitSuite->getMinimizer()->getOptions().setTolerance(100);
+
+    // GSLSimAn
+//    m_fitSuite->getMinimizer()->getOptions().setValue("ntries",50);
+//    m_fitSuite->getMinimizer()->getOptions().setValue("niters_fixed_t",5);
+//    m_fitSuite->getMinimizer()->getOptions().setMaxIterations(5);
+
+//    m_fitSuite->getMinimizer()->getOptions().setValue("Strategy",2);
+
+    //m_fitSuite->getMinimizer()->getOptions().print();
+
+
+    m_fitSuite->attachObserver( FitSuiteObserverFactory::createPrintObserver(100) );
+    m_fitSuite->attachObserver( FitSuiteObserverFactory::createDrawObserver() );
+
+    FitStrategyAdjustMinimizer *strategy1 = new FitStrategyAdjustMinimizer();
+    strategy1->setMinimizer(MinimizerFactory::createMinimizer("Genetic"));
+    strategy1->getMinimizer()->getOptions().setMaxIterations(5);
+    strategy1->getMinimizer()->getOptions().setValue("Steps",5);
+    m_fitSuite->addFitStrategy(strategy1);
+
+    FitStrategyAdjustMinimizer *strategy2 = new FitStrategyAdjustMinimizer();
+    strategy2->setMinimizer(MinimizerFactory::createMinimizer("Minuit2","Migrad"));
+    m_fitSuite->addFitStrategy(strategy2);
+
+    m_fitSuite->runFit();
+}
+
+
+/* ************************************************************************* */
+// initializing simulation
+/* ************************************************************************* */
+void TestFittingModule4::initializeSimulation()
+{
+    if( !mp_sample ) {
+        throw NullPointerException("TestFittingModule1::initializeSimulation() -> No sample defined");
+    }
+    delete mp_simulation;
+    mp_simulation = new Simulation(mp_options);
+    mp_simulation->setSample(*mp_sample);
+    mp_simulation->setDetectorParameters(100, 0.0*Units::degree,
+            2.0*Units::degree,100 , 0.0*Units::degree, 2.0*Units::degree);
+    mp_simulation->setBeamParameters(1.0*Units::angstrom, 0.2*Units::degree,
+            0.0*Units::degree);
+    mp_simulation->setBeamIntensity(1e10);
+}
+
+
+/* ************************************************************************* */
+// initialize sample: layer + nanoparticles, 2 parameters
+/* ************************************************************************* */
+void TestFittingModule4::initializeSample()
+{
+    delete mp_sample;
+
+    MultiLayer *p_multi_layer = new MultiLayer();
+    complex_t n_air(1.0, 0.0);
+    complex_t n_particle(1.0-6e-4, 2e-8);
+    const IMaterial *p_air_material =
+            MaterialManager::getHomogeneousMaterial("Air", n_air);
+    const IMaterial *particle_material =
+            MaterialManager::getHomogeneousMaterial("Particle", n_particle);
+
+    Layer air_layer;
+    air_layer.setMaterial(p_air_material);
+    ParticleDecoration particle_decoration( new Particle(particle_material,
+            new FormFactorCylinder(5*Units::nanometer, 5*Units::nanometer)));
+
+    air_layer.setDecoration(particle_decoration);
+
+    p_multi_layer->addLayer(air_layer);
+    mp_sample = p_multi_layer;
+
+    // defining parameters for minimization
+    if( !m_fitSuite ) {
+        throw NullPointerException("TestFittingModule::initializeSample() -> Error! No FitSuite is defined");
+    }
+
+    m_fitSuite->addFitParameter("*height", 1.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 30.) );
+    m_fitSuite->addFitParameter("*radius", 20.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 30.) );
+//    m_fitSuite->addFitParameter("*height", 6.*Units::nanometer, 0.04*Units::nanometer, AttLimits::limited(0.01, 30.) );
+//    m_fitSuite->addFitParameter("*radius", 6.*Units::nanometer, 0.06*Units::nanometer, AttLimits::limited(0.01, 30.) );
+}
+
+
+void TestFittingModule4::initializeRealData()
+{
+    if( !mp_simulation ) throw NullPointerException("TestFittingModule2::initializeRealData() -> Error! No simulation of sample defined ");
+
+    mp_simulation->runSimulation();
+    mp_simulation->normalize();
+    m_fitSuite->getFitObjects()->setSimulationNormalize(true);
+    delete mp_real_data;
+    mp_real_data = IsGISAXSTools::createNoisyData(*mp_simulation->getOutputData());
+}
+
+
+
+
diff --git a/App/src/TestFumiliLMA.cpp b/App/src/TestFumiliLMA.cpp
index fe3fc706776459db2aef10839c50515d31bdb1c4..a4d7718d166e1658fcabaca84347a2bab94351a3 100644
--- a/App/src/TestFumiliLMA.cpp
+++ b/App/src/TestFumiliLMA.cpp
@@ -90,7 +90,7 @@ void TestFumiliLMA::execute()
     //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Fumili2"); // same as ("Minuit2", "Fumili" )
     //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Fumili2" ); // same as ("Minuit2", "Migrad" ), i.e. Fumili2 is wrong key
     m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("Fumili"); //
-    //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("GSLMultiFit");
+    //m_root_minimizer = ROOT::Math::Factory::CreateMinimizer("GSLLMA");
     m_root_minimizer->SetVariable(0, "p0", 1.0, 0.01);
     m_root_minimizer->SetVariable(1, "p1", 0.0, 0.01);
     m_root_minimizer->SetVariable(2, "p2", 0.0, 0.01);
diff --git a/App/src/TestIsGISAXS13.cpp b/App/src/TestIsGISAXS13.cpp
index 28e5004c1a5bcc21a0dae5dc6cfdf8e70325f784..c2fd211e12bbf12ce9175a295950c2353078d513 100644
--- a/App/src/TestIsGISAXS13.cpp
+++ b/App/src/TestIsGISAXS13.cpp
@@ -87,7 +87,7 @@ void TestIsGISAXS13::run_isgisaxs_fit()
     // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") );
     // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") );
     // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") );
-    // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") ); // LMA
+    // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") ); // LMA
     // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") );
     // m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Scan") );
 
diff --git a/App/src/TestPerformance.cpp b/App/src/TestPerformance.cpp
index 0eb0d01339b9d19d09c2b522b805380a608971e7..bce60ffb8b1454a069fe18a4091abbc2fa482bf1 100644
--- a/App/src/TestPerformance.cpp
+++ b/App/src/TestPerformance.cpp
@@ -1,136 +1,120 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      App/src/TestPerformance.cpp
-//! @brief     Implements class TestPerformance.
-//
-//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
-//! License:   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2013
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
 #include "TestPerformance.h"
-#include "Types.h"
-#include "Units.h"
+#include "SimulationRegistry.h"
 #include "Utils.h"
-#include "Exceptions.h"
-#include "MultiLayer.h"
-#include "MaterialManager.h"
-#include "SampleFactory.h"
+#include "ProgramOptions.h"
+#include "Units.h"
 #include "SpecularMatrix.h"
-#include "SampleBuilderFactory.h"
-#include "SimulationRegistry.h"
+#include "SampleFactory.h"
+#include "SpecularMagnetic.h"
 
-#include "TSystem.h"
 #include "TDatime.h"
+#include "TSystem.h"
 #include "TBenchmark.h"
-#include <string>
-#include <iostream>
-#include <fstream>
 #include <sstream>
+#include <fstream>
 #include <iomanip>
-#include <time.h>
+#include <boost/format.hpp>
+
+
 
 TestPerformance::TestPerformance()
 {
-    // preparing performance tests to run
-    m_tests.push_back( new PerformanceTestInfo(new PerfTest_Pyramid(), 20) );
-    m_tests.push_back( new PerformanceTestInfo(new PerfTest_RotatedPyramid(), 20) );
-    m_tests.push_back( new PerformanceTestInfo(new PerfTest_MesoCrystal(), 1) );
-    m_tests.push_back( new PerformanceTestInfo(new PerfTest_SpecularMatrix(), 200000) );
-
+    m_tests.push_back(new PerformanceTest("isgisaxs02",2));
+    m_tests.push_back(new PerformanceTest("isgisaxs06a",50));
+    m_tests.push_back(new PerformanceTest("isgisaxs09b",50));
+    m_tests.push_back(new PerformanceTest("isgisaxs11",50));
+    m_tests.push_back(new PerformanceTest("isgisaxs15",20));
+    m_tests.push_back(new PerformanceTest("mesocrystal01",1));
+    m_tests.push_back(new SpecularMatrixPerformanceTest("specmatrix", 500000));
+    m_tests.push_back(new SpecularMagneticPerformanceTest("specmagnetic", 500000));
+    m_tests.push_back(new PerformanceTest("magcyl2",50));
     std::cout << "TestPerformance::TestPerformance() -> Info. Preparing to run " << m_tests.size() << " performance tests."  << std::endl;
+
 }
 
+
 TestPerformance::~TestPerformance()
 {
-    for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) {
-        delete (*it);
-    }
+    for(size_t i=0; i<m_tests.size(); ++i) delete m_tests[i];
 }
 
-//! Run performance tests.
 
-void TestPerformance::execute()
-{
-    // getting system information
-    get_sysinfo();
 
-    //clock_t clock1 = clock();
-    //clock_t gt_clock1 = clock_get_time();
 
-    // run tests
-    TBenchmark mb;
-    for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) {
-        PerformanceTestInfo *test_info = (*it);
-        std::string test_name = test_info->m_test->getName();
 
-        std::cout << "Running test: " << std::setw(20) << std::left << test_name << " ... ";
+void TestPerformance::execute()
+{
+    for(size_t i=0; i<m_tests.size(); ++i) {
+        PerformanceTest *test = m_tests[i];
+        set_sysinfo(test);
+
+        std::cout << "Running test: " << std::setw(20) << std::left << test->getName() << " ... ";
         std::cout.flush();
-        test_info->m_test->initialise(mp_options);
-        mb.Start( test_name.c_str() );
-        for(int i=0; i<test_info->m_nrepetitions; i++){
-            test_info->m_test->execute();
-        }
-        mb.Stop( test_name.c_str() );
-
-        // printing results
-        double result = mb.GetCpuTime( test_name.c_str() );
-        double fhz = double(test_info->m_nrepetitions)/result;
-        std::cout << std::setw(6) << std::left << result << " sec, "
-                  << std::setw(8) << std::left << fhz << " Hz ("
-                  << std::setw(4) << std::left << test_info->m_nrepetitions << " repetitions )"<< std::endl;
-        // saving results
-        std::ostringstream os;
-        os << std::setprecision(6)  << fhz;
-        m_performance_info[test_name] = os.str();
+        test->execute();
+        std::cout << boost::format("OK: %-6.3f (real sec), %-6.3f (cpu sec) ") % test->m_real_time % test->m_cpu_time << std::endl;
     }
 
-    write_performance();
-
-    //clock_t clock2 = clock();
+    write_results();
 }
 
-//! Append results to log file.
 
-void TestPerformance::write_performance()
-{
-    // appending performance information to the file
-//    std::string filename = Utils::FileSystem::GetHomePath() +
-//        "./dev-tools/log/perf_history.txt";
-    std::string filename = "perf_history.txt";
 
+void TestPerformance::write_results()
+{
+    std::string filename("perf_history.txt");
     std::ofstream file;
     file.open(filename.c_str(), std::ios_base::app);
     if( !file.is_open() ) {
         throw FileNotIsOpenException("TestPerformance::execute() -> Error. Can't open file '"+filename+"' for writing.");
     }
 
-    file << m_performance_info["datime"] << get_delimeter();
-    file << std::left << Utils::AdjustStringLength(m_performance_info["hostname"],10) << get_delimeter();
-    file << std::left << Utils::AdjustStringLength(m_performance_info["sysinfo"],23) << get_delimeter();
-    for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); ++it) {
-        std::string test_name = (*it)->m_test->getName();
-        file << std::left << Utils::AdjustStringLength(m_performance_info[test_name],11) << get_delimeter();
-    }
-    file<<std::endl;
+    write_header(file);
+    write_performance(file);
 
     file.close();
 
     std::cout << "TestPerformance::write_performance() -> Info. File '" << filename << "' is updated." << std::endl;
 }
 
-//! Fill system information.
 
-void TestPerformance::get_sysinfo()
+//! write header in file
+void TestPerformance::write_header(std::ofstream &file)
+{
+    file << std::endl;
+    file << boost::format("| %-19s | %-10s | %-13s | %2s | %-8s |") %  "date " % "hostname" % "sysinfo" % "tr" % "total";
+    for(size_t i=0; i<m_tests.size(); ++i) {
+        file  << boost::format(" %-12s |") %  Utils::AdjustStringLength(m_tests[i]->getName(),12);
+    }
+    file << std::endl;
+}
+
+//! write results of performance measurements
+void TestPerformance::write_performance(std::ofstream &file)
+{
+    PerformanceTest *test0 = m_tests[0];
+    file << boost::format("| %-19s | %-10s | %-13s | %-2d |") %  test0->m_datime % test0->m_hostname % test0->m_sysinfo % test0->m_nthreads;
+    double sum_real(0), sum_cpu(0);
+    for(size_t i=0; i<m_tests.size(); ++i) {
+        sum_real += m_tests[i]->m_real_time;
+        sum_cpu += m_tests[i]->m_cpu_time;
+    }
+    file  << boost::format(" %-8.3f |") %  sum_real;
+
+    for(size_t i=0; i<m_tests.size(); ++i) {
+        file  << boost::format(" %-12.3f |") %  m_tests[i]->m_real_time;
+    }
+    file << std::endl;
+}
+
+
+//! read sustem information and store it in the test
+void TestPerformance::set_sysinfo(PerformanceTest *test)
 {
+    test->initialise(mp_options);
+
     // saving date and time
     TDatime td;
-    m_performance_info["datime"] = std::string(td.AsSQLString());
+    test->m_datime = std::string(td.AsSQLString());
 
     // saving host name
     std::string hostname(gSystem->HostName());
@@ -139,95 +123,90 @@ void TestPerformance::get_sysinfo()
     if(pos != std::string::npos) {
         hostname.erase(pos,hostname.size()-pos);
     }
-    m_performance_info["hostname"] = hostname;
+    test->m_hostname = hostname;
 
     // saving hardware information
-    //std::string sysinfo;
     SysInfo_t sys_info;
     int status = gSystem->GetSysInfo(&sys_info);
     if( status == -1) {
-        std::cout << "TestPerformance::get_sysinfo() -> Warning! Can't get system info." << std::endl;
-        m_performance_info["sysinfo"] = std::string("failed");
+        test->m_sysinfo = std::string("Unknown hardware");
     }else{
         std::ostringstream os;
-        os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz";
-
+        os << std::string(gSystem->GetBuildArch());
+        //os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz";
         //os << ", " << 	sys_info.fL2Cache << " Kb";
-        m_performance_info["sysinfo"] = os.str();
+        test->m_sysinfo = os.str();
     }
-}
-
-//! Start PerfTest_SpecularMatrix.
 
-void PerfTest_SpecularMatrix::initialise(ProgramOptions *p_options)
-{
-    IApplicationTest::initialise(p_options);
-    if(m_sample) delete m_sample;
-    m_sample = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer"));
+    if (mp_options->find("threads")) {
+        test->m_nthreads = (*mp_options)["threads"].as<int>();
+    }
 }
 
-//! Run PerfTest_SpecularMatrix.
 
-void PerfTest_SpecularMatrix::execute()
-{
-    static double alpha_i = -0.3;
-    kvector_t kvec;
-    kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
-    SpecularMatrix::MultiLayerCoeff_t coeffs;
-    SpecularMatrix matrixCalculator;
-    MultiLayer *ml = dynamic_cast<MultiLayer *>(m_sample);
-    matrixCalculator.execute(*ml, kvec, coeffs);
-}
+// -----------------------------------------------------------------------------
+// General PerformanceTest
+// -----------------------------------------------------------------------------
 
-//! Start PerfTest_Pyramid.
-
-void PerfTest_Pyramid::initialise(ProgramOptions *p_options)
+//! run performance measurements
+void PerformanceTest::execute()
 {
-    IApplicationTest::initialise(p_options);
-    SimulationRegistry registry;
-    m_simulation = registry.createSimulation("isgisaxs09a");
-    m_simulation->setProgramOptions(p_options);
-}
-
-//! Run PerfTest_Pyramid.
+    TBenchmark mb;
+    mb.Start( getName().c_str() );
 
-void PerfTest_Pyramid::execute()
-{
-    m_simulation->runSimulation();
-}
+    runTests();
 
-//! Start PerfTest_RotatedPyramid
+    mb.Stop( getName().c_str() );
 
-void PerfTest_RotatedPyramid::initialise(ProgramOptions *p_options)
-{
-    IApplicationTest::initialise(p_options);
-    SimulationRegistry registry;
-    m_simulation = registry.createSimulation("isgisaxs09b");
-    m_simulation->setProgramOptions(p_options);
+    m_cpu_time = mb.GetCpuTime(getName().c_str());
+    m_real_time = mb.GetRealTime(getName().c_str());
 }
 
-//! Run PerfTest_RotatedPyramid
 
-void PerfTest_RotatedPyramid::execute()
+//! run standard simulation
+void PerformanceTest::runTests()
 {
-    m_simulation->runSimulation();
+    SimulationRegistry registry;
+    Simulation *simulation = registry.createSimulation(getName());
+    simulation->setProgramOptions(mp_options);
+    for(int i=0; i<m_nrepetitions; i++){
+        simulation->runSimulation();
+    }
+    delete simulation;
 }
 
-//! Start PerfTest_MesoCrystal.
+// -----------------------------------------------------------------------------
+// custom PerformanceTest's
+// -----------------------------------------------------------------------------
 
-void PerfTest_MesoCrystal::initialise(ProgramOptions *p_options)
+void SpecularMatrixPerformanceTest::runTests()
 {
-    IApplicationTest::initialise(p_options);
-    SimulationRegistry registry;
-    m_simulation = registry.createSimulation("mesocrystal01");
-    m_simulation->setProgramOptions(p_options);
+    MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer"));
+
+    for(int i=0; i<m_nrepetitions; i++){
+        static double alpha_i = -0.3;
+        kvector_t kvec;
+        kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
+        SpecularMatrix::MultiLayerCoeff_t coeffs;
+        SpecularMatrix matrixCalculator;
+        matrixCalculator.execute(*ml, kvec, coeffs);
+    }
+    delete ml;
 }
 
-//! Run PerfTest_MesoCrystal.
-
-void PerfTest_MesoCrystal::execute()
+void SpecularMagneticPerformanceTest::runTests()
 {
-    m_simulation->runSimulation();
+    MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("MultilayerSpecularMagneticTestCase"));
+
+    for(int i=0; i<m_nrepetitions; i++){
+        static double alpha_i = -0.3;
+        kvector_t kvec;
+        kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
+        SpecularMagnetic::MultiLayerCoeff_t coeffs;
+        SpecularMagnetic magneticCalculator;
+        magneticCalculator.execute(*ml, kvec, coeffs);
+    }
+    delete ml;
 }
 
 
diff --git a/App/src/TestPerformance2.cpp b/App/src/TestPerformance2.cpp
deleted file mode 100644
index 460c22ce2463a12e23afb0d4029539f7a980f988..0000000000000000000000000000000000000000
--- a/App/src/TestPerformance2.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-#include "TestPerformance2.h"
-#include "SimulationRegistry.h"
-#include "Utils.h"
-#include "ProgramOptions.h"
-#include "Units.h"
-#include "SpecularMatrix.h"
-#include "SampleFactory.h"
-#include "SpecularMagnetic.h"
-
-#include "TDatime.h"
-#include "TSystem.h"
-#include "TBenchmark.h"
-#include <sstream>
-#include <fstream>
-#include <iomanip>
-#include <boost/format.hpp>
-
-
-
-TestPerformance2::TestPerformance2()
-{
-    m_tests.push_back(new PerformanceTest("isgisaxs02",2));
-    m_tests.push_back(new PerformanceTest("isgisaxs06a",50));
-    m_tests.push_back(new PerformanceTest("isgisaxs09b",50));
-    m_tests.push_back(new PerformanceTest("isgisaxs11",50));
-    m_tests.push_back(new PerformanceTest("isgisaxs15",20));
-    m_tests.push_back(new PerformanceTest("mesocrystal01",1));
-    m_tests.push_back(new SpecularMatrixPerformanceTest("specmatrix", 500000));
-    m_tests.push_back(new SpecularMagneticPerformanceTest("specmagnetic", 500000));
-    m_tests.push_back(new PerformanceTest("magcyl2",50));
-    std::cout << "TestPerformance::TestPerformance() -> Info. Preparing to run " << m_tests.size() << " performance tests."  << std::endl;
-
-}
-
-
-TestPerformance2::~TestPerformance2()
-{
-    for(size_t i=0; i<m_tests.size(); ++i) delete m_tests[i];
-}
-
-
-
-
-
-void TestPerformance2::execute()
-{
-    for(size_t i=0; i<m_tests.size(); ++i) {
-        PerformanceTest *test = m_tests[i];
-        set_sysinfo(test);
-
-        std::cout << "Running test: " << std::setw(20) << std::left << test->getName() << " ... ";
-        std::cout.flush();
-        test->execute();
-        std::cout << boost::format("OK: %-6.3f (real sec), %-6.3f (cpu sec) ") % test->m_real_time % test->m_cpu_time << std::endl;
-    }
-
-    write_results();
-}
-
-
-
-void TestPerformance2::write_results()
-{
-    std::string filename("perf_history.txt");
-    std::ofstream file;
-    file.open(filename.c_str(), std::ios_base::app);
-    if( !file.is_open() ) {
-        throw FileNotIsOpenException("TestPerformance::execute() -> Error. Can't open file '"+filename+"' for writing.");
-    }
-
-    write_header(file);
-    write_performance(file);
-
-    file.close();
-
-    std::cout << "TestPerformance::write_performance() -> Info. File '" << filename << "' is updated." << std::endl;
-}
-
-
-//! write header in file
-void TestPerformance2::write_header(std::ofstream &file)
-{
-    file << std::endl;
-    file << boost::format("| %-19s | %-10s | %-13s | %2s | %-8s |") %  "date " % "hostname" % "sysinfo" % "tr" % "total";
-    for(size_t i=0; i<m_tests.size(); ++i) {
-        file  << boost::format(" %-12s |") %  Utils::AdjustStringLength(m_tests[i]->getName(),12);
-    }
-    file << std::endl;
-}
-
-//! write results of performance measurements
-void TestPerformance2::write_performance(std::ofstream &file)
-{
-    PerformanceTest *test0 = m_tests[0];
-    file << boost::format("| %-19s | %-10s | %-13s | %-2d |") %  test0->m_datime % test0->m_hostname % test0->m_sysinfo % test0->m_nthreads;
-    double sum_real(0), sum_cpu(0);
-    for(size_t i=0; i<m_tests.size(); ++i) {
-        sum_real += m_tests[i]->m_real_time;
-        sum_cpu += m_tests[i]->m_cpu_time;
-    }
-    file  << boost::format(" %-8.3f |") %  sum_real;
-
-    for(size_t i=0; i<m_tests.size(); ++i) {
-        file  << boost::format(" %-12.3f |") %  m_tests[i]->m_real_time;
-    }
-    file << std::endl;
-}
-
-
-//! read sustem information and store it in the test
-void TestPerformance2::set_sysinfo(PerformanceTest *test)
-{
-    test->initialise(mp_options);
-
-    // saving date and time
-    TDatime td;
-    test->m_datime = std::string(td.AsSQLString());
-
-    // saving host name
-    std::string hostname(gSystem->HostName());
-    // stripping host name after first '.' (somehost.jcns.frm2 -> somehost)
-    std::string::size_type pos = hostname.find_first_of('.');
-    if(pos != std::string::npos) {
-        hostname.erase(pos,hostname.size()-pos);
-    }
-    test->m_hostname = hostname;
-
-    // saving hardware information
-    SysInfo_t sys_info;
-    int status = gSystem->GetSysInfo(&sys_info);
-    if( status == -1) {
-        test->m_sysinfo = std::string("Unknown hardware");
-    }else{
-        std::ostringstream os;
-        os << std::string(gSystem->GetBuildArch());
-        //os << std::string(gSystem->GetBuildArch()) << ", "<< sys_info.fCpuSpeed << " MHz";
-        //os << ", " << 	sys_info.fL2Cache << " Kb";
-        test->m_sysinfo = os.str();
-    }
-
-    if (mp_options->find("threads")) {
-        test->m_nthreads = (*mp_options)["threads"].as<int>();
-    }
-}
-
-
-// -----------------------------------------------------------------------------
-// General PerformanceTest
-// -----------------------------------------------------------------------------
-
-//! run performance measurements
-void PerformanceTest::execute()
-{
-    TBenchmark mb;
-    mb.Start( getName().c_str() );
-
-    runTests();
-
-    mb.Stop( getName().c_str() );
-
-    m_cpu_time = mb.GetCpuTime(getName().c_str());
-    m_real_time = mb.GetRealTime(getName().c_str());
-}
-
-
-//! run standard simulation
-void PerformanceTest::runTests()
-{
-    SimulationRegistry registry;
-    Simulation *simulation = registry.createSimulation(getName());
-    simulation->setProgramOptions(mp_options);
-    for(int i=0; i<m_nrepetitions; i++){
-        simulation->runSimulation();
-    }
-    delete simulation;
-}
-
-// -----------------------------------------------------------------------------
-// custom PerformanceTest's
-// -----------------------------------------------------------------------------
-
-void SpecularMatrixPerformanceTest::runTests()
-{
-    MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("SimpleMultilayer"));
-
-    for(int i=0; i<m_nrepetitions; i++){
-        static double alpha_i = -0.3;
-        kvector_t kvec;
-        kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
-        SpecularMatrix::MultiLayerCoeff_t coeffs;
-        SpecularMatrix matrixCalculator;
-        matrixCalculator.execute(*ml, kvec, coeffs);
-    }
-    delete ml;
-}
-
-void SpecularMagneticPerformanceTest::runTests()
-{
-    MultiLayer *ml = dynamic_cast<MultiLayer *>(SampleFactory::createSample("MultilayerSpecularMagneticTestCase"));
-
-    for(int i=0; i<m_nrepetitions; i++){
-        static double alpha_i = -0.3;
-        kvector_t kvec;
-        kvec.setLambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
-        SpecularMagnetic::MultiLayerCoeff_t coeffs;
-        SpecularMagnetic magneticCalculator;
-        magneticCalculator.execute(*ml, kvec, coeffs);
-    }
-    delete ml;
-}
-
-
diff --git a/App/src/TestToySimulation.cpp b/App/src/TestToySimulation.cpp
index 19368ea3f43f4623efc896fd293d148d760dbf46..edeb6978cc8ae3e6693d55fc5e9f6f2e17a786b0 100644
--- a/App/src/TestToySimulation.cpp
+++ b/App/src/TestToySimulation.cpp
@@ -98,7 +98,7 @@ void TestToySimulation::execute()
     m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Migrad") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Minuit2", "Fumili") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Fumili") );
-    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLMultiFit") );
+    //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLLMA") );
     m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("Genetic") );
     //m_fitSuite->setMinimizer( MinimizerFactory::createMinimizer("GSLSimAn") );
     //m_fitSuite->getMinimizer()->setOptions("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1");
diff --git a/Core/Algorithms/inc/ISquaredFunction.h b/Core/Algorithms/inc/ISquaredFunction.h
index 4c205fe255e9c3164e6c98f145819bfd1d508d17..090faf2dff1b79958813edede36a75cdf2dc06de 100644
--- a/Core/Algorithms/inc/ISquaredFunction.h
+++ b/Core/Algorithms/inc/ISquaredFunction.h
@@ -51,6 +51,7 @@ private:
 //!
 //! value = (a-b)*(a-b)/norm, where
 //! norm = max(b, 1.0)
+//! a - simulated values, b - real_values
 
 class BA_CORE_API_ SquaredFunctionDefault : public ISquaredFunction
 {
@@ -76,6 +77,37 @@ public:
 };
 
 
+//! @class SquaredFunctionSimError
+//! @ingroup fitting
+//! @brief Squared difference between two values.
+//!
+//! value = (a-b)*(a-b)/norm, where
+//! norm = max(a, 1.0)
+//! a - simulated values, b - real_values
+
+class BA_CORE_API_ SquaredFunctionSimError : public ISquaredFunction
+{
+public:
+    SquaredFunctionSimError() {}
+    virtual ~SquaredFunctionSimError() {}
+    virtual SquaredFunctionSimError *clone() const { return new SquaredFunctionSimError(); }
+
+    virtual double calculateSquaredDifference(double real_value, double simulated_value) const
+    {
+        double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
+        if (diff_squared < Numeric::double_epsilon) return 0.0;
+        double normalization = calculateSquaredError(real_value, simulated_value);
+        return diff_squared/normalization;
+    }
+
+    virtual double calculateSquaredError(double real_value, double simulated_value) const
+    {
+        (void) real_value;
+        return std::max(simulated_value,1.0);
+    }
+};
+
+
 //! @class SquaredFunctionMeanSquaredError
 //! @ingroup fitting
 //! @brief Squared difference between two values normalized by mean squared error
diff --git a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py
index 7af3a83205a524493ea4168bcf6fc055cf0d1a4a..2c3c464464953723468ecf3eaf40e599091c7d7b 100644
--- a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py
+++ b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice.py
@@ -149,7 +149,7 @@ def run_fitting():
     fit_suite.addSimulationAndRealData(simulation, real_data)
     fit_suite.initPrint(10)
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2", "Fumili"))
-    #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLMultiFit"))
+    #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLLMA"))
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2","Scan"))
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLSimAn"))
 
diff --git a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py
index e3dd45fadaac2ec95b1e0b9ecfcb5480aef5807f..bbb4b98b0571cf3b88734493090a28e4fce6f88e 100644
--- a/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py
+++ b/Examples/python/fitting/ex003_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py
@@ -167,7 +167,7 @@ def run_fitting():
     fit_suite.addSimulationAndRealData(simulation, real_data)
     fit_suite.initPrint(10)
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2", "Fumili"))
-    #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLMultiFit"))
+    #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLLMA"))
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("Minuit2","Scan"))
     #fit_suite.setMinimizer( MinimizerFactory.createMinimizer("GSLSimAn"))
 
diff --git a/Fit/CMakeLists.txt b/Fit/CMakeLists.txt
index fa0e453f5636545ac21b2d37838935af25e56eed..d8fa58266a14297cd38ea7fb8e6125609dbacf6d 100644
--- a/Fit/CMakeLists.txt
+++ b/Fit/CMakeLists.txt
@@ -18,11 +18,18 @@ file(GLOB include_files
     "FitKernel/inc/*.h"
 )
 
+# genetic minimizer only available if ROOT present
+if(NOT ROOT_FOUND)
+    list(REMOVE_ITEM source_files "${CMAKE_CURRENT_SOURCE_DIR}/FitKernel/src/ROOTGeneticMinimizer.cpp")
+    list(REMOVE_ITEM include_files "${CMAKE_CURRENT_SOURCE_DIR}/FitKernel/inc/ROOTGeneticMinimizer.h")
+endif()
+
 if(BORNAGAIN_PYTHON)
     file(GLOB source_pythonapi "PythonAPI/src/*.cpp")
     list(APPEND source_files ${source_pythonapi})
     file(GLOB include_pythonapi "PythonAPI/inc/*.h")
     list(APPEND include_files ${include_pythonapi})
+
     include_directories(
         ${CMAKE_CURRENT_SOURCE_DIR}/PythonAPI/inc
     )
@@ -48,6 +55,7 @@ set(${library_name}_LIBRARY_TYPE SHARED)
 set(${library_name}_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
 set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE)
 
+
 # --- dependencies ---
 include_directories(
     ${BornAgainCore_INCLUDE_DIRS}
@@ -63,6 +71,16 @@ target_link_libraries(
     ${RootMinimizers_LIBRARY}
 )
 
+if(ROOT_FOUND)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAS_GENETIC_MINIMIZER")
+    include_directories(
+        ${ROOT_INCLUDE_DIR}
+    )
+    target_link_libraries(${library_name}
+        ${ROOT_LIBRARIES} -lGenetic -lTMVA
+    )
+endif()
+
 if(BORNAGAIN_PYTHON)
     include_directories(${PYTHON_INCLUDE_DIRS})
     target_link_libraries(${library_name} ${PYTHON_LIBRARIES})
diff --git a/Fit/Factory/inc/AttFitting.h b/Fit/Factory/inc/AttFitting.h
deleted file mode 100644
index 4d5cd34274b462a38c2780f63c10e4bcdf27bafd..0000000000000000000000000000000000000000
--- a/Fit/Factory/inc/AttFitting.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Factory/inc/AttFitting.h
-//! @brief     Defines class AttFitting.
-//!
-//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2013
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef ATTFITTING_H
-#define ATTFITTING_H
-
-#include "WinDllMacros.h"
-#include <iostream>
-#include <iomanip>
-
-//! General fitting attributes.
-
-class BA_CORE_API_ AttFitting
-{
- public:
-    AttFitting();
-    ~AttFitting(){}
-
-    double getDerivEpsilon() const { return m_deriv_epsilon; }
-    void setDerivEpsilon(double deriv_epsilon) { m_deriv_epsilon = deriv_epsilon; }
-
-    double getStepFactor() const { return m_step_factor; }
-    void setStepFactor(double step_factor) { m_step_factor = step_factor; }
-
- private:
-    double m_deriv_epsilon;  //! epsilon for derivative calculation
-    double m_step_factor; //! default relative parameter step
-};
-
-inline AttFitting::AttFitting()
-    : m_deriv_epsilon(1e-09)
-    , m_step_factor(0.01)
-{
-}
-
-#endif // ATTFITTING_H
-
-
diff --git a/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h b/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h
index aa3645f1dca5d5de4e28c0e03204fc5775bde222..d37826f191c1e1f709e1a570abc8d6e7cadd1442 100644
--- a/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h
+++ b/Fit/FitKernel/inc/FitStrategyAdjustMinimizer.h
@@ -17,6 +17,7 @@
 #define FITSTRATEGYADJUSTMINIMIZER_H
 
 #include "IFitStrategy.h"
+#include "IMinimizer.h"
 
 //! @class FitStrategyAdjustMinimizer
 //! @ingroup fitting
@@ -25,6 +26,18 @@
 class BA_CORE_API_ FitStrategyAdjustMinimizer : public IFitStrategy
 {
 public:
+    FitStrategyAdjustMinimizer() : IFitStrategy("FitStrategyAdjustMinimizer"), m_minimizer(0) {}
+    virtual ~FitStrategyAdjustMinimizer(){ delete m_minimizer; }
+
+    virtual FitStrategyAdjustMinimizer *clone() const;
+
+    IMinimizer *getMinimizer() { return m_minimizer; }
+    void setMinimizer(IMinimizer *minimizer) { m_minimizer = minimizer; }
+
+    virtual void execute();
+
+private:
+    IMinimizer *m_minimizer;
 };
 
 #endif // FITSTRATEGYADJUSTMINIMIZER_H
diff --git a/Fit/FitKernel/inc/FitSuite.h b/Fit/FitKernel/inc/FitSuite.h
index 72ebf07fd3e259f62c247ba83b8d58aa8dff493a..ad779b20610988834ada06d48f843decd043ef50 100644
--- a/Fit/FitKernel/inc/FitSuite.h
+++ b/Fit/FitKernel/inc/FitSuite.h
@@ -86,7 +86,7 @@ class BA_CORE_API_ FitSuite : public IObservable
     size_t getNCalls() const;
 
     //! Returns the number of current strategy
-    size_t getNStrategy() const { return m_fit_strategies.getNStrategy(); }
+    size_t getNStrategy() const { return m_fit_strategies.getCurrentStrategyIndex(); }
 
     //! Prints results of the screen
     void printResults() const;
diff --git a/Fit/FitKernel/inc/FitSuitePrintObserver.h b/Fit/FitKernel/inc/FitSuitePrintObserver.h
index 6c3bf85b88440eb6a9b95859749ddf87147e1917..10ffae838440d75e44d0264f14b3a8eeb597a7e3 100644
--- a/Fit/FitKernel/inc/FitSuitePrintObserver.h
+++ b/Fit/FitKernel/inc/FitSuitePrintObserver.h
@@ -18,7 +18,7 @@
 
 #include "IObserver.h"
 #include <boost/date_time/posix_time/posix_time.hpp>
-
+class FitSuite;
 
 //! @class FitSuitePrintObserver
 //! @ingroup fitting_internal
@@ -33,9 +33,15 @@ public:
     void update(IObservable *subject);
 
 private:
+    bool skipIteration();
+    void checkStrategy();
+
+    FitSuite *m_fitSuite;
     int m_print_every_nth;
+    int m_previous_strategy_index;
     boost::posix_time::ptime m_start_time;
     boost::posix_time::ptime m_last_call_time;
+    bool m_strategy_is_changed;
 };
 
 #endif // FITSUITEPRINTOBSERVER_H
diff --git a/Fit/FitKernel/inc/FitSuiteStrategies.h b/Fit/FitKernel/inc/FitSuiteStrategies.h
index 01b713289432597ba9caf98869846b21afe24bfa..fc21d3a16adb668aded7a05846ce12ee2d0eee1e 100644
--- a/Fit/FitKernel/inc/FitSuiteStrategies.h
+++ b/Fit/FitKernel/inc/FitSuiteStrategies.h
@@ -40,16 +40,19 @@ class BA_CORE_API_  FitSuiteStrategies
 
     void minimize();
 
-    size_t getNStrategy() const { return m_current_strategy_index; }
+    size_t getCurrentStrategyIndex() const { return m_current_strategy_index; }
+    std::string getCurrentStrategyName() const { return m_current_strategy_name; }
 
     iterator begin() { return m_strategies.begin(); }
     iterator end() { return m_strategies.end(); }
+    size_t size() const { return m_strategies.size(); }
 
     void clear();
  private:
     strategies_t m_strategies;
     FitSuite *m_fit_suite;
     size_t m_current_strategy_index;
+    std::string m_current_strategy_name;
 };
 
 #endif // FITSUITESTRATEGIES_H
diff --git a/Fit/FitKernel/inc/IMinimizer.h b/Fit/FitKernel/inc/IMinimizer.h
index 1bc99eadf36ff4cac189a526bfceacdf07b8c8fb..36c7f3e58de110347ef1dbaa37c493e0d3bd4bda 100644
--- a/Fit/FitKernel/inc/IMinimizer.h
+++ b/Fit/FitKernel/inc/IMinimizer.h
@@ -82,18 +82,27 @@ class BA_CORE_API_ IMinimizer
     //! Prints fit results
     virtual void printResults() const;
 
-
     //! Returns number of calls of minimized function
     virtual size_t getNCalls() const;
 
     //! return minimizer options
-    virtual MinimizerOptions getOptions() const;
+    virtual MinimizerOptions &getOptions();
+    virtual const MinimizerOptions &getOptions() const;
 
     //! set minimizer options
     virtual void setOptions(const MinimizerOptions &options);
 
     //! set minimizer option string
-    virtual void setOptions(const std::string& options);
+    virtual void setOptionString(const std::string& options);
+
+    //! Checks if type of algorithm is Levenberg-Marquardt or similar
+    virtual bool isGradientBasedAgorithm();
+
+    //! return name of the minimizer
+    virtual std::string getMinimizerName() const;
+
+    //! return name of the minimization algorithm
+    virtual std::string getAlgorithmName() const;
 
 };
 
@@ -162,7 +171,13 @@ inline size_t IMinimizer::getNCalls() const
     throw NotImplementedException("IMinimizer::getNCalls() -> Not implemented.");
 }
 
-inline MinimizerOptions IMinimizer::getOptions() const
+inline MinimizerOptions &IMinimizer::getOptions()
+{
+    throw NotImplementedException("IMinimizer::getOptions() -> Not implemented.");
+}
+
+
+inline const MinimizerOptions &IMinimizer::getOptions() const
 {
     throw NotImplementedException("IMinimizer::getOptions() -> Not implemented.");
 }
@@ -172,11 +187,28 @@ inline void IMinimizer::setOptions(const MinimizerOptions &/*options*/)
     throw NotImplementedException("IMinimizer::setOptions() -> Not implemented.");
 }
 
-inline void IMinimizer::setOptions(const std::string &/*options*/)
+inline void IMinimizer::setOptionString(const std::string &/*options*/)
 {
-    throw NotImplementedException("IMinimizer::setOptions() -> Not implemented.");
+    throw NotImplementedException("IMinimizer::setOptionString() -> Not implemented.");
 }
 
+inline bool IMinimizer::isGradientBasedAgorithm()
+{
+    throw NotImplementedException("IMinimizer::isGradientBasedAlgorithm() -> Not implemented.");
+}
+
+inline std::string IMinimizer::getMinimizerName() const
+{
+    throw NotImplementedException("IMinimizer::getMinimizerName() -> Not implemented.");
+}
+
+inline std::string IMinimizer::getAlgorithmName() const
+{
+    throw NotImplementedException("IMinimizer::getAlgorithmName() -> Not implemented.");
+}
+
+
+
 #endif // IMINIMIZER_H
 
 
diff --git a/Fit/FitKernel/inc/MinimizerFactory.h b/Fit/FitKernel/inc/MinimizerFactory.h
index 6687534775afc36720493e0b36314897f99646b7..675d57b3d8e8413555852553c5d8414cb52d3414 100644
--- a/Fit/FitKernel/inc/MinimizerFactory.h
+++ b/Fit/FitKernel/inc/MinimizerFactory.h
@@ -32,6 +32,9 @@ class BA_CORE_API_ MinimizerFactory
     static IMinimizer *createMinimizer(const std::string& minimizer, const std::string& algorithm = std::string(), const std::string& options=std::string() );
     static void printCatalogue();
 
+    //! Create minimizer using existing one. Only minimizer type and minimizer settings are propagated.
+    static IMinimizer *createMinimizer(const IMinimizer *minimizer);
+
  private:
 
     //! @class map of minimizer names holding list of defined algorithms for every minimizer
diff --git a/Fit/FitKernel/inc/MinimizerOptions.h b/Fit/FitKernel/inc/MinimizerOptions.h
index 55a9e1e7029ef1e9af84c4377e1e4450f61705c3..92876f335ea92f391115812b41aee73586efeb2e 100644
--- a/Fit/FitKernel/inc/MinimizerOptions.h
+++ b/Fit/FitKernel/inc/MinimizerOptions.h
@@ -16,17 +16,23 @@
 #ifndef MINIMIZEROPTIONS_H
 #define MINIMIZEROPTIONS_H
 #include "WinDllMacros.h"
-
+#include "Exceptions.h"
+#include <string>
+#include <map>
+#include <iostream>
+#include <iomanip>
 
 //! @class MinimizerOptions
 //! @ingroup fitting
 //! @brief The %MinimizerOptions class contains options for minimization algorithms
+//!
+//! It allows to set values only if they have been already registered.
 
 class BA_CORE_API_ MinimizerOptions
 {
 public:
     MinimizerOptions();
-    virtual ~MinimizerOptions(){}
+    ~MinimizerOptions(){}
 
     //! return minimizer tolerance
     double getTolerance() const { return m_tolerance; }
@@ -48,7 +54,79 @@ public:
     //! set maximum number of allowed function calls
     void setMaxFunctionCalls(int max_function_calls) { m_max_function_calls = max_function_calls; }
 
+    //! return internal print level of the minimizer
+    int getPrintLevel() const { return m_print_level; }
+    //! set internal print level of the minimizer
+    void setPrintLevel(int print_level){ m_print_level = print_level; }
+
+    //! set option value
+
+    void setValue(const std::string &name, double val) { setExistingValue(name, m_RealOpts, val); }
+    void setValue(const std::string &name, int val) { setExistingValue(name, m_IntOpts, val);}
+    void setValue(const std::string &name, const std::string &val) { setExistingValue(name, m_NamOpts, val);}
+
+    void getValue(const std::string &name, int &val) { val = getIntValue(name); }
+    void getValue(const std::string &name, double &val) { val = getRealValue(name); }
+    void getValue(const std::string &name, std::string &val) { val = getNamedValue(name); }
+
+    void addValue(const std::string &name, double val) { addNewValue(name, m_RealOpts, val); }
+    void addValue(const std::string &name, int val) { addNewValue(name, m_IntOpts, val);}
+    void addValue(const std::string &name, const std::string &val) { addNewValue(name, m_NamOpts, val);}
+
+    int getIntValue(const std::string &name) { return getValue(name, m_IntOpts); }
+    double getRealValue(const std::string &name) { return getValue(name, m_RealOpts); }
+    std::string getNamedValue(const std::string &name) { return getValue(name, m_NamOpts); }
+
+    void print() const {
+        print_common(std::cout);
+        if(m_IntOpts.size() || m_RealOpts.size() || m_NamOpts.size())
+            std::cout << std::setw(24) << std::left << "Extra options " << " : " << std::endl;
+        print_extra(m_IntOpts, std::cout);
+        print_extra(m_RealOpts, std::cout);
+        print_extra(m_NamOpts, std::cout);
+    }
+
 private:
+    template<class M>
+    static void setExistingValue(const std::string &name, M & opts, const typename M::mapped_type & value) {
+       typename M::iterator pos;
+       pos = opts.find(name);
+       if (pos != opts.end()) {
+           pos->second = value;
+       } else {
+           throw LogicErrorException("MinimizerOptions::setValue() -> Error! Not existing name '"+name+"'");
+       }
+    }
+
+    template<class M>
+    static void addNewValue(const std::string &name, M & opts, const typename M::mapped_type & value) {
+       typename M::iterator pos;
+       pos = opts.find(name);
+       if (pos != opts.end()) {
+           throw LogicErrorException("MinimizerOptions::addValue() -> Error! Already existing name '"+name+"'");
+       } else {
+           opts.insert(typename M::value_type(name, value) );
+       }
+    }
+
+    template<class M>
+    static const typename M::mapped_type getValue(const std::string &  name, const M & opts) {
+       typename M::const_iterator pos;
+       pos = opts.find(name);
+       if (pos == opts.end()) {
+           throw LogicErrorException("MinimizerOptions::getValue() -> Error! Not existing name '"+name+"'");
+       }
+       return  (*pos).second;
+    }
+
+    template<class M>
+    static void print_extra( const M & opts, std::ostream & os) {
+       for (typename M::const_iterator pos = opts.begin(); pos != opts.end(); ++pos)
+          os << std::setw(24) << pos->first << " : " << std::setw(15) << pos->second << std::endl;
+    }
+
+    void print_common(std::ostream & os) const;
+
     double m_tolerance; //!< Tolerance on the function value at the minimum.
     //!< the default tolerance value is 0.01 and the minimization will stop
     //!< when the estimated vertical distance to the minimum (EDM) is less
@@ -65,6 +143,11 @@ private:
 
     int m_max_function_calls; //!< Max number of function calls.
 
+    int m_print_level; //!< internal print level of the minimizer, 0- silent
+
+    std::map<std::string, double> m_RealOpts; //!< additional map of the real options
+    std::map<std::string, int> m_IntOpts; //!< map of the integer options
+    std::map<std::string, std::string> m_NamOpts; //!< map of the named options
 };
 
 
diff --git a/Fit/FitKernel/inc/ROOTGSLNLSMinimizer.h b/Fit/FitKernel/inc/PatchedGSLNLSMinimizer.h
similarity index 100%
rename from Fit/FitKernel/inc/ROOTGSLNLSMinimizer.h
rename to Fit/FitKernel/inc/PatchedGSLNLSMinimizer.h
diff --git a/Fit/FitKernel/inc/ROOTGSLSimAnMinimizer.h b/Fit/FitKernel/inc/PatchedGSLSimAnMinimizer.h
similarity index 100%
rename from Fit/FitKernel/inc/ROOTGSLSimAnMinimizer.h
rename to Fit/FitKernel/inc/PatchedGSLSimAnMinimizer.h
diff --git a/Fit/FitKernel/inc/ROOTGeneticMinimizer.h b/Fit/FitKernel/inc/ROOTGeneticMinimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..4709dbabfd2a72c0c591ed9f19e1fff068938c90
--- /dev/null
+++ b/Fit/FitKernel/inc/ROOTGeneticMinimizer.h
@@ -0,0 +1,43 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/inc/ROOTGeneticMinimizer.h
+//! @brief     Defines class ROOTGeneticMinimizer.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef ROOTGENETICMINIMIZER_H
+#define ROOTGENETICMINIMIZER_H
+
+#include "ROOTMinimizer.h"
+#include "Math/GeneticMinimizer.h"
+
+//! @class ROOTGeneticMinimizer
+//! @ingroup fitting_internal
+//! @brief Wrapper for ROOT Genetic minimizer
+
+class ROOTGeneticMinimizer : public ROOTMinimizer
+{
+public:
+    ROOTGeneticMinimizer(const std::string& minimizer_name, const std::string& algo_type);
+    virtual ~ROOTGeneticMinimizer(){}
+
+    virtual void setParameter(size_t index, const FitParameter *par);
+
+protected:
+   virtual void propagateOptions();
+
+   ROOT::Math::GeneticMinimizer *m_genetic_minimizer;
+
+};
+
+#endif // ROOTGENETICMINIMIZER_H
+
+
diff --git a/Fit/FitKernel/inc/ROOTLMAMinimizer.h b/Fit/FitKernel/inc/ROOTLMAMinimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..325cd801334a9da79fbebbf16a2366b9578de809
--- /dev/null
+++ b/Fit/FitKernel/inc/ROOTLMAMinimizer.h
@@ -0,0 +1,44 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/inc/ROOTLMAMinimizer.h
+//! @brief     Defines class ROOTLMAMinimizer.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef ROOTMULTIFITMINIMIZER_H
+#define ROOTMULTIFITMINIMIZER_H
+
+#include "ROOTMinimizer.h"
+#include "PatchedGSLNLSMinimizer.h"
+
+//! @class ROOTLMAMinimizer
+//! @ingroup fitting_internal
+//! @brief Wrapper for Levenberg Marquard GSL minimizer
+
+class ROOTLMAMinimizer : public ROOTMinimizer
+{
+public:
+    ROOTLMAMinimizer(const std::string& minimizer_name, const std::string& algo_type);
+    virtual ~ROOTLMAMinimizer(){}
+
+    virtual bool isGradientBasedAgorithm() { return true; }
+
+protected:
+   virtual void propagateOptions();
+
+   ROOT::Patch::GSLNLSMinimizer *m_lma_minimizer;
+
+};
+
+#endif // ROOTMULTIFITMINIMIZER_H
+
+
+
diff --git a/Fit/FitKernel/inc/ROOTMinimizer.h b/Fit/FitKernel/inc/ROOTMinimizer.h
index 104c092ca4db06dde2f6a6d7fdbabf94f0bebd2a..d5430bc42463dcc570e3db75445c1e47b99c91ee 100644
--- a/Fit/FitKernel/inc/ROOTMinimizer.h
+++ b/Fit/FitKernel/inc/ROOTMinimizer.h
@@ -23,7 +23,6 @@
 #include "FitSuiteParameters.h"
 #include <string>
 #include "Math/Minimizer.h"
-#include "Math/Factory.h"
 #include "Math/Functor.h"
 
 
@@ -66,21 +65,28 @@ class BA_CORE_API_ ROOTMinimizer : public IMinimizer
     virtual size_t getNCalls() const;
 
     //! return minimizer options
-    virtual MinimizerOptions getOptions() const;
+    virtual MinimizerOptions &getOptions() { return m_options; }
+    virtual const MinimizerOptions &getOptions() const { return m_options; }
 
     //! set minimizer options
     virtual void setOptions(const MinimizerOptions &options);
 
-    //! set minimizer option string
-    virtual void setOptions(const std::string& options);
-
     //! Returns created minimizer
     ROOT::Math::Minimizer *getROOTMinimizer() { return m_root_minimizer; }
+    const ROOT::Math::Minimizer *getROOTMinimizer() const { return m_root_minimizer; }
 
     //! Checks if type of algorithm is Levenberg-Marquardt or similar
-    bool isGradientBasedAgorithm();    
+    virtual bool isGradientBasedAgorithm() { return false;}
+
+    //! return name of the minimizer
+    virtual std::string getMinimizerName() const { return m_minimizer_name; }
+
+    //! return name of the minimization algorithm
+    virtual std::string getAlgorithmName() const { return m_algo_type; }
+
+ protected:
+    virtual void propagateOptions();
 
- private:
     ROOTMinimizer(const ROOTMinimizer& );
     ROOTMinimizer& operator=(const ROOTMinimizer& );
 
@@ -91,6 +97,7 @@ class BA_CORE_API_ ROOTMinimizer : public IMinimizer
     ROOT::Math::Minimizer *m_root_minimizer;
     ROOTMinimizerChiSquaredFunction *m_chi2_func;
     ROOTMinimizerGradientFunction *m_gradient_func;
+    MinimizerOptions m_options;
 };
 
 #endif // ROOTMINIMIZER_H
diff --git a/Fit/FitKernel/inc/ROOTMinimizerHelper.h b/Fit/FitKernel/inc/ROOTMinimizerHelper.h
index a771efd6bee8dc8807fbbdbd0c06538dd864b87b..4da05c324b33b47e6a8b65f13528a068f6a3187b 100644
--- a/Fit/FitKernel/inc/ROOTMinimizerHelper.h
+++ b/Fit/FitKernel/inc/ROOTMinimizerHelper.h
@@ -17,8 +17,7 @@
 #define ROOTMINIMIZERHELPER_H
 
 #include "ROOTMinimizer.h"
-#include "ROOTGSLSimAnMinimizer.h"
-
+#include "PatchedGSLSimAnMinimizer.h"
 
 
 //! @class ROOTMinimizerHelper
@@ -37,9 +36,7 @@ class BA_CORE_API_ ROOTMinimizerHelper
             const std::string& options);
 
     //! Prints results of minimization
-    static void printResults(ROOT::Math::Minimizer *minimizer,
-            const std::string& minimizer_name, const std::string& algo_type);
-
+    static void printResults(const ROOTMinimizer *minimizer);
 
  private:
     //! process single command
@@ -55,13 +52,13 @@ class BA_CORE_API_ ROOTMinimizerHelper
             const std::string& command);
 
     //! Prints minimizer options
-    static void printOptions(ROOT::Math::Minimizer *minimizer);
+    static void printOptions(const ROOT::Math::Minimizer *minimizer);
 
     //! Prints minimizer status
-    static void printStatus(ROOT::Math::Minimizer *minimizer);
+    static void printStatus(const ROOT::Math::Minimizer *minimizer);
 
     //! Prints variables
-    static void printVariables(ROOT::Math::Minimizer *minimizer);
+    static void printVariables(const ROOT::Math::Minimizer *minimizer);
 
 };
 
diff --git a/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h b/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e56199935a3abc7917bc9c5fef6ae5a1f6a9a14
--- /dev/null
+++ b/Fit/FitKernel/inc/ROOTMinuit2Minimizer.h
@@ -0,0 +1,42 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/inc/ROOTMinuitMinimizer.h
+//! @brief     Defines class ROOTMinuitMinimizer.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef ROOTMINUIT2MINIMIZER_H
+#define ROOTMINUIT2MINIMIZER_H
+
+#include "ROOTMinimizer.h"
+#include "Minuit2/Minuit2Minimizer.h"
+
+//! @class ROOTMinuit2Minimizer
+//! @ingroup fitting_internal
+//! @brief Wrapper for ROOT Minuit2 minimizer
+
+class ROOTMinuit2Minimizer : public ROOTMinimizer
+{
+public:
+    ROOTMinuit2Minimizer(const std::string& minimizer_name, const std::string& algo_type);
+    virtual ~ROOTMinuit2Minimizer(){}
+
+    virtual bool isGradientBasedAgorithm();
+
+protected:
+   virtual void propagateOptions();
+
+   ROOT::Minuit2::Minuit2Minimizer *m_minuit2_minimizer;
+
+};
+
+
+#endif
diff --git a/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h b/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ee4ce26c9aa910a19bed2eb27394071e7840c41
--- /dev/null
+++ b/Fit/FitKernel/inc/ROOTMultiMinMinimizer.h
@@ -0,0 +1,40 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/inc/ROOTMultiMinMinimizer.h
+//! @brief     Defines class ROOTMultiMinMinimizer.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef ROOTMULTIMINMINIMIZER_H
+#define ROOTMULTIMINMINIMIZER_H
+
+#include "ROOTMinimizer.h"
+#include "Math/GSLMinimizer.h"
+
+//! @class ROOTMultiMinMinimizer
+//! @ingroup fitting_internal
+//! @brief Wrapper for GSL gradiend descent minimizer family
+
+class ROOTMultiMinMinimizer : public ROOTMinimizer
+{
+public:
+    ROOTMultiMinMinimizer(const std::string& minimizer_name, const std::string& algo_type);
+    virtual ~ROOTMultiMinMinimizer(){}
+
+protected:
+   virtual void propagateOptions();
+
+   ROOT::Math::GSLMinimizer *m_gsl_minimizer;
+
+};
+
+
+#endif // ROOTMULTIMINMINIMIZER_H
diff --git a/Fit/FitKernel/inc/ROOTSimAnMinimizer.h b/Fit/FitKernel/inc/ROOTSimAnMinimizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..803419b71ea80ba78f4a78652e8d02fc8e75f003
--- /dev/null
+++ b/Fit/FitKernel/inc/ROOTSimAnMinimizer.h
@@ -0,0 +1,40 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/inc/ROOTSimAnMinimizer.h
+//! @brief     Defines class ROOTSimAnMinimizer.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef ROOTSIMANMINIMIZER_H
+#define ROOTSIMANMINIMIZER_H
+
+#include "ROOTMinimizer.h"
+#include "PatchedGSLSimAnMinimizer.h"
+
+
+//! @class ROOTSimAnMinimizer
+//! @ingroup fitting_internal
+//! @brief Wrapper for ROOT GSL simmulated annealing minimizer
+
+class ROOTSimAnMinimizer : public ROOTMinimizer
+{
+public:
+    ROOTSimAnMinimizer(const std::string& minimizer_name, const std::string& algo_type);
+    virtual ~ROOTSimAnMinimizer(){}
+
+protected:
+   virtual void propagateOptions();
+
+   ROOT::Patch::GSLSimAnMinimizer *m_siman_minimizer;
+};
+
+
+#endif // ROOTSIMANMINIMIZER_H
diff --git a/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp b/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp
index 6ceafc542c4a6423f226ece7023e3dd1bb43826b..146900147275852c5c6f11cbacba2f2ff11cbb7c 100644
--- a/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp
+++ b/Fit/FitKernel/src/FitStrategyAdjustMinimizer.cpp
@@ -1,2 +1,24 @@
 #include "FitStrategyAdjustMinimizer.h"
 #include "FitSuite.h"
+#include "MinimizerFactory.h"
+
+
+// It's not real clone
+FitStrategyAdjustMinimizer *FitStrategyAdjustMinimizer::clone() const
+{
+    FitStrategyAdjustMinimizer *result = new FitStrategyAdjustMinimizer();
+    result->setMinimizer( MinimizerFactory::createMinimizer(m_minimizer));
+    return result;
+}
+
+
+void FitStrategyAdjustMinimizer::execute()
+{
+
+    m_fit_suite->setMinimizer( MinimizerFactory::createMinimizer(m_minimizer) );
+
+    m_fit_suite->minimize();
+
+    //m_fit_suite->printResults();
+
+}
diff --git a/Fit/FitKernel/src/FitSuitePrintObserver.cpp b/Fit/FitKernel/src/FitSuitePrintObserver.cpp
index b6c64fc36023d1c96521adb840dbfe3a8e6ac397..4461e5c708d106db565a7f26493e3a38eaa6ea4b 100644
--- a/Fit/FitKernel/src/FitSuitePrintObserver.cpp
+++ b/Fit/FitKernel/src/FitSuitePrintObserver.cpp
@@ -18,45 +18,84 @@
 
 
 FitSuitePrintObserver::FitSuitePrintObserver(int print_every_nth)
-    : m_print_every_nth(print_every_nth)
+    : m_fitSuite(0)
+    , m_print_every_nth(print_every_nth)
+    , m_previous_strategy_index(-1)
     , m_start_time()
     , m_last_call_time()
+    , m_strategy_is_changed(false)
 {
 	m_last_call_time = boost::posix_time::second_clock::local_time();
 }
 
 void FitSuitePrintObserver::update(IObservable *subject)
 {
-    FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject);
-    if( !fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't access FitSuite");
+    m_fitSuite = dynamic_cast<FitSuite *>(subject);
+    if( !m_fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't access FitSuite");
 
-    if(fitSuite->getNCalls() == 0 ) m_start_time = boost::posix_time::second_clock::local_time();
+    if(skipIteration()) return;
 
-    if( (fitSuite->getNCalls() % m_print_every_nth != 0)
-            && fitSuite->getNCalls()!=0
-            && !fitSuite->isLastIteration()
-            ) return; // print first iteration, every n'th and last iteration
+    if(m_fitSuite->getFitStrategies()->size() && m_strategy_is_changed) {
+        std::cout << "-------------------------------------------------------------------------------" << std::endl;
+        std::cout << "CurrentStrategyName: '"<< m_fitSuite->getFitStrategies()->getCurrentStrategyName() << "'" << std::endl;
+        std::cout << "-------------------------------------------------------------------------------" << std::endl;
+    }
 
-        std::cout << "FitSuitePrintObserver::update() -> Info."
-                  << " NCall:" << fitSuite->getNCalls()
-                  << " NStrategy:" << fitSuite->getNStrategy()
-                  << " Chi2:" << std::scientific << std::setprecision(8)
-                  << fitSuite->getFitObjects()->getChiSquaredValue() << std::endl;
+    std::cout << "FitSuitePrintObserver::update() -> Info."
+              << " NCall:" << m_fitSuite->getNCalls()
+              << " NStrategy:" << m_fitSuite->getNStrategy()
+              << " Chi2:" << std::scientific << std::setprecision(8)
+              << m_fitSuite->getFitObjects()->getChiSquaredValue() << std::endl;
 
-        boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - m_last_call_time;
-        std::cout << "Wall time since last call:"
-                  << std::fixed << std::setprecision(2) 
+    boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - m_last_call_time;
+    std::cout << "Wall time since last call:"
+              << std::fixed << std::setprecision(2)
+              << diff.total_milliseconds()/1000. << " sec." <<std::endl;
+    m_last_call_time = boost::posix_time::microsec_clock::local_time();
+
+    m_fitSuite->getFitParameters()->printParameters();
+
+    if(m_fitSuite->isLastIteration()) {
+        std::cout << "This was the last iteration." << std::endl;
+        m_fitSuite->printResults();
+        diff = boost::posix_time::second_clock::local_time() - m_start_time;
+        std::cout << "Total time spend: "
+                  << std::fixed << std::setprecision(2)
                   << diff.total_milliseconds()/1000. << " sec." <<std::endl;
-        m_last_call_time = boost::posix_time::microsec_clock::local_time();
-
-        fitSuite->getFitParameters()->printParameters();
-
-        if(fitSuite->isLastIteration()) {
-            std::cout << "This was the last iteration." << std::endl;
-            fitSuite->printResults();
-            diff = boost::posix_time::second_clock::local_time() - m_start_time;
-            std::cout << "Total time spend: "
-                      << std::fixed << std::setprecision(2)
-                      << diff.total_milliseconds()/1000. << " sec." <<std::endl;
-        }
+    }
 }
+
+
+// return false if given iteration is
+//   * the first iteration
+//   * the last iteration
+//   * n-th iteration
+//   * strategy changed
+bool FitSuitePrintObserver::skipIteration()
+{
+    if(m_fitSuite->getNCalls() == 0 ) {
+        m_start_time = boost::posix_time::second_clock::local_time();
+        m_last_call_time = boost::posix_time::second_clock::local_time();
+    }
+
+    checkStrategy();
+
+    if( m_fitSuite->getNCalls() == 0 ) return false;  // first iteration
+    if( m_fitSuite->isLastIteration() ) return false; // last iteration
+    if( m_fitSuite->getNCalls() % m_print_every_nth == 0 ) return false; // every n'th iteration
+    if(m_strategy_is_changed) return false; // strategy is changed
+
+    return true;
+}
+
+
+void FitSuitePrintObserver::checkStrategy()
+{
+    m_strategy_is_changed = false;
+    if(m_previous_strategy_index != (int)m_fitSuite->getNStrategy()) {
+        m_previous_strategy_index = m_fitSuite->getNStrategy();
+        m_strategy_is_changed = true;
+    }
+}
+
+
diff --git a/Fit/FitKernel/src/FitSuiteStrategies.cpp b/Fit/FitKernel/src/FitSuiteStrategies.cpp
index 69a39c7de9c7181af84387191c622ec0c240f53a..14d88aad5bf15df455cd2b4e4b45663f236f2e13 100644
--- a/Fit/FitKernel/src/FitSuiteStrategies.cpp
+++ b/Fit/FitKernel/src/FitSuiteStrategies.cpp
@@ -47,10 +47,12 @@ void FitSuiteStrategies::minimize()
          m_fit_suite->minimize();
     } else {
         for(strategies_t::iterator it=m_strategies.begin(); it!=m_strategies.end(); ++it) {
-            msglog(MSG::INFO) << "FitSuiteStrategies::minimize() -> Running strategy #" << m_current_strategy_index << " '" << (*it)->getName() << "'";
+            //msglog(MSG::INFO) << "FitSuiteStrategies::minimize() -> Running strategy #" << m_current_strategy_index << " '" << (*it)->getName() << "'";
+            m_current_strategy_name = (*it)->getName();
             (*it)->execute();
             ++m_current_strategy_index;
         }
+        --m_current_strategy_index;
     }
 }
 
diff --git a/Fit/FitKernel/src/MinimizerFactory.cpp b/Fit/FitKernel/src/MinimizerFactory.cpp
index f641af36c96596e9d4831371af2c60af7ddd19ef..576c004b160365c26f333a02dbf4610924ac72fd 100644
--- a/Fit/FitKernel/src/MinimizerFactory.cpp
+++ b/Fit/FitKernel/src/MinimizerFactory.cpp
@@ -14,11 +14,15 @@
 // ************************************************************************** //
 
 #include "MinimizerFactory.h"
-#include "ROOTGSLNLSMinimizer.h"
-#include "ROOTGSLSimAnMinimizer.h"
 #include "MinimizerTest.h"
 #include "MinimizerScan.h"
-#include "ROOTMinimizer.h"
+#include "ROOTMinuit2Minimizer.h"
+#include "ROOTMultiMinMinimizer.h"
+#include "ROOTSimAnMinimizer.h"
+#include "ROOTLMAMinimizer.h"
+#ifdef HAS_GENETIC_MINIMIZER
+#include "ROOTGeneticMinimizer.h"
+#endif
 #include <boost/assign/list_of.hpp>
 #include <iomanip>
 
@@ -29,20 +33,18 @@ MinimizerFactory::Catalogue MinimizerFactory::m_catalogue =
 // for every minimizer
 MinimizerFactory::Catalogue::Catalogue()
 {
-    // TODO FIXME As soon as we got rid from ROOT in our dependencies, we've
-    // lost Genetic minimizer and it is not easy to get it back
-
     // our minimizers
     //m_data["Test"]        = boost::assign::list_of("");
     //m_data["Scan"]        = boost::assign::list_of("");
     // ROOT minimizers
     //m_data["Minuit"]      = boost::assign::list_of("Migrad")("Simplex")("Combined")("Scan");
     m_data["Minuit2"]     = boost::assign::list_of("Migrad")("Simplex")("Combined")("Scan")("Fumili");
-    //m_data["Fumili"]      = boost::assign::list_of("");
     m_data["GSLMultiMin"] = boost::assign::list_of("ConjugateFR")("ConjugatePR")("BFGS")("BFGS2")("SteepestDescent");
-    m_data["GSLMultiFit"] = boost::assign::list_of("");
+    m_data["GSLLMA"] = boost::assign::list_of("");
     m_data["GSLSimAn"]    = boost::assign::list_of("");
-    //m_data["Genetic"]     = boost::assign::list_of(""); // available only with ROOT libraries
+#ifdef HAS_GENETIC_MINIMIZER
+    m_data["Genetic"]     = boost::assign::list_of(""); // available only with ROOT libraries
+#endif
 }
 
 
@@ -80,7 +82,8 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons
 {
     if( !m_catalogue.isValid(minimizer, algorithm) ) {
         std::ostringstream ostr;
-        ostr << "MinimizerFactory::MinimizerFactory() -> Error! Wrong minimizer name. Possible names are:" << std::endl;
+        ostr << "MinimizerFactory::MinimizerFactory() -> Error! Wrong minimizer name '" << minimizer << "' or algorithm '" << algorithm << "'" << std::endl;
+        ostr << "Possible names are:" << std::endl;
         ostr << m_catalogue;
         throw LogicErrorException(ostr.str());
     }
@@ -88,14 +91,36 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons
     IMinimizer *result(0);
     if( minimizer == "Test" ) {
         result = new MinimizerTest();
+
     } else if( minimizer == "Scan" ) {
         result = new MinimizerScan();
-    } else {
-        result = new ROOTMinimizer(minimizer, algorithm);
+
+    } else if( minimizer == "Minuit2" ) {
+        result = new ROOTMinuit2Minimizer(minimizer, algorithm);
+
+    } else if( minimizer == "GSLMultiMin" ) {
+        result = new ROOTMultiMinMinimizer(minimizer, algorithm);
+
+    } else if( minimizer == "GSLLMA" ) {
+        result = new ROOTLMAMinimizer(minimizer, algorithm);
+
+    } else if( minimizer == "GSLSimAn" ) {
+        result = new ROOTSimAnMinimizer(minimizer, algorithm);
+
+#ifdef HAS_GENETIC_MINIMIZER
+    } else if( minimizer == "Genetic" ) {
+        result = new ROOTGeneticMinimizer(minimizer, algorithm);
+#endif
+
+    }
+
+    if(!result) {
+        throw LogicErrorException("MinimizerFactory::createMinimizer() -> Error! Wrong minimizer name '"+minimizer+"'");
     }
+
     if( !options.empty() ) {
         try {
-            result->setOptions(options);
+            result->setOptionString(options);
         } catch (NotImplementedException& e) {
             std::cout << "MinimizerFactory::createMinimizer() -> Warning! Minimizer doesn't have method implemented" << e.what() << std::endl;
         }
@@ -105,3 +130,19 @@ IMinimizer *MinimizerFactory::createMinimizer(const std::string& minimizer, cons
 }
 
 
+
+//! Create minimizer using existing one. Only minimizer type and minimizer settings are propagated.
+//! This method serves as a kind of 'shallow' clone for minimizer.
+//! The reason why the minimizer doesn't have own clone method is because of complicate structure of
+//! ROOT minimizer internals.
+IMinimizer *MinimizerFactory::createMinimizer(const IMinimizer *minimizer)
+{
+    IMinimizer *result = createMinimizer(minimizer->getMinimizerName(), minimizer->getAlgorithmName());
+    result->setOptions(minimizer->getOptions());
+    return result;
+}
+
+
+
+
+
diff --git a/Fit/FitKernel/src/MinimizerOptions.cpp b/Fit/FitKernel/src/MinimizerOptions.cpp
index 4e997525acc545bcf844fe0023a1331be012761f..ffdf32360243984f9e089c7a3d26e0bd35b93628 100644
--- a/Fit/FitKernel/src/MinimizerOptions.cpp
+++ b/Fit/FitKernel/src/MinimizerOptions.cpp
@@ -14,13 +14,40 @@
 // ************************************************************************** //
 
 #include "MinimizerOptions.h"
-
+#include <iomanip>
 
 MinimizerOptions::MinimizerOptions()
     : m_tolerance(0.01)
     , m_precision(-1)
     , m_max_iterations(0)
     , m_max_function_calls(0)
+    , m_print_level(0)
+{
+
+}
+
+//void MinimizerOptions::setRealValue(const std::string &name, double val)
+//{
+//    m_RealOpts[name] = val;
+//}
+
+//void MinimizerOptions::setIntValue(const std::string &name, int val)
+//{
+//    m_IntOpts[name] = val;
+//}
+
+//void MinimizerOptions::setNamedValue(const std::string &name, const std::string &val)
+//{
+//    m_NamOpts[name] = val;
+//}
+
+
+void MinimizerOptions::print_common(std::ostream & os) const
 {
+    os << std::setw(24) << std::left << "Tolerance " << " : " << std::setw(15) << m_tolerance << std::endl;
+    os << std::setw(24) << std::left << "Precision " << " : " << std::setw(15) << m_precision << std::endl;
+    os << std::setw(24) << std::left << "MaxIterations " << " : " << std::setw(15) << m_max_iterations << std::endl;
+    os << std::setw(24) << std::left << "MaxFunctionCalls " << " : " << std::setw(15) << m_max_function_calls << std::endl;
+    os << std::setw(24) << std::left << "PrintLevel " << " : " << std::setw(15) << m_print_level << std::endl;
 
 }
diff --git a/Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp b/Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp
similarity index 99%
rename from Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp
rename to Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp
index ac687586322ea4eed3431d9c26fba7a0ad96059b..cb9234ef77f9cf0f2c7e477066edd09f03ed4e84 100644
--- a/Fit/FitKernel/src/ROOTGSLNLSMinimizer.cpp
+++ b/Fit/FitKernel/src/PatchedGSLNLSMinimizer.cpp
@@ -7,7 +7,7 @@
 //!
 // ************************************************************************** //
 
-#include "ROOTGSLNLSMinimizer.h"
+#include "PatchedGSLNLSMinimizer.h"
 
 //#include "Math/GSLNLSMinimizer.h"
 
diff --git a/Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp b/Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp
similarity index 99%
rename from Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp
rename to Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp
index d6f092f9c68c634498bce776ae5bc972c129b290..c2acf3092909db866e61e43cea93e10c2ea719f1 100644
--- a/Fit/FitKernel/src/ROOTGSLSimAnMinimizer.cpp
+++ b/Fit/FitKernel/src/PatchedGSLSimAnMinimizer.cpp
@@ -7,7 +7,7 @@
 //!
 // ************************************************************************** //
 
-#include "ROOTGSLSimAnMinimizer.h"
+#include "PatchedGSLSimAnMinimizer.h"
 
 
 //#include "Math/GSLSimAnMinimizer.h"
diff --git a/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp b/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..261a2adc1fe0658a15152cf96e8fe159c4c121c7
--- /dev/null
+++ b/Fit/FitKernel/src/ROOTGeneticMinimizer.cpp
@@ -0,0 +1,82 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/src/ROOTGeneticMinimizer.cpp
+//! @brief     Implements class ROOTGeneticMinimizer.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ROOTGeneticMinimizer.h"
+#include "Math/GenAlgoOptions.h"
+#include "MessageService.h"
+
+
+ROOTGeneticMinimizer::ROOTGeneticMinimizer(const std::string& minimizer_name, const std::string& algo_type)
+  : ROOTMinimizer(minimizer_name, algo_type)
+{
+    m_genetic_minimizer = new ROOT::Math::GeneticMinimizer();
+    m_root_minimizer = m_genetic_minimizer;
+
+    m_options.addValue("Cycles",3);
+    m_options.addValue("PopSize",300);
+    m_options.addValue("SC_rate",5);
+    m_options.addValue("SC_steps",10);
+    m_options.addValue("Steps",40);
+//    m_options.addValue("ConvCrit",0.1); // It's defined from tolerance inside GeneticMinimizer (ConvCrit=10*Tolerance())
+    m_options.addValue("SC_factor",0.95);
+}
+
+
+void ROOTGeneticMinimizer::setParameter(size_t index, const FitParameter *par)
+{
+    if( !par->isFixed() && !par->hasLowerAndUpperLimits()) {
+        std::ostringstream ostr;
+        ostr << "ROOTGeneticMinimizer::setParameter() -> Error! ";
+        ostr << "Genetic minimizer requires either fixed or limited AttLimits::limited(left,right) parameter. ";
+        ostr << " Parameter name '" << par->getName() << "', isFixed():" << par->isFixed() << " hasLowerandUpperLimits:" << par->hasLowerAndUpperLimits();
+        throw LogicErrorException(ostr.str());
+    }
+    ROOTMinimizer::setParameter(index, par);
+}
+
+
+// this function serve as a bridge and propagates MinimizerOptions inside GeneticMinimizer
+// (which has own messy options)
+void ROOTGeneticMinimizer::propagateOptions()
+{
+    ROOTMinimizer::propagateOptions();
+
+    if( m_options.getMaxIterations() > 0 && m_options.getMaxIterations() < m_options.getIntValue("Steps")) {
+        msglog(MSG::WARNING) << "ROOTGeneticMinimizer::propagateOptions() -> Max iterations smaller than Steps. ";
+        msglog(MSG::WARNING) << "Setting equal to steps " << m_options.getIntValue("Steps") << ".";
+        m_options.setMaxIterations(m_options.getIntValue("Steps"));
+    }
+
+    // accessing minimizer
+    ROOT::Math::MinimizerOptions options = m_genetic_minimizer->Options();
+
+    options.SetTolerance(m_options.getTolerance());
+    options.SetPrecision(m_options.getPrecision());
+    options.SetMaxFunctionCalls(m_options.getMaxFunctionCalls());
+    options.SetMaxIterations(m_options.getMaxIterations());
+
+    ROOT::Math::IOptions *geneticOpt = options.ExtraOptions();
+    geneticOpt->SetValue("Cycles", m_options.getIntValue("Cycles"));
+    geneticOpt->SetValue("PopSize", m_options.getIntValue("PopSize"));
+    geneticOpt->SetValue("SC_rate", m_options.getIntValue("SC_rate"));
+    geneticOpt->SetValue("SC_steps", m_options.getIntValue("SC_steps"));
+    geneticOpt->SetValue("Steps", m_options.getIntValue("Steps") );
+    geneticOpt->SetValue("ConvCrit", 10.*m_options.getTolerance());
+    geneticOpt->SetValue("SC_factor", m_options.getRealValue("SC_factor"));
+
+    m_genetic_minimizer->SetOptions(options);
+
+}
+
diff --git a/Fit/FitKernel/src/ROOTLMAMinimizer.cpp b/Fit/FitKernel/src/ROOTLMAMinimizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2db92fa1b5134d02644ddf4110a0736a7b531ee2
--- /dev/null
+++ b/Fit/FitKernel/src/ROOTLMAMinimizer.cpp
@@ -0,0 +1,32 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/src/ROOTMultiFitMinimizer.cpp
+//! @brief     Implements class ROOTMultiFitMinimizer.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ROOTLMAMinimizer.h"
+#include "Math/GenAlgoOptions.h"
+
+
+ROOTLMAMinimizer::ROOTLMAMinimizer(const std::string& minimizer_name, const std::string& algo_type)
+  : ROOTMinimizer(minimizer_name, algo_type)
+{
+    m_lma_minimizer = new ROOT::Patch::GSLNLSMinimizer(2);
+    m_root_minimizer = m_lma_minimizer;
+}
+
+// this function serve as a bridge and propagates MinimizerOptions inside GSLNLSMinimizer
+void ROOTLMAMinimizer::propagateOptions()
+{
+    ROOTMinimizer::propagateOptions();
+}
+
diff --git a/Fit/FitKernel/src/ROOTMinimizer.cpp b/Fit/FitKernel/src/ROOTMinimizer.cpp
index 2fdfd7ae7aed2940e151f9a441063e163a026b25..f92107e0f2311f5888d27670b7fc06040cc0d941 100644
--- a/Fit/FitKernel/src/ROOTMinimizer.cpp
+++ b/Fit/FitKernel/src/ROOTMinimizer.cpp
@@ -22,12 +22,15 @@
 #include <sstream>
 #include <boost/assign/list_of.hpp>
 #include <boost/assign/list_of.hpp>
-#include "ROOTGSLNLSMinimizer.h"
-#include "ROOTGSLSimAnMinimizer.h"
 #include "ROOTMinimizerHelper.h"
 #include "MinimizerOptions.h"
 
 
+#ifdef HAS_GENETIC_MINIMIZER
+#include "Math/GeneticMinimizer.h"
+#endif
+
+
 // ----------------------------------------------------------------------------
 // ROOTMinimizer c-tor
 //
@@ -37,23 +40,40 @@
 ROOTMinimizer::ROOTMinimizer(const std::string& minimizer_name, const std::string& algo_type)
     : m_minimizer_name(minimizer_name)
     , m_algo_type(algo_type)
+    , m_root_minimizer(0)
     , m_chi2_func(0)
     , m_gradient_func(0)
 {
-    if( m_minimizer_name == "GSLMultiFit") {
-        // hacked version of ROOT's GSL Levenberg-Marquardt minimizer
-        m_root_minimizer = new ROOT::Patch::GSLNLSMinimizer(2);
-    }else if( m_minimizer_name == "GSLSimAn") {
-        // hacked version of ROOT's GSL Simulated annealing minimizer
-        m_root_minimizer = new ROOT::Patch::GSLSimAnMinimizer();
-        // changing default options to more appropriate
-        setOptions("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1");
-    } else {
-        m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type );
-    }
-    if(!m_root_minimizer) {
-        throw LogicErrorException("Can't create minimizer with name '"+minimizer_name+"', algo '" + algo_type+"'");
-    }
+//    if( m_minimizer_name == "GSLMultiFit") {
+//        // hacked version of ROOT's GSL Levenberg-Marquardt minimizer
+//        m_root_minimizer = new ROOT::Patch::GSLNLSMinimizer(2);
+//    }else if( m_minimizer_name == "GSLSimAn") {
+//        // hacked version of ROOT's GSL Simulated annealing minimizer
+//        m_root_minimizer = new ROOT::Patch::GSLSimAnMinimizer();
+//        // changing default options to more appropriate
+//        setOptionString("ntries=100:niters=10:step_size=1.0:k=1:t_initial=50.0:mu=1.05:t_min=0.1");
+
+//    }else if( m_minimizer_name == "Minuit2") {
+//        m_root_minimizer = new ROOT::Minuit2::Minuit2Minimizer(algo_type.c_str());
+
+//    } else if( m_minimizer_name == "GSLMultiMin") {
+//        m_root_minimizer = new ROOT::Math::GSLMinimizer(algo_type.c_str());
+
+//#ifdef HAS_GENETIC_MINIMIZER
+//   } else if (m_minimizer_name ==  "Genetic") {
+//      m_root_minimizer = new ROOT::Math::GeneticMinimizer();
+//#endif
+
+////    } else {
+////        m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type );
+//    }
+//    if(!m_root_minimizer) {
+//        throw LogicErrorException("Can't create minimizer with name '"+minimizer_name+"', algo '" + algo_type+"'");
+//    }
+
+
+
+
 }
 
 
@@ -64,17 +84,6 @@ ROOTMinimizer::~ROOTMinimizer()
     delete m_gradient_func;
 }
 
-
-// check if algorithm needs gradient function (Levenberg-Marquardt, Fumili)
-bool ROOTMinimizer::isGradientBasedAgorithm()
-{
-    if (m_minimizer_name == "Fumili" ||
-        m_minimizer_name == "GSLMultiFit" ||
-        (m_minimizer_name == "Minuit2" && m_algo_type == "Fumili") ) return true;
-    return false;
-}
-
-
 void ROOTMinimizer::setParameters(const FitSuiteParameters& parameters)
 {
     size_t index(0);
@@ -104,22 +113,14 @@ void ROOTMinimizer::setParameter(size_t index, const FitParameter *par)
     } else if( !par->hasUpperLimit() && !par->hasLowerLimit() && !par->isFixed() ) {
         success=m_root_minimizer->SetVariable((int)index, par->getName().c_str(), par->getValue(), par->getStep());
     } else {
-        throw LogicErrorException("ROOTMinimizer::setVariable() -> Strange place... I wish I knew how I got here.");
-    }
-
-    if( m_minimizer_name == "Genetic" && (!par->isFixed() && !par->hasLowerAndUpperLimits()) ) {
-        std::ostringstream ostr;
-        ostr << "ROOTMinimizdr::setParameter() -> Error! ";
-        ostr << "Genetic minimizer requires either fixed or limited AttLimits::limited(left,right) parameter. ";
-        ostr << " Parameter name '" << par->getName() << "', isFixed():" << par->isFixed() << " hasLowerandUpperLimits:" << par->hasLowerAndUpperLimits();
-        throw LogicErrorException(ostr.str());
+        throw DomainErrorException("ROOTMinimizer::setVariable() -> Error!");
     }
 
     if( !success ) {
         std::ostringstream ostr;
         ostr << "ROOTMinimizer::setVariable() -> Error! Minimizer returned false while setting the variable." << std::endl;
-        ostr << "                                Probably given index has been already used for another variable name." << std::endl;
-        ostr << "                                Index:" << index << " name '" << par->getName() << "'" << std::endl;
+        ostr << "Probably given index has been already used for another variable name." << std::endl;
+        ostr << "Index:" << index << " name '" << par->getName() << "'" << std::endl;
         throw LogicErrorException(ostr.str());
     }
 }
@@ -127,6 +128,7 @@ void ROOTMinimizer::setParameter(size_t index, const FitParameter *par)
 
 void ROOTMinimizer::minimize()
 {
+    propagateOptions();
     m_root_minimizer->Minimize();
 }
 
@@ -138,6 +140,7 @@ void ROOTMinimizer::setChiSquaredFunction(function_chi2_t fun_chi2, size_t npara
     if( !isGradientBasedAgorithm() ) m_root_minimizer->SetFunction(*m_chi2_func);
 }
 
+
 void ROOTMinimizer::setGradientFunction(function_gradient_t fun_gradient, size_t nparameters, size_t ndatasize)
 {
     delete m_gradient_func;
@@ -168,7 +171,7 @@ std::vector<double > ROOTMinimizer::getErrorOfVariables() const
 
 void ROOTMinimizer::printResults() const
 {
-    ROOTMinimizerHelper::printResults(m_root_minimizer, m_minimizer_name, m_algo_type);
+    ROOTMinimizerHelper::printResults(this);
 }
 
 
@@ -178,29 +181,21 @@ size_t ROOTMinimizer::getNCalls() const
 }
 
 
-MinimizerOptions ROOTMinimizer::getOptions() const
-{
-    MinimizerOptions options;
-    options.setTolerance(m_root_minimizer->Tolerance());
-    options.setPrecision(m_root_minimizer->Precision());
-    options.setMaxFunctionCalls(m_root_minimizer->MaxFunctionCalls());
-    options.setMaxIterations(m_root_minimizer->MaxIterations());
-    return options;
-}
-
 void ROOTMinimizer::setOptions(const MinimizerOptions &options)
 {
-    m_root_minimizer->SetTolerance(options.getTolerance());
-    m_root_minimizer->SetPrecision(options.getPrecision());
-    m_root_minimizer->SetMaxFunctionCalls(options.getMaxFunctionCalls());
-    m_root_minimizer->SetMaxIterations(options.getMaxIterations());
+    m_options = options;
+    propagateOptions();
 }
 
-void ROOTMinimizer::setOptions(const std::string& options)
+
+void ROOTMinimizer::propagateOptions()
 {
-    ROOTMinimizerHelper::setOptions(m_root_minimizer, options);
+    m_root_minimizer->SetTolerance(m_options.getTolerance());
+    m_root_minimizer->SetPrecision(m_options.getPrecision());
+    m_root_minimizer->SetMaxFunctionCalls(m_options.getMaxFunctionCalls());
+    m_root_minimizer->SetMaxIterations(m_options.getMaxIterations());
+    m_root_minimizer->SetPrintLevel(m_options.getPrintLevel());
 }
 
 
 
-
diff --git a/Fit/FitKernel/src/ROOTMinimizerHelper.cpp b/Fit/FitKernel/src/ROOTMinimizerHelper.cpp
index 6e1f7dbb1610971f6fd4fbffa16167d5592778af..35006c2be91cfcfea233267b43baab9e0cb1c7a4 100644
--- a/Fit/FitKernel/src/ROOTMinimizerHelper.cpp
+++ b/Fit/FitKernel/src/ROOTMinimizerHelper.cpp
@@ -14,9 +14,10 @@
 // ************************************************************************** //
 
 #include "ROOTMinimizerHelper.h"
-#include "ROOTGSLSimAnMinimizer.h"
+#include "PatchedGSLSimAnMinimizer.h"
 #include "Utils.h"
 #include <boost/lexical_cast.hpp>
+#include "Math/GenAlgoOptions.h"
 
 // ----------------------------------------------------------------------------
 // translate text with options into appropriate calls of minimizer's set method
@@ -125,23 +126,24 @@ bool ROOTMinimizerHelper::processCommandGSLSimAn(ROOT::Patch::GSLSimAnMinimizer
     return success;
 }
 
-
 // Printing minimizer results on the screen
-void ROOTMinimizerHelper::printResults(ROOT::Math::Minimizer *minimizer, const std::string& minimizer_name, const std::string& algo_type)
+void ROOTMinimizerHelper::printResults(const ROOTMinimizer *minimizer)
 {
     std::cout << "--------------------------------------------------------------------------------" << std::endl;
-    std::cout << std::setw(25) << std::left << "  MinimizerType"      << ": " << minimizer_name << std::endl;
-    std::cout << std::setw(25) << std::left << "  MinimizerAlgorithm" << ": " << algo_type << std::endl;
-    printOptions(minimizer);
-    printStatus(minimizer);
-    printVariables(minimizer);
+    std::cout << std::setw(25) << std::left << "  MinimizerType"      << ": " << minimizer->getMinimizerName() << std::endl;
+    std::cout << std::setw(25) << std::left << "  MinimizerAlgorithm" << ": " << minimizer->getAlgorithmName() << std::endl;
+    //printOptions(minimizer->getROOTMinimizer());
+    std::cout << "--- Options --------------------------------------------------------------------" << std::endl;
+    minimizer->getOptions().print();
+    printStatus(minimizer->getROOTMinimizer());
+    printVariables(minimizer->getROOTMinimizer());
     // own print method of the minimizer
     //m_root_minimizer->PrintResults();
 }
 
 
 // print minimizer description
-void ROOTMinimizerHelper::printOptions(ROOT::Math::Minimizer *minimizer)
+void ROOTMinimizerHelper::printOptions(const ROOT::Math::Minimizer *minimizer)
 {
     std::cout << "--- Options --------------------------------------------------------------------" << std::endl;
     ROOT::Math::MinimizerOptions opt = minimizer->Options();
@@ -151,11 +153,16 @@ void ROOTMinimizerHelper::printOptions(ROOT::Math::Minimizer *minimizer)
     std::cout << std::setw(25) << std::left << "  MaxIterations"      << ": " << minimizer->MaxIterations() << std::endl;
     std::cout << std::setw(25) << std::left << "  Precision"          << ": " << minimizer->Precision() << std::endl;
     std::cout << std::setw(25) << std::left << "  ErrorDefinition"    << ": " << minimizer->ErrorDef() << " (1-chi2, 0.5 likelihood)" << std::endl;
-    std::cout << std::setw(25) << std::left << "  ExtraOptions"       << ": " << opt.ExtraOptions() << std::endl;
+    //std::cout << std::setw(25) << std::left << "  ExtraOptions"       << ": " << opt.ExtraOptions() << std::endl;
+    if(opt.ExtraOptions()) {
+        std::cout << "--- Extra Options --------------------------------------------------------------" << std::endl;
+        opt.ExtraOptions()->Print();
+    }
+
 }
 
 
-void ROOTMinimizerHelper::printStatus(ROOT::Math::Minimizer *minimizer)
+void ROOTMinimizerHelper::printStatus(const ROOT::Math::Minimizer *minimizer)
 {
     std::cout << "--- Status --------------------------------------------------------------------- " << std::endl;
     std::map<int, std::string> minimizerStatus;
@@ -194,7 +201,7 @@ void ROOTMinimizerHelper::printStatus(ROOT::Math::Minimizer *minimizer)
 }
 
 
-void ROOTMinimizerHelper::printVariables(ROOT::Math::Minimizer *minimizer)
+void ROOTMinimizerHelper::printVariables(const ROOT::Math::Minimizer *minimizer)
 {
     std::cout << "--- Variables ------------------------------------------------------------------" << std::endl;
     std::cout << std::setw(25) << std::left << "  NumberOfVariables"      << ": "
diff --git a/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp b/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d3771c75a47386e0db0f4ea5c234221dd57f150
--- /dev/null
+++ b/Fit/FitKernel/src/ROOTMinuit2Minimizer.cpp
@@ -0,0 +1,46 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/src/ROOTMinuit2Minimizer.cpp
+//! @brief     Implements class ROOTMinuit2Minimizer.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ROOTMinuit2Minimizer.h"
+
+
+ROOTMinuit2Minimizer::ROOTMinuit2Minimizer(const std::string& minimizer_name, const std::string& algo_type)
+    : ROOTMinimizer(minimizer_name, algo_type)
+{
+    m_minuit2_minimizer = new ROOT::Minuit2::Minuit2Minimizer(algo_type.c_str());
+    m_root_minimizer = m_minuit2_minimizer;
+
+    m_options.addValue("Strategy", 1);
+    m_options.addValue("ErrorDef", 1);
+
+}
+
+
+bool ROOTMinuit2Minimizer::isGradientBasedAgorithm()
+{
+    if(m_algo_type == "Fumili") return true;
+    return false;
+}
+
+
+// this function serve as a bridge and propagates MinimizerOptions inside Minuit2Minimizer
+void ROOTMinuit2Minimizer::propagateOptions()
+{
+    ROOTMinimizer::propagateOptions();
+    m_minuit2_minimizer->SetStrategy(m_options.getIntValue("Strategy"));
+    m_minuit2_minimizer->SetErrorDef(m_options.getIntValue("ErrorDef"));
+}
+
+
diff --git a/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp b/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5be846056daad0d865cb7f859692d6871d12451f
--- /dev/null
+++ b/Fit/FitKernel/src/ROOTMultiMinMinimizer.cpp
@@ -0,0 +1,33 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/src/ROOTMultiMinMinimizer.cpp
+//! @brief     Implements class ROOTMultiMinMinimizer.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ROOTMultiMinMinimizer.h"
+
+
+ROOTMultiMinMinimizer::ROOTMultiMinMinimizer(const std::string& minimizer_name, const std::string& algo_type)
+    : ROOTMinimizer(minimizer_name, algo_type)
+{
+    m_gsl_minimizer = new ROOT::Math::GSLMinimizer(algo_type.c_str());
+    m_root_minimizer = m_gsl_minimizer;
+}
+
+
+// this function serve as a bridge and propagates MinimizerOptions inside Minuit2Minimizer
+void ROOTMultiMinMinimizer::propagateOptions()
+{
+    ROOTMinimizer::propagateOptions();
+}
+
+
diff --git a/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp b/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f3215d3602f3c24b0196f0549213314374bdbe7e
--- /dev/null
+++ b/Fit/FitKernel/src/ROOTSimAnMinimizer.cpp
@@ -0,0 +1,48 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      FitKernel/src/ROOTSimAnMinimizer.cpp
+//! @brief     Implements class ROOTSimAnMinimizer.
+//
+//! Homepage:  apps.jcns.fz-juelich.de/BornAgain
+//! License:   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ROOTSimAnMinimizer.h"
+
+ROOTSimAnMinimizer::ROOTSimAnMinimizer(const std::string& minimizer_name, const std::string& algo_type)
+    : ROOTMinimizer(minimizer_name, algo_type)
+{
+    m_siman_minimizer = new ROOT::Patch::GSLSimAnMinimizer();
+    m_root_minimizer = m_siman_minimizer;
+
+    m_options.addValue("ntries", 100);
+    m_options.addValue("niters_fixed_t", 10);
+    m_options.addValue("step_size", 1.0);
+    m_options.addValue("k", 1.0);
+    m_options.addValue("t_initial", 50.0);
+    m_options.addValue("mu", 1.05);
+    m_options.addValue("t_min", 0.1);
+    m_options.setMaxIterations(100);
+}
+
+
+// this function serve as a bridge and propagates MinimizerOptions inside GSLSimAnMinimizer
+void ROOTSimAnMinimizer::propagateOptions()
+{
+    ROOTMinimizer::propagateOptions();
+
+    ROOT::Math::GSLSimAnParams& pars = m_siman_minimizer->getSolver().Params();
+    m_options.getValue("ntries", pars.n_tries);
+    m_options.getValue("niters_fixed_t", pars.iters_fixed_T);
+    m_options.getValue("step_size", pars.step_size);
+    m_options.getValue("k", pars.k);
+    m_options.getValue("t_initial", pars.t_initial);
+    m_options.getValue("mu", pars.mu);
+    m_options.getValue("t_min", pars.t_min);
+}
diff --git a/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h b/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2de9ca4390b569e9a8aa32a352e08c6623c5cc9d
--- /dev/null
+++ b/Fit/PythonAPI/inc/SquaredFunctionSimError.pypp.h
@@ -0,0 +1,11 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence 
+//! @brief automatically generated boost::python code for PythonCoreAPI  
+
+#ifndef SquaredFunctionSimError_hpp__pyplusplus_wrapper
+#define SquaredFunctionSimError_hpp__pyplusplus_wrapper
+
+void register_SquaredFunctionSimError_class();
+
+#endif//SquaredFunctionSimError_hpp__pyplusplus_wrapper
diff --git a/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp b/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp
index 484e94f4552f4ca187f73d9840d6bb0d1363ff00..510f4de2dcc605751b4a40d05879260082197d29 100644
--- a/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp
+++ b/Fit/PythonAPI/src/FitStrategyAdjustMinimizer.pypp.cpp
@@ -16,21 +16,42 @@ namespace bp = boost::python;
 
 struct FitStrategyAdjustMinimizer_wrapper : FitStrategyAdjustMinimizer, bp::wrapper< FitStrategyAdjustMinimizer > {
 
-    FitStrategyAdjustMinimizer_wrapper()
-    : FitStrategyAdjustMinimizer()
+    FitStrategyAdjustMinimizer_wrapper(FitStrategyAdjustMinimizer const & arg )
+    : FitStrategyAdjustMinimizer( arg )
       , bp::wrapper< FitStrategyAdjustMinimizer >(){
-        // null constructor
+        // copy constructor
         
     }
 
-    virtual ::IFitStrategy * clone(  ) const {
-        bp::override func_clone = this->get_override( "clone" );
-        return func_clone(  );
+    FitStrategyAdjustMinimizer_wrapper( )
+    : FitStrategyAdjustMinimizer( )
+      , bp::wrapper< FitStrategyAdjustMinimizer >(){
+        // null constructor
+    
     }
 
-    virtual void execute(  ){
-        bp::override func_execute = this->get_override( "execute" );
-        func_execute(  );
+    virtual ::FitStrategyAdjustMinimizer * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else
+            return this->FitStrategyAdjustMinimizer::clone(  );
+    }
+    
+    
+    ::FitStrategyAdjustMinimizer * default_clone(  ) const  {
+        return FitStrategyAdjustMinimizer::clone( );
+    }
+
+    virtual void execute(  ) {
+        if( bp::override func_execute = this->get_override( "execute" ) )
+            func_execute(  );
+        else
+            this->FitStrategyAdjustMinimizer::execute(  );
+    }
+    
+    
+    void default_execute(  ) {
+        FitStrategyAdjustMinimizer::execute( );
     }
 
 };
@@ -38,26 +59,50 @@ struct FitStrategyAdjustMinimizer_wrapper : FitStrategyAdjustMinimizer, bp::wrap
 void register_FitStrategyAdjustMinimizer_class(){
 
     { //::FitStrategyAdjustMinimizer
-        typedef bp::class_< FitStrategyAdjustMinimizer_wrapper, bp::bases< IFitStrategy >, boost::noncopyable > FitStrategyAdjustMinimizer_exposer_t;
-        FitStrategyAdjustMinimizer_exposer_t FitStrategyAdjustMinimizer_exposer = FitStrategyAdjustMinimizer_exposer_t( "FitStrategyAdjustMinimizer" );
+        typedef bp::class_< FitStrategyAdjustMinimizer_wrapper, bp::bases< IFitStrategy > > FitStrategyAdjustMinimizer_exposer_t;
+        FitStrategyAdjustMinimizer_exposer_t FitStrategyAdjustMinimizer_exposer = FitStrategyAdjustMinimizer_exposer_t( "FitStrategyAdjustMinimizer", bp::init< >() );
         bp::scope FitStrategyAdjustMinimizer_scope( FitStrategyAdjustMinimizer_exposer );
-        { //::IFitStrategy::clone
+        { //::FitStrategyAdjustMinimizer::clone
         
-            typedef ::IFitStrategy * ( ::IFitStrategy::*clone_function_type )(  ) const;
+            typedef ::FitStrategyAdjustMinimizer * ( ::FitStrategyAdjustMinimizer::*clone_function_type )(  ) const;
+            typedef ::FitStrategyAdjustMinimizer * ( FitStrategyAdjustMinimizer_wrapper::*default_clone_function_type )(  ) const;
             
             FitStrategyAdjustMinimizer_exposer.def( 
                 "clone"
-                , bp::pure_virtual( clone_function_type(&::IFitStrategy::clone) )
+                , clone_function_type(&::FitStrategyAdjustMinimizer::clone)
+                , default_clone_function_type(&FitStrategyAdjustMinimizer_wrapper::default_clone)
                 , bp::return_value_policy< bp::manage_new_object >() );
         
         }
-        { //::IFitStrategy::execute
+        { //::FitStrategyAdjustMinimizer::execute
         
-            typedef void ( ::IFitStrategy::*execute_function_type )(  ) ;
+            typedef void ( ::FitStrategyAdjustMinimizer::*execute_function_type )(  ) ;
+            typedef void ( FitStrategyAdjustMinimizer_wrapper::*default_execute_function_type )(  ) ;
             
             FitStrategyAdjustMinimizer_exposer.def( 
                 "execute"
-                , bp::pure_virtual( execute_function_type(&::IFitStrategy::execute) ) );
+                , execute_function_type(&::FitStrategyAdjustMinimizer::execute)
+                , default_execute_function_type(&FitStrategyAdjustMinimizer_wrapper::default_execute) );
+        
+        }
+        { //::FitStrategyAdjustMinimizer::getMinimizer
+        
+            typedef ::IMinimizer * ( ::FitStrategyAdjustMinimizer::*getMinimizer_function_type )(  ) ;
+            
+            FitStrategyAdjustMinimizer_exposer.def( 
+                "getMinimizer"
+                , getMinimizer_function_type( &::FitStrategyAdjustMinimizer::getMinimizer )
+                , bp::return_value_policy< bp::reference_existing_object >() );
+        
+        }
+        { //::FitStrategyAdjustMinimizer::setMinimizer
+        
+            typedef void ( ::FitStrategyAdjustMinimizer::*setMinimizer_function_type )( ::IMinimizer * ) ;
+            
+            FitStrategyAdjustMinimizer_exposer.def( 
+                "setMinimizer"
+                , setMinimizer_function_type( &::FitStrategyAdjustMinimizer::setMinimizer )
+                , ( bp::arg("minimizer") ) );
         
         }
     }
diff --git a/Fit/PythonAPI/src/IMinimizer.pypp.cpp b/Fit/PythonAPI/src/IMinimizer.pypp.cpp
index 692986d6c7952638bb5402f67f4ec14b20eae6da..2ca3a9995dccae2cfbe454093505fb843cb4be06 100644
--- a/Fit/PythonAPI/src/IMinimizer.pypp.cpp
+++ b/Fit/PythonAPI/src/IMinimizer.pypp.cpp
@@ -35,6 +35,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > {
         IMinimizer::clear( );
     }
 
+    virtual ::std::string getAlgorithmName(  ) const  {
+        if( bp::override func_getAlgorithmName = this->get_override( "getAlgorithmName" ) )
+            return func_getAlgorithmName(  );
+        else
+            return this->IMinimizer::getAlgorithmName(  );
+    }
+    
+    
+    ::std::string default_getAlgorithmName(  ) const  {
+        return IMinimizer::getAlgorithmName( );
+    }
+
     virtual double getErrorOfVariable( ::std::size_t arg0 ) const  {
         if( bp::override func_getErrorOfVariable = this->get_override( "getErrorOfVariable" ) )
             return func_getErrorOfVariable( arg0 );
@@ -71,6 +83,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > {
         return IMinimizer::getMinValue( );
     }
 
+    virtual ::std::string getMinimizerName(  ) const  {
+        if( bp::override func_getMinimizerName = this->get_override( "getMinimizerName" ) )
+            return func_getMinimizerName(  );
+        else
+            return this->IMinimizer::getMinimizerName(  );
+    }
+    
+    
+    ::std::string default_getMinimizerName(  ) const  {
+        return IMinimizer::getMinimizerName( );
+    }
+
     virtual ::std::size_t getNCalls(  ) const  {
         if( bp::override func_getNCalls = this->get_override( "getNCalls" ) )
             return func_getNCalls(  );
@@ -95,18 +119,6 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > {
         return IMinimizer::getNumberOfVariables( );
     }
 
-    virtual ::MinimizerOptions getOptions(  ) const  {
-        if( bp::override func_getOptions = this->get_override( "getOptions" ) )
-            return func_getOptions(  );
-        else
-            return this->IMinimizer::getOptions(  );
-    }
-    
-    
-    ::MinimizerOptions default_getOptions(  ) const  {
-        return IMinimizer::getOptions( );
-    }
-
     virtual double getValueOfVariableAtMinimum( ::std::size_t arg0 ) const  {
         if( bp::override func_getValueOfVariableAtMinimum = this->get_override( "getValueOfVariableAtMinimum" ) )
             return func_getValueOfVariableAtMinimum( arg0 );
@@ -131,6 +143,18 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > {
         return IMinimizer::getValueOfVariablesAtMinimum( );
     }
 
+    virtual bool isGradientBasedAgorithm(  ) {
+        if( bp::override func_isGradientBasedAgorithm = this->get_override( "isGradientBasedAgorithm" ) )
+            return func_isGradientBasedAgorithm(  );
+        else
+            return this->IMinimizer::isGradientBasedAgorithm(  );
+    }
+    
+    
+    bool default_isGradientBasedAgorithm(  ) {
+        return IMinimizer::isGradientBasedAgorithm( );
+    }
+
     virtual void minimize(  ){
         bp::override func_minimize = this->get_override( "minimize" );
         func_minimize(  );
@@ -148,28 +172,28 @@ struct IMinimizer_wrapper : IMinimizer, bp::wrapper< IMinimizer > {
         IMinimizer::printResults( );
     }
 
-    virtual void setOptions( ::MinimizerOptions const & arg0 ) {
-        if( bp::override func_setOptions = this->get_override( "setOptions" ) )
-            func_setOptions( boost::ref(arg0) );
+    virtual void setOptionString( ::std::string const & arg0 ) {
+        if( bp::override func_setOptionString = this->get_override( "setOptionString" ) )
+            func_setOptionString( arg0 );
         else
-            this->IMinimizer::setOptions( boost::ref(arg0) );
+            this->IMinimizer::setOptionString( arg0 );
     }
     
     
-    void default_setOptions( ::MinimizerOptions const & arg0 ) {
-        IMinimizer::setOptions( boost::ref(arg0) );
+    void default_setOptionString( ::std::string const & arg0 ) {
+        IMinimizer::setOptionString( arg0 );
     }
 
-    virtual void setOptions( ::std::string const & arg0 ) {
+    virtual void setOptions( ::MinimizerOptions const & arg0 ) {
         if( bp::override func_setOptions = this->get_override( "setOptions" ) )
-            func_setOptions( arg0 );
+            func_setOptions( boost::ref(arg0) );
         else
-            this->IMinimizer::setOptions( arg0 );
+            this->IMinimizer::setOptions( boost::ref(arg0) );
     }
     
     
-    void default_setOptions( ::std::string const & arg0 ) {
-        IMinimizer::setOptions( arg0 );
+    void default_setOptions( ::MinimizerOptions const & arg0 ) {
+        IMinimizer::setOptions( boost::ref(arg0) );
     }
 
     virtual void setParameters( ::FitSuiteParameters const & arg0 ) {
@@ -202,6 +226,17 @@ void register_IMinimizer_class(){
                 , clear_function_type(&::IMinimizer::clear)
                 , default_clear_function_type(&IMinimizer_wrapper::default_clear) );
         
+        }
+        { //::IMinimizer::getAlgorithmName
+        
+            typedef ::std::string ( ::IMinimizer::*getAlgorithmName_function_type )(  ) const;
+            typedef ::std::string ( IMinimizer_wrapper::*default_getAlgorithmName_function_type )(  ) const;
+            
+            IMinimizer_exposer.def( 
+                "getAlgorithmName"
+                , getAlgorithmName_function_type(&::IMinimizer::getAlgorithmName)
+                , default_getAlgorithmName_function_type(&IMinimizer_wrapper::default_getAlgorithmName) );
+        
         }
         { //::IMinimizer::getErrorOfVariable
         
@@ -236,6 +271,17 @@ void register_IMinimizer_class(){
                 , getMinValue_function_type(&::IMinimizer::getMinValue)
                 , default_getMinValue_function_type(&IMinimizer_wrapper::default_getMinValue) );
         
+        }
+        { //::IMinimizer::getMinimizerName
+        
+            typedef ::std::string ( ::IMinimizer::*getMinimizerName_function_type )(  ) const;
+            typedef ::std::string ( IMinimizer_wrapper::*default_getMinimizerName_function_type )(  ) const;
+            
+            IMinimizer_exposer.def( 
+                "getMinimizerName"
+                , getMinimizerName_function_type(&::IMinimizer::getMinimizerName)
+                , default_getMinimizerName_function_type(&IMinimizer_wrapper::default_getMinimizerName) );
+        
         }
         { //::IMinimizer::getNCalls
         
@@ -261,13 +307,12 @@ void register_IMinimizer_class(){
         }
         { //::IMinimizer::getOptions
         
-            typedef ::MinimizerOptions ( ::IMinimizer::*getOptions_function_type )(  ) const;
-            typedef ::MinimizerOptions ( IMinimizer_wrapper::*default_getOptions_function_type )(  ) const;
+            typedef ::MinimizerOptions & ( ::IMinimizer::*getOptions_function_type )(  ) ;
             
             IMinimizer_exposer.def( 
                 "getOptions"
                 , getOptions_function_type(&::IMinimizer::getOptions)
-                , default_getOptions_function_type(&IMinimizer_wrapper::default_getOptions) );
+                , bp::return_internal_reference< >() );
         
         }
         { //::IMinimizer::getValueOfVariableAtMinimum
@@ -292,6 +337,17 @@ void register_IMinimizer_class(){
                 , getValueOfVariablesAtMinimum_function_type(&::IMinimizer::getValueOfVariablesAtMinimum)
                 , default_getValueOfVariablesAtMinimum_function_type(&IMinimizer_wrapper::default_getValueOfVariablesAtMinimum) );
         
+        }
+        { //::IMinimizer::isGradientBasedAgorithm
+        
+            typedef bool ( ::IMinimizer::*isGradientBasedAgorithm_function_type )(  ) ;
+            typedef bool ( IMinimizer_wrapper::*default_isGradientBasedAgorithm_function_type )(  ) ;
+            
+            IMinimizer_exposer.def( 
+                "isGradientBasedAgorithm"
+                , isGradientBasedAgorithm_function_type(&::IMinimizer::isGradientBasedAgorithm)
+                , default_isGradientBasedAgorithm_function_type(&IMinimizer_wrapper::default_isGradientBasedAgorithm) );
+        
         }
         { //::IMinimizer::minimize
         
@@ -313,22 +369,22 @@ void register_IMinimizer_class(){
                 , default_printResults_function_type(&IMinimizer_wrapper::default_printResults) );
         
         }
-        { //::IMinimizer::setOptions
+        { //::IMinimizer::setOptionString
         
-            typedef void ( ::IMinimizer::*setOptions_function_type )( ::MinimizerOptions const & ) ;
-            typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::MinimizerOptions const & ) ;
+            typedef void ( ::IMinimizer::*setOptionString_function_type )( ::std::string const & ) ;
+            typedef void ( IMinimizer_wrapper::*default_setOptionString_function_type )( ::std::string const & ) ;
             
             IMinimizer_exposer.def( 
-                "setOptions"
-                , setOptions_function_type(&::IMinimizer::setOptions)
-                , default_setOptions_function_type(&IMinimizer_wrapper::default_setOptions)
+                "setOptionString"
+                , setOptionString_function_type(&::IMinimizer::setOptionString)
+                , default_setOptionString_function_type(&IMinimizer_wrapper::default_setOptionString)
                 , ( bp::arg("arg0") ) );
         
         }
         { //::IMinimizer::setOptions
         
-            typedef void ( ::IMinimizer::*setOptions_function_type )( ::std::string const & ) ;
-            typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::std::string const & ) ;
+            typedef void ( ::IMinimizer::*setOptions_function_type )( ::MinimizerOptions const & ) ;
+            typedef void ( IMinimizer_wrapper::*default_setOptions_function_type )( ::MinimizerOptions const & ) ;
             
             IMinimizer_exposer.def( 
                 "setOptions"
diff --git a/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp b/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp
index 40c2e5b47b3311c315ac6dbc8982a44ccd783302..f5102837bca21a738f397d30cd9752699c273ab9 100644
--- a/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp
+++ b/Fit/PythonAPI/src/MinimizerOptions.pypp.cpp
@@ -20,6 +20,46 @@ void register_MinimizerOptions_class(){
         typedef bp::class_< MinimizerOptions > MinimizerOptions_exposer_t;
         MinimizerOptions_exposer_t MinimizerOptions_exposer = MinimizerOptions_exposer_t( "MinimizerOptions", bp::init< >() );
         bp::scope MinimizerOptions_scope( MinimizerOptions_exposer );
+        { //::MinimizerOptions::addValue
+        
+            typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,double ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "addValue"
+                , addValue_function_type( &::MinimizerOptions::addValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::addValue
+        
+            typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,int ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "addValue"
+                , addValue_function_type( &::MinimizerOptions::addValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::addValue
+        
+            typedef void ( ::MinimizerOptions::*addValue_function_type )( ::std::string const &,::std::string const & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "addValue"
+                , addValue_function_type( &::MinimizerOptions::addValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::getIntValue
+        
+            typedef int ( ::MinimizerOptions::*getIntValue_function_type )( ::std::string const & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getIntValue"
+                , getIntValue_function_type( &::MinimizerOptions::getIntValue )
+                , ( bp::arg("name") ) );
+        
+        }
         { //::MinimizerOptions::getMaxFunctionCalls
         
             typedef int ( ::MinimizerOptions::*getMaxFunctionCalls_function_type )(  ) const;
@@ -37,6 +77,16 @@ void register_MinimizerOptions_class(){
                 "getMaxIterations"
                 , getMaxIterations_function_type( &::MinimizerOptions::getMaxIterations ) );
         
+        }
+        { //::MinimizerOptions::getNamedValue
+        
+            typedef ::std::string ( ::MinimizerOptions::*getNamedValue_function_type )( ::std::string const & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getNamedValue"
+                , getNamedValue_function_type( &::MinimizerOptions::getNamedValue )
+                , ( bp::arg("name") ) );
+        
         }
         { //::MinimizerOptions::getPrecision
         
@@ -46,6 +96,25 @@ void register_MinimizerOptions_class(){
                 "getPrecision"
                 , getPrecision_function_type( &::MinimizerOptions::getPrecision ) );
         
+        }
+        { //::MinimizerOptions::getPrintLevel
+        
+            typedef int ( ::MinimizerOptions::*getPrintLevel_function_type )(  ) const;
+            
+            MinimizerOptions_exposer.def( 
+                "getPrintLevel"
+                , getPrintLevel_function_type( &::MinimizerOptions::getPrintLevel ) );
+        
+        }
+        { //::MinimizerOptions::getRealValue
+        
+            typedef double ( ::MinimizerOptions::*getRealValue_function_type )( ::std::string const & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getRealValue"
+                , getRealValue_function_type( &::MinimizerOptions::getRealValue )
+                , ( bp::arg("name") ) );
+        
         }
         { //::MinimizerOptions::getTolerance
         
@@ -55,6 +124,45 @@ void register_MinimizerOptions_class(){
                 "getTolerance"
                 , getTolerance_function_type( &::MinimizerOptions::getTolerance ) );
         
+        }
+        { //::MinimizerOptions::getValue
+        
+            typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,int & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getValue"
+                , getValue_function_type( &::MinimizerOptions::getValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::getValue
+        
+            typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,double & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getValue"
+                , getValue_function_type( &::MinimizerOptions::getValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::getValue
+        
+            typedef void ( ::MinimizerOptions::*getValue_function_type )( ::std::string const &,::std::string & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "getValue"
+                , getValue_function_type( &::MinimizerOptions::getValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::print
+        
+            typedef void ( ::MinimizerOptions::*print_function_type )(  ) const;
+            
+            MinimizerOptions_exposer.def( 
+                "print"
+                , print_function_type( &::MinimizerOptions::print ) );
+        
         }
         { //::MinimizerOptions::setMaxFunctionCalls
         
@@ -85,6 +193,16 @@ void register_MinimizerOptions_class(){
                 , setPrecision_function_type( &::MinimizerOptions::setPrecision )
                 , ( bp::arg("precision") ) );
         
+        }
+        { //::MinimizerOptions::setPrintLevel
+        
+            typedef void ( ::MinimizerOptions::*setPrintLevel_function_type )( int ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "setPrintLevel"
+                , setPrintLevel_function_type( &::MinimizerOptions::setPrintLevel )
+                , ( bp::arg("print_level") ) );
+        
         }
         { //::MinimizerOptions::setTolerance
         
@@ -96,6 +214,36 @@ void register_MinimizerOptions_class(){
                 , ( bp::arg("tolerance") ) );
         
         }
+        { //::MinimizerOptions::setValue
+        
+            typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,double ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "setValue"
+                , setValue_function_type( &::MinimizerOptions::setValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::setValue
+        
+            typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,int ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "setValue"
+                , setValue_function_type( &::MinimizerOptions::setValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
+        { //::MinimizerOptions::setValue
+        
+            typedef void ( ::MinimizerOptions::*setValue_function_type )( ::std::string const &,::std::string const & ) ;
+            
+            MinimizerOptions_exposer.def( 
+                "setValue"
+                , setValue_function_type( &::MinimizerOptions::setValue )
+                , ( bp::arg("name"), bp::arg("val") ) );
+        
+        }
     }
 
 }
diff --git a/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp b/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..484555f829fd5ee07ebe7f61700186dac8790370
--- /dev/null
+++ b/Fit/PythonAPI/src/SquaredFunctionSimError.pypp.cpp
@@ -0,0 +1,108 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence 
+//! @brief automatically generated boost::python code for PythonCoreAPI  
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "PythonFitList.h"
+#include "SquaredFunctionSimError.pypp.h"
+
+namespace bp = boost::python;
+
+struct SquaredFunctionSimError_wrapper : SquaredFunctionSimError, bp::wrapper< SquaredFunctionSimError > {
+
+    SquaredFunctionSimError_wrapper( )
+    : SquaredFunctionSimError( )
+      , bp::wrapper< SquaredFunctionSimError >(){
+        // null constructor
+    
+    }
+
+    virtual double calculateSquaredDifference( double real_value, double simulated_value ) const  {
+        if( bp::override func_calculateSquaredDifference = this->get_override( "calculateSquaredDifference" ) )
+            return func_calculateSquaredDifference( real_value, simulated_value );
+        else
+            return this->SquaredFunctionSimError::calculateSquaredDifference( real_value, simulated_value );
+    }
+    
+    
+    double default_calculateSquaredDifference( double real_value, double simulated_value ) const  {
+        return SquaredFunctionSimError::calculateSquaredDifference( real_value, simulated_value );
+    }
+
+    virtual double calculateSquaredError( double real_value, double simulated_value ) const  {
+        if( bp::override func_calculateSquaredError = this->get_override( "calculateSquaredError" ) )
+            return func_calculateSquaredError( real_value, simulated_value );
+        else
+            return this->SquaredFunctionSimError::calculateSquaredError( real_value, simulated_value );
+    }
+    
+    
+    double default_calculateSquaredError( double real_value, double simulated_value ) const  {
+        return SquaredFunctionSimError::calculateSquaredError( real_value, simulated_value );
+    }
+
+    virtual ::SquaredFunctionSimError * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else
+            return this->SquaredFunctionSimError::clone(  );
+    }
+    
+    
+    ::SquaredFunctionSimError * default_clone(  ) const  {
+        return SquaredFunctionSimError::clone( );
+    }
+
+};
+
+void register_SquaredFunctionSimError_class(){
+
+    { //::SquaredFunctionSimError
+        typedef bp::class_< SquaredFunctionSimError_wrapper, bp::bases< ISquaredFunction >, boost::noncopyable > SquaredFunctionSimError_exposer_t;
+        SquaredFunctionSimError_exposer_t SquaredFunctionSimError_exposer = SquaredFunctionSimError_exposer_t( "SquaredFunctionSimError", bp::init< >() );
+        bp::scope SquaredFunctionSimError_scope( SquaredFunctionSimError_exposer );
+        { //::SquaredFunctionSimError::calculateSquaredDifference
+        
+            typedef double ( ::SquaredFunctionSimError::*calculateSquaredDifference_function_type )( double,double ) const;
+            typedef double ( SquaredFunctionSimError_wrapper::*default_calculateSquaredDifference_function_type )( double,double ) const;
+            
+            SquaredFunctionSimError_exposer.def( 
+                "calculateSquaredDifference"
+                , calculateSquaredDifference_function_type(&::SquaredFunctionSimError::calculateSquaredDifference)
+                , default_calculateSquaredDifference_function_type(&SquaredFunctionSimError_wrapper::default_calculateSquaredDifference)
+                , ( bp::arg("real_value"), bp::arg("simulated_value") ) );
+        
+        }
+        { //::SquaredFunctionSimError::calculateSquaredError
+        
+            typedef double ( ::SquaredFunctionSimError::*calculateSquaredError_function_type )( double,double ) const;
+            typedef double ( SquaredFunctionSimError_wrapper::*default_calculateSquaredError_function_type )( double,double ) const;
+            
+            SquaredFunctionSimError_exposer.def( 
+                "calculateSquaredError"
+                , calculateSquaredError_function_type(&::SquaredFunctionSimError::calculateSquaredError)
+                , default_calculateSquaredError_function_type(&SquaredFunctionSimError_wrapper::default_calculateSquaredError)
+                , ( bp::arg("real_value"), bp::arg("simulated_value") ) );
+        
+        }
+        { //::SquaredFunctionSimError::clone
+        
+            typedef ::SquaredFunctionSimError * ( ::SquaredFunctionSimError::*clone_function_type )(  ) const;
+            typedef ::SquaredFunctionSimError * ( SquaredFunctionSimError_wrapper::*default_clone_function_type )(  ) const;
+            
+            SquaredFunctionSimError_exposer.def( 
+                "clone"
+                , clone_function_type(&::SquaredFunctionSimError::clone)
+                , default_clone_function_type(&SquaredFunctionSimError_wrapper::default_clone)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+    }
+
+}
diff --git a/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp b/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp
index 1fbdb98bee2a160680b829116aac05d49b94ea33..65d1e93013e0b550c5684f88831f9d4d02efcb03 100644
--- a/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp
+++ b/Tests/FunctionalTests/TestFit/TestFit01/TestFit01.cpp
@@ -28,7 +28,7 @@ TestFit01::TestFit01()
     m_minimizers.push_back( Minimizer("Minuit2","Fumili") );
     m_minimizers.push_back( Minimizer("GSLMultiMin","BFGS") );
     m_minimizers.push_back( Minimizer("GSLMultiMin","SteepestDescent") );
-    m_minimizers.push_back( Minimizer("GSLMultiFit","") ); // this is Levenberg-Marquard
+    m_minimizers.push_back( Minimizer("GSLLMA","") ); // this is Levenberg-Marquard
 //    m_minimizers.push_back( Minimizer("GSLSimAn","") );
 //    m_minimizers.push_back( Minimizer("Genetic","") );
 }
diff --git a/Tests/FunctionalTests/TestPyFit/testfit01.py b/Tests/FunctionalTests/TestPyFit/testfit01.py
index 284c9eeb14a6951e7bea322a9022f40f11ddd28a..0d4bfda215cc44d0a6fb1750107b4613337fa91b 100644
--- a/Tests/FunctionalTests/TestPyFit/testfit01.py
+++ b/Tests/FunctionalTests/TestPyFit/testfit01.py
@@ -26,11 +26,11 @@ cylinder_radius = 5*nanometer
 
 # minimizer name and type of minimization algorithm
 Minimizers = [ 
-    ("Minuit2","Migrad"), 
-    ("Minuit2","Fumili"), 
-    ("GSLMultiMin","BFGS"),
-    ("GSLMultiMin","SteepestDescent"),
-    ("GSLMultiFit",""),
+    ("Minuit2", "Migrad"),
+    ("Minuit2", "Fumili"),
+    ("GSLMultiMin", "BFGS"),
+    ("GSLMultiMin", "SteepestDescent"),
+    ("GSLLMA", ""),
 #    ("GSLSimAn","")
 ]
 
diff --git a/Tests/UnitTests/TestFit/MinimizerOptionsTest.h b/Tests/UnitTests/TestFit/MinimizerOptionsTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cdca48e08cabeaeb0bee668330a1858f42a84ed
--- /dev/null
+++ b/Tests/UnitTests/TestFit/MinimizerOptionsTest.h
@@ -0,0 +1,57 @@
+#include "MinimizerOptions.h"
+
+class MinimizerOptionsTest : public ::testing::Test
+{
+ protected:
+    MinimizerOptionsTest(){}
+    virtual ~MinimizerOptionsTest(){}
+
+};
+
+
+TEST_F(MinimizerOptionsTest, InitialState)
+{
+    MinimizerOptions options;
+    EXPECT_EQ(0.01, options.getTolerance());
+    EXPECT_EQ(-1, options.getPrecision());
+    EXPECT_EQ(0, options.getMaxIterations());
+    EXPECT_EQ(0, options.getMaxFunctionCalls());
+
+    ASSERT_THROW(options.setValue("some_value",1.0), LogicErrorException);
+}
+
+
+TEST_F(MinimizerOptionsTest, SetValues)
+{
+    MinimizerOptions options;
+
+    options.setTolerance(0.02);
+    options.setPrecision(2);
+    options.setMaxIterations(10);
+    options.setMaxFunctionCalls(100);
+    EXPECT_EQ(0.02, options.getTolerance());
+    EXPECT_EQ(2, options.getPrecision());
+    EXPECT_EQ(10, options.getMaxIterations());
+    EXPECT_EQ(100, options.getMaxFunctionCalls());
+
+    options.addValue("some_int",1);
+    options.addValue("some_double",9.9);
+    options.addValue("some_string","xxx");
+
+    ASSERT_THROW(options.addValue("some_int",1), LogicErrorException);
+    EXPECT_EQ(options.getIntValue("some_int"), 1);
+    EXPECT_EQ(options.getRealValue("some_double"), 9.9);
+    EXPECT_EQ(options.getNamedValue("some_string"), "xxx");
+
+    ASSERT_THROW(options.getIntValue("some_int2"), LogicErrorException);
+
+    MinimizerOptions opt2 = options;
+    EXPECT_EQ(0.02, opt2.getTolerance());
+    EXPECT_EQ(2, opt2.getPrecision());
+    EXPECT_EQ(10, opt2.getMaxIterations());
+    EXPECT_EQ(100, opt2.getMaxFunctionCalls());
+    EXPECT_EQ(opt2.getIntValue("some_int"), 1);
+    EXPECT_EQ(opt2.getRealValue("some_double"), 9.9);
+    EXPECT_EQ(opt2.getNamedValue("some_string"), "xxx");
+}
+
diff --git a/Tests/UnitTests/TestFit/main.cpp b/Tests/UnitTests/TestFit/main.cpp
index af2495f06ab145937ee5d4a9da056375887ede59..a2b45c939ea9ed15d8006f94f7e00efbb1ad126a 100644
--- a/Tests/UnitTests/TestFit/main.cpp
+++ b/Tests/UnitTests/TestFit/main.cpp
@@ -6,6 +6,8 @@
 #include "AttLimitsTest.h"
 #include "FitParameterTest.h"
 #include "FitParameterLinkedTest.h"
+#include "MinimizerOptionsTest.h"
+
 
 struct ErrorStreamRedirect {
     ErrorStreamRedirect( std::streambuf * new_buffer )
diff --git a/ThirdParty/RootMinimizers/inc/Math/Factory.h b/ThirdParty/RootMinimizers/inc/Math/Factory.h
deleted file mode 100644
index 26fb52c759fe210538715008da9b3ad8d0a55ebc..0000000000000000000000000000000000000000
--- a/ThirdParty/RootMinimizers/inc/Math/Factory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// @(#)root/mathcore:$Id$
-// Author: L. Moneta Fri Dec 22 14:43:33 2006
-
-/**********************************************************************
- *                                                                    *
- * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
- *                                                                    *
- *                                                                    *
- **********************************************************************/
-
-// Header file for class Factory
-
-#ifndef ROOT_Math_Factory
-#define ROOT_Math_Factory
-
-#include <string>
-
-
-namespace ROOT { 
-
-   namespace Math { 
-
-   class Minimizer; 
-   class DistSampler;   
-   
-//___________________________________________________________________________
-/** 
-   Factory  class holding static functions to create the interfaces like ROOT::Math::Minimizer
-   via the Plugin Manager
-*/ 
-class Factory { 
-      public: 
-
-   /**
-      static method to create the corresponding Minimizer given the string
-      Supported Minimizers types are: 
-      Minuit (TMinuit), Minuit2, GSLMultiMin, GSLMultiFit, GSLSimAn, Linear, Fumili, Genetic
-      If no name is given use default values defined in  MinimizerOptions
-    */
-   static ROOT::Math::Minimizer * CreateMinimizer(const std::string & minimizerType = "", const std::string & algoType = "");
-
-   /**
-      static method to create the distribution sampler class given a string specifying the type
-      Supported sampler types are: 
-      Unuran, Foam
-      If no name is given use default values defined in  DistSamplerOptions
-    */
-   static ROOT::Math::DistSampler * CreateDistSampler(const std::string & samplerType ="");
-   
-
-}; 
-
-   } // end namespace Fit
-
-} // end namespace ROOT
-
-
-#endif /* ROOT_Fit_MinimizerFactory */
diff --git a/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h b/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h
index 67fd5f217855ec3c27728a32b1ac08af2b3ca186..f1abd5324015646559e9b280f80a56a1c5891163 100644
--- a/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h
+++ b/ThirdParty/RootMinimizers/inc/Math/GSLRndmEngines.h
@@ -77,6 +77,16 @@ namespace Math {
       */
       GSLRandomEngine( GSLRngWrapper * rng);  
 
+      /**
+         Copy constructor : clone the contained GSL generator
+       */
+      GSLRandomEngine(const GSLRandomEngine & eng);  
+
+      /**
+         Assignment operator : make a deep copy of the contained GSL generator
+       */
+      GSLRandomEngine & operator=(const GSLRandomEngine & eng);  
+
       /**
          initialize the generator 
          If no rng is present the default one based on Mersenne and Twister is created 
diff --git a/ThirdParty/RootMinimizers/inc/Math/Minimizer.h b/ThirdParty/RootMinimizers/inc/Math/Minimizer.h
index 4cb3b647b497b797298e6f404620ec41fd79e7b6..6e8826a6f81ccdbc790bc4082150c4b8fd4e71d7 100644
--- a/ThirdParty/RootMinimizers/inc/Math/Minimizer.h
+++ b/ThirdParty/RootMinimizers/inc/Math/Minimizer.h
@@ -52,7 +52,7 @@ namespace ROOT {
    plug-in manager.
 
    Provides interface for setting the function to be minimized. 
-   The function must implement the multi-dimensional generic interface
+   The function must  implemente the multi-dimensional generic interface
    ROOT::Math::IBaseFunctionMultiDim. 
    If the function provides gradient calculation 
    (implements the ROOT::Math::IGradientFunctionMultiDim interface) this will be 
diff --git a/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h b/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h
index d74b2124971cd39b5b453c7b6c8630fcc17eaab4..f060f7d7a1d11dabbbb7f4509bdded70d8b4a78a 100644
--- a/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h
+++ b/ThirdParty/RootMinimizers/inc/Math/OneDimFunctionAdapter.h
@@ -102,8 +102,11 @@ public:
       clone
    */
    virtual OneDimMultiFunctionAdapter * Clone( ) const { 
-      if (fOwn) 
-         return new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams); 
+      if (fOwn) { 
+         OneDimMultiFunctionAdapter * f =  new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams); 
+         std::copy(fX, fX+fDim, f->fX); 
+         return f; 
+      }
       else 
          return new OneDimMultiFunctionAdapter( fFunc, fX, fCoord, fParams); 
    }
diff --git a/ThirdParty/RootMinimizers/src/Math/Factory.cxx b/ThirdParty/RootMinimizers/src/Math/Factory.cxx
deleted file mode 100644
index b72504b85b9949b0fec4c385ca7aca8f0dc93dfd..0000000000000000000000000000000000000000
--- a/ThirdParty/RootMinimizers/src/Math/Factory.cxx
+++ /dev/null
@@ -1,185 +0,0 @@
-// @(#)root/mathcore:$Id$
-// Author: L. Moneta Fri Dec 22 14:43:33 2006
-
-/**********************************************************************
- *                                                                    *
- * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
- *                                                                    *
- *                                                                    *
- **********************************************************************/
-
-// Implementation file for class MinimizerFactory
-
-#include "Math/Factory.h"
-#include "Math/Error.h"
-
-//#include "RConfigure.h"
-
-#include "Math/Minimizer.h"
-#include "Math/MinimizerOptions.h"
-
-//#include "Math/DistSampler.h"
-//#include "Math/DistSamplerOptions.h"
-
-#ifndef MATH_NO_PLUGIN_MANAGER
-// use ROOT Plug-in manager
-#include "TPluginManager.h"
-#include "TROOT.h"
-#else 
-// all the minimizer implementation classes 
-//#define HAS_MINUIT2
-#ifdef HAS_MINUIT2
-#include "Minuit2/Minuit2Minimizer.h"
-#endif
-#ifdef HAS_MINUIT
-#include "TMinuitMinimizer.h"
-#endif
-#ifdef R__HAS_MATHMORE
-#include "Math/GSLMinimizer.h"
-#include "Math/GSLNLSMinimizer.h"
-#include "Math/GSLSimAnMinimizer.h"
-#endif
-
-#endif
-
-#include <algorithm>
-#include <cassert>
-
-//#define DEBUG
-#ifdef DEBUG
-#include <iostream>
-#endif
-
-#ifndef MATH_NO_PLUGIN_MANAGER 
-// use ROOT Plugin Manager to create Minimizer concrete classes 
-
-ROOT::Math::Minimizer * ROOT::Math::Factory::CreateMinimizer(const std::string & minimizerType,const std::string & algoType)  
-{
-   // create Minimizer using the pluBg-in manager given the type of Minimizer (MINUIT, MINUIT2, FUMILI, etc..) and
-   // algorithm (MIGRAD, SIMPLEX, etc..)
-
-   const char * minim = minimizerType.c_str();
-   const char * algo = algoType.c_str();  
-
-   //case of fumili2
-   std::string s1,s2;
-   if (minimizerType == "Fumili2" ) {
-      s1 = "Minuit2";
-      s2 = "fumili";
-      minim = s1.c_str();
-      algo =  s2.c_str();
-   }
-   if (minimizerType == "TMinuit") { 
-      s1 = "Minuit"; 
-      minim = s1.c_str();
-   }
-
-   if (minimizerType.empty() ) minim = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str(); 
-
-   // create Minimizer using the PM
-   TPluginHandler *h; 
-   //gDebug = 3; 
-   if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::Minimizer",minim ))) {
-      if (h->LoadPlugin() == -1)  {
-#ifdef DEBUG
-      std::cout << "Error Loading ROOT::Math::Minimizer " << minim << std::endl;
-#endif
-         return 0;
-      }
-
-      // create plug-in with required algorithm
-      ROOT::Math::Minimizer * min = reinterpret_cast<ROOT::Math::Minimizer *>( h->ExecPlugin(1,algo ) ); 
-#ifdef DEBUG
-      if (min != 0) 
-         std::cout << "Loaded Minimizer " << minimizerType << "  " << algoType << std::endl;
-      else 
-         std::cout << "Error creating Minimizer " << minimizerType << "  " << algoType << std::endl;
-#endif
-
-      return min; 
-   }
-   return 0;
-                                                                                          
-}
-
-#else 
-
-// use directly classes instances 
-
-ROOT::Math::Minimizer * ROOT::Math::Factory::CreateMinimizer(const std::string & minimizerType, const std::string & algoType)  
-{
-   // static method to create a minimizer . 
-   // not using PM so direct dependency on all libraries (Minuit, Minuit2, MathMore, etc...)
-   // The default is the Minuit2 minimizer or GSL Minimizer
-
-   // should use enumerations instead of string ?  
-   
-   Minimizer * min = 0; 
-   std::string algo = algoType; 
-
-
-#ifdef HAS_MINUIT2
-   if (minimizerType ==  "Minuit2")        
-      min = new ROOT::Minuit2::Minuit2Minimizer(algoType.c_str()); 
-   if (minimizerType ==  "Fumili2")        
-      min = new ROOT::Minuit2::Minuit2Minimizer("fumili"); 
-#endif
-
-#ifdef HAS_MINUIT
-   // use TMinuit
-   if (minimizerType ==  "Minuit" || minimizerType ==  "TMinuit")        
-      min = new ROOT::Fit::TMinuitMinimizer(algoType.c_str());        
-#endif
-
-#ifdef R__HAS_MATHMORE
-   // use GSL minimizer 
-   if (minimizerType ==  "GSL")        
-      min = new ROOT::Math::GSLMinimizer(algoType.c_str());        
-
-   else if (minimizerType ==  "GSL_NLS")        
-      min = new ROOT::Math::GSLNLSMinimizer();        
-
-   else if (minimizerType ==  "GSL_SIMAN")        
-      min = new ROOT::Math::GSLSimAnMinimizer();        
-#endif
-
-
-#ifdef HAS_MINUIT2
-   // DEFAULT IS MINUIT2 based on MIGRAD id minuit2 exists
-   else
-      min = new ROOT::Minuit2::Minuit2Minimizer(); 
-#endif
-
-   return min; 
-}
-
-#endif
-
-// ROOT::Math::DistSampler * ROOT::Math::Factory::CreateDistSampler(const std::string & type) { 
-// #ifdef MATH_NO_PLUGIN_MANAGER 
-//    MATH_ERROR_MSG("Factory::CreateDistSampler","ROOT plug-in manager not available"); 
-//    return 0; 
-// #else 
-//    // create a DistSampler class using the ROOT plug-in manager 
-//    const char * typeName = type.c_str();
-//    if (type.empty() )  typeName = ROOT::Math::DistSamplerOptions::DefaultSampler().c_str();
-// 
-//    TPluginManager *pm = gROOT->GetPluginManager(); 
-//    assert(pm != 0);
-//    TPluginHandler *h = pm->FindHandler("ROOT::Math::DistSampler", typeName );
-//    if (h != 0) {
-//       if (h->LoadPlugin() == -1) {
-//          MATH_ERROR_MSG("Factory::CreateDistSampler","Error loading DistSampler plug-in");
-//          return 0;
-//       }
-// 
-//       ROOT::Math::DistSampler * smp = reinterpret_cast<ROOT::Math::DistSampler *>( h->ExecPlugin(0) );
-//       assert(smp != 0);
-//       return smp; 
-//    }
-//    MATH_ERROR_MSGVAL("Factory::CreateDistSampler","Error finding DistSampler plug-in",typeName);
-//    return 0;
-// #endif
-// }
-
-
diff --git a/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx b/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx
index f22b9db420765d60c2debac03bb1fed63d4de039..eef00b72820af056ef0dd9c6ae3fb732d217d630 100644
--- a/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx
+++ b/ThirdParty/RootMinimizers/src/Math/GSLNLSMinimizer.cxx
@@ -236,6 +236,11 @@ void GSLNLSMinimizer::SetFunction(const ROOT::Math::IMultiGenFunction & func) {
       return;
    } 
    fSize = chi2Func->NPoints(); 
+
+   if (fSize == 0) { 
+      MATH_WARN_MSG("GSLNLSMinimizer::SetFunction","Objective function has zero elements");
+   }
+   
    fDim = chi2Func->NDim(); 
    fNFree = fDim;
 
@@ -266,6 +271,12 @@ bool GSLNLSMinimizer::Minimize() {
       return false; 
    }
 
+   if (fSize == 0) { 
+      MATH_ERROR_MSG("GSLNLSMinimizer::Minimize","Number of data points is zero");
+      return false; 
+   }
+
+
    unsigned int npar = fValues.size();
    if (npar == 0 || npar < fDim) { 
        MATH_ERROR_MSGVAL("GSLNLSMinimizer::Minimize","Wrong number of parameters",npar);
diff --git a/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx b/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx
index 89c92e9978a648cd0a4d23817cd10b6285b8107d..6faac2b08714559487012f4185dccbf87f699feb 100644
--- a/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx
+++ b/ThirdParty/RootMinimizers/src/Math/GSLRndmEngines.cxx
@@ -68,17 +68,28 @@ namespace Math {
       fCurTime(0)
    {}
 
-//    // constructor from external rng
-//    GSLRandomEngine( GSLRngWrapper & rng) : 
-//       fRng(new GSLRngWrapper(rng) ),
-//       fCurTime(0)
-//    {}
+   // copy constructor 
+   GSLRandomEngine::GSLRandomEngine(const GSLRandomEngine & eng) : 
+      fRng(new GSLRngWrapper(*eng.fRng) ),
+      fCurTime(0)
+   {}
 
    GSLRandomEngine::~GSLRandomEngine() {
       // destructor : call terminate if not yet called
       if (fRng) Terminate();
    }
 
+   // assignment operator 
+   GSLRandomEngine & GSLRandomEngine::operator=(const GSLRandomEngine & eng) {
+      if (this == &eng) return *this;
+      if (fRng) 
+         *fRng = *eng.fRng;
+      else  
+         fRng = new GSLRngWrapper(*eng.fRng);
+      fCurTime = eng.fCurTime;
+      return *this;
+   }
+
 
    void GSLRandomEngine::Initialize() { 
       // initialize the generator by allocating the GSL object
diff --git a/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h b/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h
index 55a34ea197a3152ead7433cb50615ca46b765d6b..3cc65b1d61b9428cc5de0e8fe42b99dd628eaa12 100644
--- a/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h
+++ b/ThirdParty/RootMinimizers/src/Math/GSLRngWrapper.h
@@ -59,18 +59,32 @@ public:
     }
 
    /** 
-      Copy constructor - pass ownership (need not to be const)
-      Just copy the pointer and do not manage it 
+      Copy constructor - clone the GSL object and manage it
    */ 
    GSLRngWrapper(GSLRngWrapper & r) :
-      fOwn(r.fOwn),
-      fRng(r.fRng),
+      fOwn(1),
       fRngType(r.fRngType)
    { 
-      // in case an rng exists must release it
-      if (fRng && fOwn) r.fOwn = false;  
+      fRng = gsl_rng_clone(r.fRng);
    } 
 
+   /** 
+      Assignment operator
+   */ 
+   GSLRngWrapper & operator = (const GSLRngWrapper & rhs)  {
+      if (this == &rhs) return *this;  // time saving self-test
+      fRngType = rhs.fRngType;
+      int iret = 0; 
+      if (fRngType == rhs.fRngType) { 
+         iret = gsl_rng_memcpy(fRng, rhs.fRng); 
+         if (!iret) return *this;
+      }
+      // otherwise create a new copy
+      if (fOwn) Free(); 
+      fRng = gsl_rng_clone(rhs.fRng);
+      fOwn = true;
+      return *this;
+   }
 
    /**
       Destructor  (free the rng if not done before)
@@ -104,24 +118,14 @@ public:
       fRngType =  gsl_rng_default; 
     }
 
-
+   void PrintState() const { 
+      gsl_rng_print_state(fRng);
+   }
 
     inline gsl_rng * Rng()  { return fRng; } 
 
     inline const gsl_rng * Rng() const { return fRng; } 
 
-private:
-   // usually copying is non trivial, so we make this unaccessible
-
-
-   /** 
-      Assignment operator
-      Disable since if don't want to change an already created wrapper
-   */ 
-   GSLRngWrapper & operator = (const GSLRngWrapper & rhs)  {
-      if (this == &rhs) return *this;  // time saving self-test
-      return *this;
-   }
 
 
 private: 
diff --git a/dev-tools/python-bindings/MakePyFit.py b/dev-tools/python-bindings/MakePyFit.py
index c197b3feb376bcd70cfd3d0640739e654581d751..a967f7f81e1950580f380c0389fb1e02b5cfc0e4 100644
--- a/dev-tools/python-bindings/MakePyFit.py
+++ b/dev-tools/python-bindings/MakePyFit.py
@@ -59,6 +59,7 @@ include_classes = [
     "SquaredFunctionMeanSquaredError",
     "SquaredFunctionGaussianError",
     "SquaredFunctionSystematicError",
+    "SquaredFunctionSimError",
 ]
 
 
@@ -69,6 +70,13 @@ def ManualClassTunings(mb):
     cl = mb.class_("IMinimizer")
     cl.member_function("setChiSquaredFunction").exclude()
     cl.member_function("setGradientFunction").exclude()
+    for fun in cl.member_functions():
+        if "getOptions" in fun.name:
+            if "::MinimizerOptions const & ( ::IMinimizer::* )(  ) const" in fun.decl_string:
+                fun.exclude()
+            else:
+                fun.call_policies = call_policies.return_internal_reference()
+
     #
     cl = mb.class_("FitSuite")
     #cl.member_functions().exclude()
@@ -76,6 +84,7 @@ def ManualClassTunings(mb):
       #if "addFitParameter" in fun.name:
           #fun.include()
     cl.member_function("getMinimizer").include()
+    cl.member_function( "getMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
     cl.member_function("setMinimizer").include()
     #cl.member_function("addSimulationAndRealData").include()
     #cl.member_function("runFit").include()
@@ -92,14 +101,20 @@ def ManualClassTunings(mb):
             #fun.exclude()
     #
     cl = mb.class_("MinimizerFactory")
-    cl.member_function( "createMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
+    #cl.member_function( "createMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
+    for fun in cl.member_functions():
+        if "createMinimizer" in fun.name:
+            fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
+
+    cl = mb.class_("FitStrategyAdjustMinimizer")
+    cl.member_function( "getMinimizer" ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
+    cl.member_function( "setMinimizer" ).include()
 
     cl = mb.class_("IObserver")
     cl.member_function("update").include()
 
     cl = mb.class_("FitSuiteParameters")
     for fun in cl.member_functions():
-        print fun.decl_string
         if "__gnu_cxx::__normal_iterator" in fun.decl_string:
             fun.exclude()