diff --git a/force_bdss/base_core_driver.py b/force_bdss/base_core_driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f0fa6db586df4ecf71a8a388cc746f910d87a02
--- /dev/null
+++ b/force_bdss/base_core_driver.py
@@ -0,0 +1,63 @@
+from envisage.extension_point import ExtensionPoint
+from envisage.plugin import Plugin
+from traits.api import List
+
+from force_bdss.data_sources.i_data_source_bundle import (
+    IDataSourceBundle)
+from force_bdss.kpi.i_kpi_calculator_bundle import IKPICalculatorBundle
+from force_bdss.mco.i_multi_criteria_optimizer_bundle import (
+    IMultiCriteriaOptimizerBundle)
+
+
+class BaseCoreDriver(Plugin):
+    """Main plugin that handles the execution of the MCO
+    or the evaluation.
+    """
+
+    # Note: we are forced to declare these extensions points here instead
+    # of the application object, and this is why we have to use this plugin.
+    # It is a workaround to an envisage bug that does not find the extension
+    # points if declared on the application.
+
+    #: A List of the available Multi Criteria Optimizers.
+    #: This will be populated by MCO plugins.
+    mco_bundles = ExtensionPoint(
+        List(IMultiCriteriaOptimizerBundle),
+        id='force.bdss.mco.bundles')
+
+    #: A list of the available Data Sources.
+    #: It will be populated by plugins.
+    data_source_bundles = ExtensionPoint(
+        List(IDataSourceBundle),
+        id='force.bdss.data_sources.bundles')
+
+    #: A list of the available Key Performance Indicator calculators.
+    #: It will be populated by plugins.
+    kpi_calculator_bundles = ExtensionPoint(
+        List(IKPICalculatorBundle),
+        id='force.bdss.kpi_calculators.bundles')
+
+    def _data_source_bundle_by_name(self, name):
+        for ds in self.data_source_bundles:
+            if ds.name == name:
+                return ds
+
+        raise Exception("Requested data source {} but don't know "
+                        "to find it.".format(name))
+
+    def _kpi_calculator_bundle_by_name(self, name):
+        for kpic in self.kpi_calculator_bundles:
+            if kpic.name == name:
+                return kpic
+
+        raise Exception(
+            "Requested kpi calculator {} but don't know "
+            "to find it.".format(name))
+
+    def _mco_bundle_by_name(self, name):
+        for mco in self.mco_bundles:
+            if mco.name == name:
+                return mco
+
+        raise Exception("Requested MCO {} but it's not available"
+                        "to compute it.".format(name))
diff --git a/force_bdss/bdss_application.py b/force_bdss/bdss_application.py
index e6abb68250d434c03d1f88ff68fae5b9b6c91141..64537cfa1a72ed6ab9a6db1aca9a99ca48a54342 100644
--- a/force_bdss/bdss_application.py
+++ b/force_bdss/bdss_application.py
@@ -1,6 +1,13 @@
 import json
 
+from stevedore import extension
+from stevedore.exception import NoMatches
 from envisage.api import Application
+from envisage.core_plugin import CorePlugin
+
+from force_bdss.core_evaluation_driver import CoreEvaluationDriver
+from force_bdss.core_mco_driver import CoreMCODriver
+
 from traits.api import Unicode, Bool, Instance
 
 from force_bdss.workspecs.workflow import Workflow
@@ -22,6 +29,33 @@ class BDSSApplication(Application):
     #: coordination of the MCO itself. See design notes for more details.
     evaluate = Bool()
 
+    def __init__(self, evaluate, workflow_filepath):
+        self.evaluate = evaluate
+        self.workflow_filepath = workflow_filepath
+
+        plugins = [CorePlugin()]
+
+        if self.evaluate:
+            plugins.append(CoreEvaluationDriver())
+        else:
+            plugins.append(CoreMCODriver())
+
+        mgr = extension.ExtensionManager(
+            namespace='force.bdss.extensions',
+            invoke_on_load=True
+        )
+
+        def import_extensions(ext):
+            print("Found extension {}".format(ext.name))
+            plugins.append(ext.obj)
+
+        try:
+            mgr.map(import_extensions)
+        except NoMatches:
+            print("No extensions found")
+
+        super().__init__(plugins=plugins)
+
     def _workflow_default(self):
         with open(self.workflow_filepath) as f:
             return Workflow.from_json(json.load(f))
