diff --git a/force_bdss/api.py b/force_bdss/api.py
index fa2fddd8cf2847e007b6e89f4c410f7011edc862..39d081d78e4483948ae128e5cf5d892bdec36d46 100644
--- a/force_bdss/api.py
+++ b/force_bdss/api.py
@@ -28,4 +28,8 @@ from .notification_listeners.base_notification_listener import BaseNotificationL
 from .notification_listeners.base_notification_listener_factory import BaseNotificationListenerFactory  # noqa
 from .notification_listeners.base_notification_listener_model import BaseNotificationListenerModel  # noqa
 
-from .local_traits import (ZMQSocketURL, Identifier)  # noqa
+from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory  # noqa
+from .ui_hooks.base_ui_hooks_factory import BaseUIHooksFactory  # noqa
+from .ui_hooks.base_ui_hooks_manager import BaseUIHooksManager  # noqa
+
+from .local_traits import Identifier  # noqa
diff --git a/force_bdss/base_extension_plugin.py b/force_bdss/base_extension_plugin.py
index 692b9fa72898aafc938854d14042890cc50bed48..c94b622a6ac546a32610da49f70e600b13e99f04 100644
--- a/force_bdss/base_extension_plugin.py
+++ b/force_bdss/base_extension_plugin.py
@@ -7,6 +7,7 @@ from .ids import ExtensionPointID
 from .data_sources.i_data_source_factory import IDataSourceFactory
 from .kpi.i_kpi_calculator_factory import IKPICalculatorFactory
 from .mco.i_mco_factory import IMCOFactory
+from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory
 
 
 class BaseExtensionPlugin(Plugin):
@@ -46,3 +47,8 @@ class BaseExtensionPlugin(Plugin):
         INotificationListenerFactory,
         contributes_to=ExtensionPointID.NOTIFICATION_LISTENER_FACTORIES
     )
+
+    ui_hooks_factories = List(
+        IUIHooksFactory,
+        contributes_to=ExtensionPointID.UI_HOOKS_FACTORIES
+    )
diff --git a/force_bdss/core_plugins/dummy/dummy_plugin.py b/force_bdss/core_plugins/dummy/dummy_plugin.py
index c8020e198a858cfb312d0080c56a1f31b06c1d26..766186f03a3330002830dad4c180f9098a88bfe2 100644
--- a/force_bdss/core_plugins/dummy/dummy_plugin.py
+++ b/force_bdss/core_plugins/dummy/dummy_plugin.py
@@ -3,6 +3,7 @@ from .dummy_notification_listener.dummy_notification_listener_factory import (
     DummyNotificationListenerFactory
 )
 from .csv_extractor.csv_extractor_factory import CSVExtractorFactory
+from .power_evaluator.power_evaluator_factory import PowerEvaluatorFactory
 from .kpi_adder.kpi_adder_factory import KPIAdderFactory
 from .dummy_dakota.dakota_factory import DummyDakotaFactory
 from .dummy_data_source.dummy_data_source_factory import DummyDataSourceFactory
