diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index d2e14050894908c35c28561664f33c895b8d00d5..02625f2a01382f0810d2163910937b3f1ff0dd92 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -36,9 +36,11 @@ class CoreMCODriver(Plugin):
         workflow = self.application.workflow
         if self.application.evaluate:
             for requested_ds in workflow.data_sources:
-                data_source = self._find_data_source_by_computes(requested_ds)
-                if data_source:
-                    data_source.run(self.application)
+                ds_bundle = self._find_data_source_bundle_by_name(requested_ds)
+                if ds_bundle:
+                    ds_model = ds_bundle.create_model(requested_ds.model_data)
+                    data_source = ds_bundle.create_data_source(self, ds_model)
+                    data_source.run()
                 else:
                     raise Exception("Requested data source {} but don't know "
                                     "to find it.".format(requested_ds))
@@ -53,9 +55,9 @@ class CoreMCODriver(Plugin):
                 raise Exception("Requested MCO {} but it's not available"
                                 "to compute it.".format(mco_data.name))
 
-    def _find_data_source_by_computes(self, computes):
+    def _find_data_source_by_name(self, name):
         for ds in self.data_sources:
-            if ds.computes == computes:
+            if ds.name == name:
                 return ds
 
         return None
diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3b12d62f0f02a0d72e0e74b7cdb5848f8f80830
--- /dev/null
+++ b/force_bdss/data_sources/base_data_source.py
@@ -0,0 +1,15 @@
+import abc
+
+
+class BaseDataSource(metaclass=abc.ABCMeta):
+    def __init__(self, bundle, application, model):
+        self.bundle = bundle
+        self.application = application
+        self.model = model
+
+    @property
+    def name(self):
+        return self.bundle.name
+
+    def run(self):
+        pass
diff --git a/force_bdss/data_sources/basic.py b/force_bdss/data_sources/basic.py
deleted file mode 100644
index 5fe2f3cee8737ca51c38c2e2653b7219464237a9..0000000000000000000000000000000000000000
--- a/force_bdss/data_sources/basic.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from traits.api import provides, HasStrictTraits, String
-
-from force_bdss.data_sources.i_data_source import (
-    IDataSource)
-
-
-@provides(IDataSource)
-class Basic(HasStrictTraits):
-    computes = String("basic")
-
-    def run(self, workflow):
-        print("Computing basic key performance indicator, {}".format(workflow))
diff --git a/force_bdss/data_sources/basic_bundle.py b/force_bdss/data_sources/basic_bundle.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e4f87ccd7a2f33a962b3ab0c1ad14a611748019
--- /dev/null
+++ b/force_bdss/data_sources/basic_bundle.py
@@ -0,0 +1,17 @@
+from traits.api import provides, HasStrictTraits
+
+from force_bdss.data_sources.basic_data_source import BasicDataSource
+from force_bdss.data_sources.i_data_source_bundle import IDataSourceBundle
+from force_bdss.mco.basic_model import BasicModel
+
+
+@provides(IDataSourceBundle)
+class BasicBundle(HasStrictTraits):
+    def create_model(self, model_data):
+        return BasicModel.from_json(model_data)
+
+    def create_ui(self):
+        pass
+
+    def create_data_source(self, application, model):
+        return BasicDataSource(self, application, model)
diff --git a/force_bdss/data_sources/basic_data_source.py b/force_bdss/data_sources/basic_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..6705515570052b6516ec7cbca76cd234b13cbb99
--- /dev/null
+++ b/force_bdss/data_sources/basic_data_source.py
@@ -0,0 +1,6 @@
+from force_bdss.data_sources.base_data_source import BaseDataSource
+
+
+class BasicDataSource(BaseDataSource):
+    def run(self):
+        print("Computing basic key performance indicator")
diff --git a/force_bdss/data_sources/basic_model.py b/force_bdss/data_sources/basic_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..3139ad7e106b74e776637f9cb92b560da04f7587
--- /dev/null
+++ b/force_bdss/data_sources/basic_model.py
@@ -0,0 +1,7 @@
+from traits.has_traits import HasStrictTraits
+
+
+class BasicModel(HasStrictTraits):
+    @classmethod
+    def from_json(cls, model_data):
+        return cls()
diff --git a/force_bdss/data_sources/data_sources_plugin.py b/force_bdss/data_sources/data_sources_plugin.py
index 2bd94d88418648f6dbb36eef508bd6b48da07e7a..85c2b1affc79a56ec1546aa14ebe592c6159417b 100644
--- a/force_bdss/data_sources/data_sources_plugin.py
+++ b/force_bdss/data_sources/data_sources_plugin.py
@@ -1,22 +1,21 @@
 from envisage.plugin import Plugin
 from traits.api import List
 