diff --git a/force_bdss/cli/force_bdss.py b/force_bdss/cli/force_bdss.py
index c4a26d123dd76722fb572cded61a63171675de91..5a389a96458265ac607cb1f752f40aeb6e3d7b3b 100644
--- a/force_bdss/cli/force_bdss.py
+++ b/force_bdss/cli/force_bdss.py
@@ -1,10 +1,6 @@
 import click
-from stevedore import extension
-from stevedore.exception import NoMatches
-from envisage.core_plugin import CorePlugin
 
 from force_bdss.bdss_application import BDSSApplication
-from force_bdss.core_mco_driver import CoreMCODriver
 
 
 @click.command()
@@ -12,27 +8,7 @@ from force_bdss.core_mco_driver import CoreMCODriver
 @click.argument('workflow_filepath', type=click.Path(exists=True))
 def run(evaluate, workflow_filepath):
 
-    plugins = [
-        CorePlugin(),
-        CoreMCODriver(),
-    ]
-
-    mgr = extension.ExtensionManager(
-        namespace='force.bdss.extensions',
-        invoke_on_load=True
-    )
-
-    def import_extensions(ext):
-        print("Found extension {}".format(ext.name))
-        plugins.append(ext.obj)
-
-    try:
-        mgr.map(import_extensions)
-    except NoMatches:
-        print("No extensions found")
-
     application = BDSSApplication(
-        plugins=plugins,
         evaluate=evaluate,
         workflow_filepath=workflow_filepath
     )
diff --git a/force_bdss/core_evaluation_driver.py b/force_bdss/core_evaluation_driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..831c539cf39ba31b68a97ea21c6f3eb43ad8cc32
--- /dev/null
+++ b/force_bdss/core_evaluation_driver.py
@@ -0,0 +1,43 @@
+from traits.has_traits import on_trait_change
+
+from force_bdss.base_core_driver import BaseCoreDriver
+
+
+class CoreEvaluationDriver(BaseCoreDriver):
+    """Main plugin that handles the execution of the MCO
+    or the evaluation.
+    """
+
+    @on_trait_change("application:started")
+    def application_started(self):
+        workflow = self.application.workflow
+
+        mco_data = workflow.multi_criteria_optimizer
+        mco_bundle = self._mco_bundle_by_name(mco_data.name)
+        mco_model = mco_bundle.create_model(mco_data.model_data)
+        mco_communicator = mco_bundle.create_communicator(
+            self.application,
+            mco_model)
+
+        parameters = mco_communicator.receive_from_mco()
+
+        ds_results = []
+        for requested_ds in workflow.data_sources:
+            ds_bundle = self._data_source_bundle_by_name(
+                requested_ds.name)
+            ds_model = ds_bundle.create_model(requested_ds.model_data)
+            data_source = ds_bundle.create_data_source(
+                self.application, ds_model)
+            ds_results.append(data_source.run(parameters))
+
+        kpi_results = []
+        for requested_kpic in workflow.kpi_calculators:
+            kpic_bundle = self._kpi_calculator_bundle_by_name(
+                requested_kpic.name)
+            ds_model = kpic_bundle.create_model(
+                requested_kpic.model_data)
+            kpi_calculator = kpic_bundle.create_data_source(
+                self.application, ds_model)
+            kpi_results.append(kpi_calculator.run(ds_results))
+
+        mco_communicator.send_to_mco(kpi_results)
diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index 2b57471cb91e9aed1b9d20b7b753c3d7bbd9bea3..cc296dae4a20930f41d0d5a54755965db848661e 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -1,43 +1,13 @@
-from envisage.extension_point import ExtensionPoint
-from envisage.plugin import Plugin
-from traits.has_traits import on_trait_change
-from traits.trait_types import List
+from traits.api import on_trait_change
 