@@ -16,7 +17,8 @@ class DummyPlugin(BaseExtensionPlugin):
 
     def _data_source_factories_default(self):
         return [DummyDataSourceFactory(self),
-                CSVExtractorFactory(self)]
+                CSVExtractorFactory(self),
+                PowerEvaluatorFactory(self)]
 
     def _mco_factories_default(self):
         return [DummyDakotaFactory(self)]
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/__init__.py b/force_bdss/core_plugins/dummy/power_evaluator/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_data_source.py b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8eb722ea6e3f485d3311d869a4709b2cdc5d3cb
--- /dev/null
+++ b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_data_source.py
@@ -0,0 +1,24 @@
+import math
+
+from force_bdss.api import BaseDataSource, DataValue
+from force_bdss.core.slot import Slot
+
+
+class PowerEvaluatorDataSource(BaseDataSource):
+    def run(self, model, parameters):
+        x = parameters[0].value
+        return [
+            DataValue(
+                type=model.cuba_type_out,
+                value=math.pow(x, model.power)
+            )]
+
+    def slots(self, model):
+        return (
+            (
+                Slot(type=model.cuba_type_in),
+            ),
+            (
+                Slot(type=model.cuba_type_out),
+            )
+        )
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_factory.py b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebd3aacf8fcd9b6a5e229756ad64a13ce9d97087
--- /dev/null
+++ b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_factory.py
@@ -0,0 +1,21 @@
+from traits.api import String
+
+from force_bdss.api import factory_id, BaseDataSourceFactory
+
+from .power_evaluator_model import PowerEvaluatorModel
+from .power_evaluator_data_source import PowerEvaluatorDataSource
+
+
+class PowerEvaluatorFactory(BaseDataSourceFactory):
+    id = String(factory_id("enthought", "power_evaluator"))
+
+    name = String("Power Evaluator")
+
+    def create_model(self, model_data=None):
+        if model_data is None:
+            model_data = {}
+
+        return PowerEvaluatorModel(self, **model_data)
+
+    def create_data_source(self):
+        return PowerEvaluatorDataSource(self)
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_model.py b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..14a2efcdb09959339213906051933ce303f18850
--- /dev/null
+++ b/force_bdss/core_plugins/dummy/power_evaluator/power_evaluator_model.py
@@ -0,0 +1,13 @@
+from traits.api import Float, String, on_trait_change
+
+from force_bdss.api import BaseDataSourceModel
+
+
+class PowerEvaluatorModel(BaseDataSourceModel):
+    power = Float(1.0)
+    cuba_type_in = String()
+    cuba_type_out = String()
+
+    @on_trait_change("cuba_type_in,cuba_type_out")
+    def _notify_changes_slots(self):
+        self.changes_slots = True
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/tests/__init__.py b/force_bdss/core_plugins/dummy/power_evaluator/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_data_source.py b/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_data_source.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4d35ac929110d6a3ee513c62a1580f72aeaba04
--- /dev/null
+++ b/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_data_source.py
@@ -0,0 +1,57 @@
+import unittest
+
+from force_bdss.core.data_value import DataValue
+from force_bdss.core.slot import Slot
+from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_data_source import PowerEvaluatorDataSource  # noqa
+from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_model import PowerEvaluatorModel  # noqa
+from force_bdss.data_sources.base_data_source_factory import \
+    BaseDataSourceFactory
+
+try:
+    import mock
+except ImportError:
+    from unittest import mock
+
+
+class TestPowerEvaluatorDataSource(unittest.TestCase):
+    def setUp(self):
+        self.factory = mock.Mock(spec=BaseDataSourceFactory)
+
+    def test_initialization(self):
+        ds = PowerEvaluatorDataSource(self.factory)
+        self.assertEqual(ds.factory, self.factory)
+
+    def test_run(self):
+        ds = PowerEvaluatorDataSource(self.factory)
+        model = PowerEvaluatorModel(self.factory)
+        model.power = 2
+        mock_params = [DataValue(value=5, type="METER")]
+        result = ds.run(model, mock_params)
+        self.assertIsInstance(result, list)
+        self.assertEqual(len(result), 1)
+        self.assertIsInstance(result[0], DataValue)
+        self.assertEqual(result[0].value, 25)
+
+    def test_run_with_exception(self):
+        ds = PowerEvaluatorDataSource(self.factory)
+        model = PowerEvaluatorModel(self.factory)
+        mock_params = []
+        model.power = 3
+        with self.assertRaises(IndexError):
+            ds.run(model, mock_params)
+
+    def test_slots(self):
+        ds = PowerEvaluatorDataSource(self.factory)
+        model = PowerEvaluatorModel(self.factory)
+        slots = ds.slots(model)
+        self.assertEqual(len(slots), 2)
+        self.assertEqual(len(slots[0]), 1)
+        self.assertEqual(len(slots[1]), 1)
+        self.assertIsInstance(slots[0][0], Slot)
+        self.assertIsInstance(slots[1][0], Slot)
+
+        model.cuba_type_in = 'METER'
+        model.cuba_type_out = 'METER'
+        slots = ds.slots(model)
+        self.assertEqual(slots[0][0].type, 'METER')
+        self.assertEqual(slots[1][0].type, 'METER')
diff --git a/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_factory.py b/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..5df8c8f9e796042aaa8a8e0b8c4bd4500dfe4ea3
--- /dev/null
+++ b/force_bdss/core_plugins/dummy/power_evaluator/tests/test_power_evaluator_factory.py
@@ -0,0 +1,22 @@
+import unittest
+
+from force_bdss.core_plugins.dummy.tests.data_source_factory_test_mixin \
+    import DataSourceFactoryTestMixin
+from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_factory import PowerEvaluatorFactory  # noqa
+from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_data_source import PowerEvaluatorDataSource  # noqa
+from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_model import PowerEvaluatorModel  # noqa
+
+
+class TestPowerEvaluatorFactory(DataSourceFactoryTestMixin,
+                                unittest.TestCase):
+    @property
+    def factory_class(self):
+        return PowerEvaluatorFactory
+
+    @property
+    def model_class(self):
+        return PowerEvaluatorModel
+
+    @property
+    def data_source_class(self):
+        return PowerEvaluatorDataSource
diff --git a/force_bdss/factory_registry_plugin.py b/force_bdss/factory_registry_plugin.py
index 67e785173c9986a4dccbd98a8d6aaa124dcaf250..64f41c24d13575789140a86220f04b1675259277 100644
--- a/force_bdss/factory_registry_plugin.py
+++ b/force_bdss/factory_registry_plugin.py
@@ -9,6 +9,7 @@ from .data_sources.i_data_source_factory import (
     IDataSourceFactory)
 from .kpi.i_kpi_calculator_factory import IKPICalculatorFactory
 from .mco.i_mco_factory import IMCOFactory
