diff --git a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py b/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py
index b197d0eab50a95e103b76e5bc8dcea83f19c82db..ea6d0a21324456958a99be225f6495dd476becec 100644
--- a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py
+++ b/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py
@@ -9,10 +9,14 @@ import bornagain as ba
 from bornagain import deg, angstrom, nm
 
 
-def get_sample(radius_a=4.0*nm, radius_b=4.0*nm, height=4.0*nm):
+def get_sample(params):
     """
     Returns a sample with uncorrelated cylinders and pyramids.
     """
+    radius_a = params["radius_a"]
+    radius_b = params["radius_b"]
+    height = params["height"]
+
     m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
     m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
     m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
@@ -33,26 +37,39 @@ def get_sample(radius_a=4.0*nm, radius_b=4.0*nm, height=4.0*nm):
     return multi_layer
 
 
-def get_simulation(incident_alpha=0.2):
+def get_simulation(params):
     """
     Returns a GISAXS simulation with beam and detector defined.
     """
+    incident_angle = params["incident_angle"]
+
     simulation = ba.GISASSimulation()
     simulation.setDetectorParameters(50, -1.5*deg, 1.5*deg,
                                      50, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, incident_alpha, 0.0*deg)
+    simulation.setBeamParameters(1.0*angstrom, incident_angle, 0.0*deg)
     simulation.setBeamIntensity(1e+08)
+    simulation.setSample(get_sample(params))
     return simulation
 
 
+def simulation1(params):
+    params["incident_angle"] = 0.1*deg
+    return get_simulation(params)
+
+
+def simulation2(params):
+    params["incident_angle"] = 0.4*deg
+    return get_simulation(params)
+
+
 def create_real_data(incident_alpha):
     """
     Generating "real" data by adding noise to the simulated data.
     """
-    sample = get_sample(
-        radius_a=5.0*nm, radius_b=6.0*nm, height=8.0*nm)
-    simulation = get_simulation(incident_alpha)
-    simulation.setSample(sample)
+    params = {'radius_a': 5.0*nm, 'radius_b': 6.0*nm,
+              'height': 8.0*nm, "incident_angle": incident_alpha}
+
+    simulation = get_simulation(params)
     simulation.runSimulation()
 
     # retrieving simulated data in the form of numpy array
@@ -65,26 +82,21 @@ def create_real_data(incident_alpha):
     return noisy
 
 
-class DrawObserver(ba.IFitObserver):
+class PlotObserver():
     """
     Draws fit progress every nth iteration. Real data, simulated data
     and chi2 map will be shown for both datasets.
     """
     def __init__(self, draw_every_nth=10):
-        import matplotlib
-        from matplotlib import pyplot as plt
-        global matplotlib, plt
-
-        ba.IFitObserver.__init__(self, draw_every_nth)
         self.fig = plt.figure(figsize=(12.8, 10.24))
         self.fig.canvas.draw()
         plt.ion()
 
-    def plot_datasets(self, fit_suite, canvas):
-        for i_dataset in range(0, fit_suite.numberOfFitObjects()):
-            real_data = fit_suite.experimentalData(i_dataset)
-            simul_data = fit_suite.simulationResult(i_dataset)
-            chi2_map = fit_suite.relativeDifference(i_dataset)
+    def plot_datasets(self, fit_objective, canvas):
+        for i_dataset in range(0, fit_objective.fitObjectCount()):
+            real_data = fit_objective.experimentalData(i_dataset)
+            simul_data = fit_objective.simulationResult(i_dataset)
+            chi2_map = fit_objective.relativeDifference(i_dataset)
 
             zmax = real_data.histogram2d().getMaximum()
 
@@ -98,16 +110,22 @@ class DrawObserver(ba.IFitObserver):
             ba.plot_colormap(chi2_map, title="Chi2 map - #"+str(i_dataset+1),
                                zmin=0.001, zmax=10.0, zlabel="")
 
-    def plot_fit_parameters(self, fit_suite, canvas):
+    def plot_fit_parameters(self, fit_objective, canvas):
         # fit parameters
         plt.subplot(canvas[6:])
         plt.axis('off')
-        plt.text(0.01, 0.95, "Iterations  " + '{:d}   '.
-                 format(fit_suite.numberOfIterations()))
-        plt.text(0.01, 0.70, "Chi2       " + '{:8.4f}'.format(fit_suite.getChi2()))
-        for index, fitPar in enumerate(fit_suite.fitParameters()):
-            plt.text(0.01, 0.30 - index*0.3,
-                     '{:40.40s}: {:6.3f}'.format(fitPar.name(), fitPar.value()))
+
+        iteration_info = fit_objective.iterationInfo()
+
+        plt.text(0.01, 0.95, "Iterations  " + '{:d}'.
+                 format(iteration_info.iterationCount()))
+        plt.text(0.01, 0.70, "Chi2       " + '{:8.4f}'.format(iteration_info.chi2()))
+        index = 0
+        params = iteration_info.parameterMap()
+        for key in params:
+            plt.text(0.01, 0.30 - index * 0.3, '{:30.30s}: {:6.3f}'.format(key, params[key]))
+            index = index + 1
+
 
     def update(self, fit_suite):
         self.fig.clf()
@@ -124,8 +142,6 @@ class DrawObserver(ba.IFitObserver):
         plt.draw()
         plt.pause(0.01)
 
-        if fit_suite.isLastIteration():
-            plt.ioff()
 
 
 def run_fitting():
@@ -133,35 +149,27 @@ def run_fitting():
     main function to run fitting
     """
 
-    incident_alpha_angles = [0.1*deg, 0.4*deg]
-    fit_suite = ba.FitSuite()
-    sample = get_sample()
-
-    for alpha in incident_alpha_angles:
-        real_data = create_real_data(incident_alpha=alpha)
-        simulation = get_simulation(incident_alpha=alpha)
-        simulation.setSample(sample)
-        fit_suite.addSimulationAndRealData(simulation, real_data)
-
-    fit_suite.initPrint(10)
-    draw_observer = DrawObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
+    data1 = create_real_data(0.1 * deg)
+    data2 = create_real_data(0.4 * deg)
 
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*/HemiEllipsoid/RadiusX", 4.*nm).setLimited(2., 10.)
-    fit_suite.addFitParameter("*/HemiEllipsoid/RadiusY", 6.*nm).setFixed()
-    fit_suite.addFitParameter("*/HemiEllipsoid/Height", 4.*nm).setLimited(2., 10.)
+    fit_objective = ba.FitObjective()
+    fit_objective.addSimulationAndData(simulation1, data1, 1.0)
+    fit_objective.addSimulationAndData(simulation2, data2, 1.0)
+    fit_objective.initPrint(10)
 
-    print(fit_suite.treeToString())
-    print(fit_suite.parametersToString())
+    # creating custom observer which will draw fit progress
+    plotter = PlotObserver()
+    fit_objective.initPlot(10, plotter.update)
 
-    # running fit
-    fit_suite.runFit()
+    params = ba.Parameters()
+    params.add("radius_a", 4.*nm, min=2.0, max=10.0)
+    params.add("radius_b", 6.*nm, vary=False)
+    params.add("height", 4.*nm, min=2.0, max=10.0)
 
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
+    print("begin")
+    minimizer = ba.Minimizer()
+    result = minimizer.minimize(fit_objective.evaluate, params)
+    fit_objective.finalize(result)
 
 
 if __name__ == '__main__':