-from force_bdss.data_sources.i_data_source_bundle import (
-    IDataSourceBundle)
-from force_bdss.kpi.i_kpi_calculator_bundle import IKPICalculatorBundle
-from force_bdss.mco.i_multi_criteria_optimizer_bundle import (
-    IMultiCriteriaOptimizerBundle)
+from force_bdss.base_core_driver import BaseCoreDriver
 
 
-class CoreMCODriver(Plugin):
+class CoreMCODriver(BaseCoreDriver):
     """Main plugin that handles the execution of the MCO
     or the evaluation.
     """
 
-    # Note: we are forced to declare these extensions points here instead
-    # of the application object, and this is why we have to use this plugin.
-    # It is a workaround to an envisage bug that does not find the extension
-    # points if declared on the application.
-
-    #: A List of the available Multi Criteria Optimizers.
-    #: This will be populated by MCO plugins.
-    mco_bundles = ExtensionPoint(
-        List(IMultiCriteriaOptimizerBundle),
-        id='force.bdss.mco.bundles')
-
-    #: A list of the available Data Sources.
-    #: It will be populated by plugins.
-    data_source_bundles = ExtensionPoint(
-        List(IDataSourceBundle),
-        id='force.bdss.data_sources.bundles')
-
-    #: A list of the available Key Performance Indicator calculators.
-    #: It will be populated by plugins.
-    kpi_calculator_bundles = ExtensionPoint(
-        List(IKPICalculatorBundle),
-        id='force.bdss.kpi_calculators.bundles')
-
     @on_trait_change("application:started")
     def application_started(self):
         workflow = self.application.workflow
@@ -46,58 +16,5 @@ class CoreMCODriver(Plugin):
         mco_bundle = self._mco_bundle_by_name(mco_data.name)
         mco_model = mco_bundle.create_model(mco_data.model_data)
         mco = mco_bundle.create_optimizer(self.application, mco_model)
-        mco_communicator = mco_bundle.create_communicator(
-            self.application,
-            mco_model)
-
-        if not self.application.evaluate:
-            mco.run()
-            return
-
-        parameters = mco_communicator.receive_from_mco()
-
-        ds_results = []
-        for requested_ds in workflow.data_sources:
-            ds_bundle = self._data_source_bundle_by_name(
-                requested_ds.name)
-            ds_model = ds_bundle.create_model(requested_ds.model_data)
-            data_source = ds_bundle.create_data_source(
-                self.application, ds_model)
-            ds_results.append(data_source.run(parameters))
-
-        kpi_results = []
-        for requested_kpic in workflow.kpi_calculators:
-            kpic_bundle = self._kpi_calculator_bundle_by_name(
-                requested_kpic.name)
-            ds_model = kpic_bundle.create_model(
-                requested_kpic.model_data)
-            kpi_calculator = kpic_bundle.create_data_source(
-                self.application, ds_model)
-            kpi_results.append(kpi_calculator.run(ds_results))
-
-        mco_communicator.send_to_mco(kpi_results)
-
-    def _data_source_bundle_by_name(self, name):
-        for ds in self.data_source_bundles:
-            if ds.name == name:
-                return ds
-
-        raise Exception("Requested data source {} but don't know "
-                        "to find it.".format(name))
-
-    def _kpi_calculator_bundle_by_name(self, name):
-        for kpic in self.kpi_calculator_bundles:
-            if kpic.name == name:
-                return kpic
-
-        raise Exception(
-            "Requested kpi calculator {} but don't know "
-            "to find it.".format(name))
-
-    def _mco_bundle_by_name(self, name):
-        for mco in self.mco_bundles:
-            if mco.name == name:
-                return mco
 
-        raise Exception("Requested MCO {} but it's not available"
-                        "to compute it.".format(name))
+        mco.run()