+from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory
 
 
 FACTORY_REGISTRY_PLUGIN_ID = "force.bdss.plugins.factory_registry"
@@ -50,6 +51,14 @@ class FactoryRegistryPlugin(Plugin):
         id=ExtensionPointID.NOTIFICATION_LISTENER_FACTORIES
     )
 
+    #: UI Hooks are pluggable entities holding methods that are called
+    #: at specific moments in the UI application lifetime. They can be used
+    #: to inject special behaviors at those moments.
+    ui_hooks_factories = ExtensionPoint(
+        List(IUIHooksFactory),
+        id=ExtensionPointID.UI_HOOKS_FACTORIES
+    )
+
     def data_source_factory_by_id(self, id):
         """Finds a given data source factory by means of its id.
         The ID is as obtained by the function factory_id() in the
@@ -140,13 +149,13 @@ class FactoryRegistryPlugin(Plugin):
 
     def notification_listener_factory_by_id(self, id):
         """Finds a given notification listener by means of its id.
-        The ID is as obtained by the function bundle_id() in the
+        The ID is as obtained by the function factory_id() in the
         plugin api.
 
         Parameters
         ----------
         id: str
-            The identifier returned by the bundle_id() function.
+            The identifier returned by the factory_id() function.
 
         Raises
         ------
diff --git a/force_bdss/ids.py b/force_bdss/ids.py
index 336b64a90e0ee2a5b7be42e5d8b471a5d3c85915..c62d52b1de49cc0fb1eba50774f89dcebe84f9fb 100644
--- a/force_bdss/ids.py
+++ b/force_bdss/ids.py
@@ -14,6 +14,7 @@ class ExtensionPointID:
     KPI_CALCULATOR_FACTORIES = 'force.bdss.kpi_calculator.factories'
     NOTIFICATION_LISTENER_FACTORIES = \
         'force.bdss.notification_listener.factories'
+    UI_HOOKS_FACTORIES = 'force.bdss.ui_hooks.factories'
 
 
 def factory_id(producer, identifier):
diff --git a/force_bdss/local_traits.py b/force_bdss/local_traits.py
index f2aa3859b2c8488d50dce64996d0ce098ac0066a..f759aed8596558d9783bae4e0ce1f35671f3059c 100644
--- a/force_bdss/local_traits.py
+++ b/force_bdss/local_traits.py
@@ -1,32 +1,10 @@
-import re
-from traits.api import Regex, BaseStr, String
+from traits.api import Regex, String
 
 #: Used for variable names, but allow also empty string as it's the default
 #: case and it will be present if the workflow is saved before actually
 #: specifying the value.
 Identifier = Regex(regex="(^[^\d\W]\w*\Z|^\Z)")
 