-from force_bdss.data_sources.i_data_source import (
-    IDataSource)
-
-from force_bdss.data_sources.basic import Basic
-from force_bdss.data_sources.price import Price
-from force_bdss.data_sources.viscosity import Viscosity
+from force_bdss.data_sources.basic_bundle import BasicBundle
+from force_bdss.data_sources.price_bundle import PriceBundle
+from force_bdss.data_sources.viscosity_bundle import ViscosityBundle
+from .i_data_source_bundle import IDataSourceBundle
 
 
 class DataSourcesPlugin(Plugin):
-
     id = "force_bdss.data_sources_plugin"
 
     data_sources = List(
-        IDataSource,
-        contributes_to='force_bdss.data_sources'
+        IDataSourceBundle,
+        contributes_to='force.bdss.data_sources.bundles'
     )
 
     def _data_sources_default(self):
-        return [Basic(), Viscosity(), Price()]
+        return [BasicBundle(),
+                ViscosityBundle(),
+                PriceBundle()]
diff --git a/force_bdss/data_sources/i_data_source.py b/force_bdss/data_sources/i_data_source.py
deleted file mode 100644
index e86f0c76a5587585322312b0ec6df4246e224f6a..0000000000000000000000000000000000000000
--- a/force_bdss/data_sources/i_data_source.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from traits.api import Interface, String
-
-
-class IDataSource(Interface):
-    computes = String()
-
-    def run(self):
-        pass
diff --git a/force_bdss/data_sources/i_data_source_bundle.py b/force_bdss/data_sources/i_data_source_bundle.py
new file mode 100644
index 0000000000000000000000000000000000000000..f277caedbd43319478a3605f9b2e815fd0725324
--- /dev/null
+++ b/force_bdss/data_sources/i_data_source_bundle.py
@@ -0,0 +1,14 @@
+from traits.api import Interface, String
+
+
+class IDataSourceBundle(Interface):
+    name = String()
+
+    def create_ui(self):
+        pass
+
+    def create_data_source(self, application, model):
+        pass
+
+    def create_model(self, model_data):
+        pass
diff --git a/force_bdss/data_sources/price.py b/force_bdss/data_sources/price.py
deleted file mode 100644
index 30fbaf78418fa5dfecf721f0714c572a1fcd1faa..0000000000000000000000000000000000000000
--- a/force_bdss/data_sources/price.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from traits.api import provides, HasStrictTraits, String
-
-from force_bdss.data_sources.i_data_source import (
-    IDataSource)
-
-
-@provides(IDataSource)
-class Price(HasStrictTraits):
-    computes = String("price")
-
-    def run(self, workflow):
-        print("Computing price")
diff --git a/force_bdss/data_sources/price_bundle.py b/force_bdss/data_sources/price_bundle.py
new file mode 100644
index 0000000000000000000000000000000000000000..678517e45a7305f095d2725f173a31da1a8953ca
--- /dev/null
+++ b/force_bdss/data_sources/price_bundle.py
@@ -0,0 +1,17 @@
+from traits.api import provides, HasStrictTraits
+
+from force_bdss.data_sources.i_data_source_bundle import IDataSourceBundle
+from force_bdss.data_sources.price_data_source import PriceDataSource
+from force_bdss.data_sources.price_model import PriceModel
+
+
+@provides(IDataSourceBundle)
+class PriceBundle(HasStrictTraits):
+    def create_model(self, model_data):
+        return PriceModel.from_json(model_data)
+
+    def create_ui(self):
+        pass
+
+    def create_data_source(self, application, model):
+        return PriceDataSource(self, application, model)
diff --git a/force_bdss/data_sources/price_data_source.py b/force_bdss/data_sources/price_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..62ec8d1738e1020b1cba6de43020d64dc30ee86f
--- /dev/null
+++ b/force_bdss/data_sources/price_data_source.py
@@ -0,0 +1,6 @@
+from force_bdss.data_sources.base_data_source import BaseDataSource
+
+
+class PriceDataSource(BaseDataSource):
+    def run(self):
+        print("Computing price")
diff --git a/force_bdss/data_sources/price_model.py b/force_bdss/data_sources/price_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..f98449a2e2791f35b1f035e9f1772e15fe1f0930
--- /dev/null
+++ b/force_bdss/data_sources/price_model.py
@@ -0,0 +1,7 @@
+from traits.has_traits import HasStrictTraits
+
+
+class PriceModel(HasStrictTraits):
+    @classmethod
+    def from_json(cls, model_data):
+        return cls()
diff --git a/force_bdss/data_sources/viscosity.py b/force_bdss/data_sources/viscosity.py
deleted file mode 100644
index 1c207f438268f1db67d29fe16602be7998040611..0000000000000000000000000000000000000000
--- a/force_bdss/data_sources/viscosity.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from traits.api import provides, HasStrictTraits, String
-
-from force_bdss.data_sources.i_data_source import (
-    IDataSource)
-
-
-@provides(IDataSource)
-class Viscosity(HasStrictTraits):
-    computes = String("viscosity")
-
-    def run(self, workflow):
-        print("Computing viscosity")
diff --git a/force_bdss/data_sources/viscosity_bundle.py b/force_bdss/data_sources/viscosity_bundle.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e495a5e2f8da6ec0ae0ad53524bced09c87f9bb
--- /dev/null
+++ b/force_bdss/data_sources/viscosity_bundle.py
@@ -0,0 +1,17 @@
+from traits.api import provides, HasStrictTraits
+
+from force_bdss.data_sources.viscosity_model import ViscosityModel
+from .i_data_source_bundle import IDataSourceBundle
+from .viscosity_data_source import ViscosityDataSource
+
+
+@provides(IDataSourceBundle)
+class ViscosityBundle(HasStrictTraits):
+    def create_model(self, model_data):
+        return ViscosityModel.from_json(model_data)
+
+    def create_ui(self):
+        pass
+
+    def create_data_source(self, application, model):
+        return ViscosityDataSource(self, application, model)
diff --git a/force_bdss/data_sources/viscosity_data_source.py b/force_bdss/data_sources/viscosity_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ebd04733aab4a01a365913d290a61d2683aec95
--- /dev/null
+++ b/force_bdss/data_sources/viscosity_data_source.py
@@ -0,0 +1,6 @@
+from force_bdss.data_sources.base_data_source import BaseDataSource
+
+
+class ViscosityDataSource(BaseDataSource):
+    def run(self):
+        print("Computing viscosity")
diff --git a/force_bdss/data_sources/viscosity_model.py b/force_bdss/data_sources/viscosity_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..8168c45e58666ecf7ae35687ffcf69aa69be014f
--- /dev/null
+++ b/force_bdss/data_sources/viscosity_model.py
@@ -0,0 +1,7 @@
+from traits.api import HasStrictTraits
+
+
+class ViscosityModel(HasStrictTraits):
+    @classmethod
+    def from_json(cls, model_data):
+        return cls()