-
-class ZMQSocketURL(BaseStr):
-    def validate(self, object, name, value):
-        super(ZMQSocketURL, self).validate(object, name, value)
-        m = re.match(
-            "tcp://(\\d{1,3})\.(\\d{1,3})\.(\\d{1,3})\.(\\d{1,3}):(\\d+)",
-            value)
-        if m is None:
-            self.error(object, name, value)
-
-        a, b, c, d, port = m.groups()
-
-        if not all(map(lambda x: 0 <= int(x) <= 255, (a, b, c, d))):
-            self.error(object, name, value)
-
-        if not (1 <= int(port) <= 65535):
-            self.error(object, name, value)
-
-        return value
-
-
 #: Identifies a CUBA type with its key. At the moment a String with
 #: no validation, but will come later.
 CUBAType = String()
diff --git a/force_bdss/tests/test_local_traits.py b/force_bdss/tests/test_local_traits.py
index d66a863206a887c90073feec2ce0b749cb4c83a9..d61e6d2c89520653d65431a0030ad89b362f18be 100644
--- a/force_bdss/tests/test_local_traits.py
+++ b/force_bdss/tests/test_local_traits.py
@@ -1,13 +1,12 @@
 import unittest
 from traits.api import HasStrictTraits, TraitError
 
-from force_bdss.local_traits import Identifier, CUBAType, ZMQSocketURL
+from force_bdss.local_traits import Identifier, CUBAType
 
 
 class Traited(HasStrictTraits):
     val = Identifier()
     cuba = CUBAType()
-    socket_url = ZMQSocketURL()
 
 
 class TestLocalTraits(unittest.TestCase):
@@ -26,22 +25,3 @@ class TestLocalTraits(unittest.TestCase):
         c = Traited()
         c.cuba = "PRESSURE"
         self.assertEqual(c.cuba, "PRESSURE")
-
-    def test_zmq_socket_url(self):
-        c = Traited()
-
-        for working in ["tcp://127.0.0.1:12345",
-                        "tcp://255.255.255.255:65535",
-                        "tcp://1.1.1.1:65535"]:
-            c.socket_url = working
-            self.assertEqual(c.socket_url, working)
-
-        for broken in ["tcp://270.0.0.1:12345",
-                       "tcp://0.270.0.1:12345",
-                       "tcp://0.0.270.1:12345",
-                       "tcp://0.0.0.270:12345",
-                       "url://255.255.255.255:65535",
-                       "whatever",
-                       "tcp://1.1.1.1:100000"]:
-            with self.assertRaises(TraitError):
-                c.socket_url = broken
diff --git a/force_bdss/ui_hooks/__init__.py b/force_bdss/ui_hooks/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/force_bdss/ui_hooks/base_ui_hooks_factory.py b/force_bdss/ui_hooks/base_ui_hooks_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..b183489b441d12adcdbf8da751578ab6a4ac194c
--- /dev/null
+++ b/force_bdss/ui_hooks/base_ui_hooks_factory.py
@@ -0,0 +1,44 @@
+import abc
+
+from traits.api import ABCHasStrictTraits, Instance, String, provides
+from envisage.plugin import Plugin
+
+from .i_ui_hooks_factory import IUIHooksFactory
+
+
+@provides(IUIHooksFactory)
+class BaseUIHooksFactory(ABCHasStrictTraits):
+    """Base class for UIHooksFactory.
+    UI Hooks are extensions that perform actions associated to specific
+    moments of the UI lifetime.
+    """
+    #: identifier of the factory
+    id = String()
+
+    #: Name of the factory. User friendly for UI
+    name = String()
+
+    #: A reference to the containing plugin
+    plugin = Instance(Plugin)
+
+    def __init__(self, plugin, *args, **kwargs):
+        """Initializes the instance.
+
+        Parameters
+        ----------
+        plugin: Plugin
+            The plugin that holds this factory.
+        """
+        self.plugin = plugin
+        super(BaseUIHooksFactory, self).__init__(*args, **kwargs)
+
+    @abc.abstractmethod
+    def create_ui_hooks_manager(self):
+        """Creates an instance of the hook manager.
+        The hooks manager contains a set of methods that are applicable in
+        various moments of the UI application lifetime.
+
+        Returns
+        -------
+        BaseUIHooksManager
+        """
diff --git a/force_bdss/ui_hooks/base_ui_hooks_manager.py b/force_bdss/ui_hooks/base_ui_hooks_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1c9228ce7299fb8106b99197ea81048f7082771
--- /dev/null
+++ b/force_bdss/ui_hooks/base_ui_hooks_manager.py
@@ -0,0 +1,51 @@
+from traits.api import HasStrictTraits, Instance
+
+from .i_ui_hooks_factory import IUIHooksFactory
+
+
+class BaseUIHooksManager(HasStrictTraits):
+    #: A reference to the factory
+    factory = Instance(IUIHooksFactory)
+
+    def __init__(self, factory, *args, **kwargs):
+        """Initializes the UI Hooks manager.
+
+        Parameters
+        ----------
+        factory: BaseUIHooksFactory
+            The factory this UI Hooks manager belongs to
+        """
+        self.factory = factory
+        super(BaseUIHooksManager, self).__init__(*args, **kwargs)
+
+    def before_execution(self, task):
+        """Hook that is called before execution of a given evaluation.
+        Gives a chance to perform operations before the temporary file is
+        created with its contents and the calculation invoked.
+
+        Parameters
+        ----------
+        task:
+            The pyface envisage task.
+        """
+
+    def after_execution(self, task):
+        """Hook that is called after execution of a given evaluation.
+        Gives a chance to perform operations after the calculation finished.
+
+        Parameters
+        ----------
+        task:
+            The pyface envisage task.
+        """
+
+    def before_save(self, task):
+        """Hook that is called just before saving a given model to disk
+        in response to a user action. This does not apply to saving of
+        temporary files before execution.
+
+        Parameters
+        ----------
+        task:
+            The pyface envisage task
+        """
diff --git a/force_bdss/ui_hooks/i_ui_hooks_factory.py b/force_bdss/ui_hooks/i_ui_hooks_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc60ae017a6ab24d6d5e20891eea33e59a2e0f41
--- /dev/null
+++ b/force_bdss/ui_hooks/i_ui_hooks_factory.py
@@ -0,0 +1,18 @@
+from traits.api import Interface, String, Instance
+from envisage.plugin import Plugin
+
+
+class IUIHooksFactory(Interface):
+    """Envisage required interface for the BaseUIHooksFactory.
+    You should not need to use this directly.
+
+    Refer to the BaseUIHooksFactory for documentation.
+    """
+    id = String()
+
+    name = String()
+
+    plugin = Instance(Plugin)
+
+    def create_hook_manager(self):
+        """"""
diff --git a/force_bdss/ui_hooks/tests/__init__.py b/force_bdss/ui_hooks/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/force_bdss/ui_hooks/tests/test_base_ui_hooks_factory.py b/force_bdss/ui_hooks/tests/test_base_ui_hooks_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..449fc91ee057c4a2bd522e0bed73a44c89c22358
--- /dev/null
+++ b/force_bdss/ui_hooks/tests/test_base_ui_hooks_factory.py
@@ -0,0 +1,21 @@
+import unittest
+
+try:
+    import mock
+except ImportError:
+    from unittest import mock
+
+from envisage.api import Plugin
+from ..base_ui_hooks_factory import BaseUIHooksFactory
+
+
+class NullUIHooksFactory(BaseUIHooksFactory):
+    def create_ui_hooks_manager(self):
+        return None
+
+
+class TestBaseUIHooksFactory(unittest.TestCase):
+    def test_initialize(self):
+        mock_plugin = mock.Mock(spec=Plugin)
+        factory = NullUIHooksFactory(plugin=mock_plugin)
+        self.assertEqual(factory.plugin, mock_plugin)
diff --git a/force_bdss/ui_hooks/tests/test_base_ui_hooks_manager.py b/force_bdss/ui_hooks/tests/test_base_ui_hooks_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..8724a19a1985682f577eee60af67235aef108e4b
--- /dev/null
+++ b/force_bdss/ui_hooks/tests/test_base_ui_hooks_manager.py
@@ -0,0 +1,16 @@
+import unittest
+
+from ..base_ui_hooks_manager import BaseUIHooksManager
+from ..base_ui_hooks_factory import BaseUIHooksFactory
+try:
+    import mock
+except ImportError:
+    from unittest import mock
+
+
+class TestBaseUIHooksManager(unittest.TestCase):
+    def test_initialization(self):
+        mock_factory = mock.Mock(spec=BaseUIHooksFactory)
+        mgr = BaseUIHooksManager(mock_factory)
+
+        self.assertEqual(mgr.factory, mock_factory)