diff --git a/wlauto/tests/test_exec_control.py b/wlauto/tests/test_exec_control.py
new file mode 100644
index 00000000..490239d2
--- /dev/null
+++ b/wlauto/tests/test_exec_control.py
@@ -0,0 +1,269 @@
+#    Copyright 2013-2015 ARM Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+# pylint: disable=W0231,W0613,E0611,W0603,R0201
+from unittest import TestCase
+
+from nose.tools import assert_equal, assert_raises
+
+from wlauto.utils.exec_control import (init_environment, reset_environment,
+                                              activate_environment, once,
+                                              once_per_class, once_per_instance)
+
+class TestClass(object):
+
+    def __init__(self):
+        self.count = 0
+
+    @once
+    def initilize_once(self):
+        self.count += 1
+
+    @once_per_class
+    def initilize_once_per_class(self):
+        self.count += 1
+
+    @once_per_instance
+    def initilize_once_per_instance(self):
+        self.count += 1
+
+
+class SubClass(TestClass):
+
+    def __init__(self):
+        super(SubClass, self).__init__()
+
+
+class SubSubClass(SubClass):
+
+    def __init__(self):
+        super(SubSubClass, self).__init__()
+
+
+class AnotherClass(object):
+
+    def __init__(self):
+        self.count = 0
+
+    @once
+    def initilize_once(self):
+        self.count += 1
+
+    @once_per_class
+    def initilize_once_per_class(self):
+        self.count += 1
+
+    @once_per_instance
+    def initilize_once_per_instance(self):
+        self.count += 1
+
+
+class EnvironmentManagementTest(TestCase):
+
+    def test_duplicate_environment(self):
+        init_environment('ENVIRONMENT')
+        assert_raises(ValueError, init_environment, 'ENVIRONMENT')
+
+    def test_reset_missing_environment(self):
+        assert_raises(ValueError, reset_environment, 'MISSING')
+
+    def test_reset_current_environment(self):
+        activate_environment('CURRENT_ENVIRONMENT')
+        t1 = TestClass()
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        reset_environment()
+        t1.initilize_once()
+        assert_equal(t1.count, 2)
+
+    def test_switch_environment(self):
+        activate_environment('ENVIRONMENT1')
+        t1 = TestClass()
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        activate_environment('ENVIRONMENT2')
+        t1.initilize_once()
+        assert_equal(t1.count, 2)
+
+        activate_environment('ENVIRONMENT1')
+        t1.initilize_once()
+        assert_equal(t1.count, 2)
+
+    def test_reset_environment_name(self):
+        activate_environment('ENVIRONMENT')
+        t1 = TestClass()
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        reset_environment('ENVIRONMENT')
+        t1.initilize_once()
+        assert_equal(t1.count, 2)
+
+
+class OnlyOnceEnvironmentTest(TestCase):
+
+    def setUp(self):
+        activate_environment('TEST_ENVIRONMENT')
+
+    def tearDown(self):
+        reset_environment('TEST_ENVIRONMENT')
+
+    def test_single_instance(self):
+        t1 = TestClass()
+        ac = AnotherClass()
+
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        ac.initilize_once()
+        assert_equal(ac.count, 1)
+
+
+    def test_mulitple_instances(self):
+        t1 = TestClass()
+        t2 = TestClass()
+
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        t2.initilize_once()
+        assert_equal(t2.count, 0)
+
+
+    def test_sub_classes(self):
+        t1 = TestClass()
+        sc = SubClass()
+        ss = SubSubClass()
+
+        t1.initilize_once()
+        assert_equal(t1.count, 1)
+
+        sc.initilize_once()
+        sc.initilize_once()
+        assert_equal(sc.count, 0)
+
+        ss.initilize_once()
+        ss.initilize_once()
+        assert_equal(ss.count, 0)
+
+
+class OncePerClassEnvironmentTest(TestCase):
+
+    def setUp(self):
+        activate_environment('TEST_ENVIRONMENT')
+
+    def tearDown(self):
+        reset_environment('TEST_ENVIRONMENT')
+
+    def test_single_instance(self):
+        t1 = TestClass()
+        ac = AnotherClass()
+
+        t1.initilize_once_per_class()
+        assert_equal(t1.count, 1)
+
+        t1.initilize_once_per_class()
+        assert_equal(t1.count, 1)
+
+        ac.initilize_once_per_class()
+        assert_equal(ac.count, 1)
+
+
+    def test_mulitple_instances(self):
+        t1 = TestClass()
+        t2 = TestClass()
+
+        t1.initilize_once_per_class()
+        assert_equal(t1.count, 1)
+
+        t2.initilize_once_per_class()
+        assert_equal(t2.count, 0)
+
+
+    def test_sub_classes(self):
+        t1 = TestClass()
+        sc1 = SubClass()
+        sc2 = SubClass()
+        ss1 = SubSubClass()
+        ss2 = SubSubClass()
+
+        t1.initilize_once_per_class()
+        assert_equal(t1.count, 1)
+
+        sc1.initilize_once_per_class()
+        sc2.initilize_once_per_class()
+        assert_equal(sc1.count, 1)
+        assert_equal(sc2.count, 0)
+
+        ss1.initilize_once_per_class()
+        ss2.initilize_once_per_class()
+        assert_equal(ss1.count, 1)
+        assert_equal(ss2.count, 0)
+
+
+class OncePerInstanceEnvironmentTest(TestCase):
+
+    def setUp(self):
+        activate_environment('TEST_ENVIRONMENT')
+
+    def tearDown(self):
+        reset_environment('TEST_ENVIRONMENT')
+
+    def test_single_instance(self):
+        t1 = TestClass()
+        ac = AnotherClass()
+
+        t1.initilize_once_per_instance()
+        assert_equal(t1.count, 1)
+
+        t1.initilize_once_per_instance()
+        assert_equal(t1.count, 1)
+
+        ac.initilize_once_per_instance()
+        assert_equal(ac.count, 1)
+
+
+    def test_mulitple_instances(self):
+        t1 = TestClass()
+        t2 = TestClass()
+
+        t1.initilize_once_per_instance()
+        assert_equal(t1.count, 1)
+
+        t2.initilize_once_per_instance()
+        assert_equal(t2.count, 1)
+
+
+    def test_sub_classes(self):
+        t1 = TestClass()
+        sc = SubClass()
+        ss = SubSubClass()
+
+        t1.initilize_once_per_instance()
+        assert_equal(t1.count, 1)
+
+        sc.initilize_once_per_instance()
+        sc.initilize_once_per_instance()
+        assert_equal(sc.count, 1)
+
+        ss.initilize_once_per_instance()
+        ss.initilize_once_per_instance()
+        assert_equal(ss.count, 1)
diff --git a/wlauto/utils/exec_control.py b/wlauto/utils/exec_control.py
new file mode 100644
index 00000000..01025ee0
--- /dev/null
+++ b/wlauto/utils/exec_control.py
@@ -0,0 +1,117 @@
+from inspect import getmro
+
+# "environment" management:
+__environments = {}
+__active_environment = None
+
+
+def activate_environment(name):
+    """
+    Sets the current tracking environment to ``name``. If an
+    environment with that name does not already exist, it will be
+    created.
+    """
+    #pylint: disable=W0603
+    global __active_environment
+
+    if name not in __environments.keys():
+        init_environment(name)
+    __active_environment = name
+
+
+def init_environment(name):
+    """
+    Create a new environment called ``name``, but do not set it as the
+    current environment.
+
+    :raises: ``ValueError`` if an environment with name ``name``
+             already exists.
+    """
+    if name in __environments.keys():
+        msg = "Environment {} already exists".format(name)
+        raise ValueError(msg)
+    __environments[name] = []
+
+
+def reset_environment(name=None):
+    """
+    Reset method call tracking for environment ``name``. If ``name`` is
+    not specified or is ``None``, reset the current active environment.
+
+    :raises: ``ValueError`` if an environment with name ``name``
+          does not exist.
+    """
+
+    if name is not None:
+        if name not in __environments.keys():
+            msg = "Environment {} does not exist".format(name)
+            raise ValueError(msg)
+        __environments[name] = []
+    else:
+        if __active_environment is None:
+            raise ValueError("No Environment Active")
+        __environments[__active_environment] = []
+
+# The decorators:
+
+
+def once_per_instance(method):
+    """
+    The specified method will be invoked only once for every bound
+    instance within the environment.
+    """
+    def wrapper(*args, **kwargs):
+        if __active_environment is None:
+            raise ValueError("No Environment Active")
+        func_id = repr(args[0])
+        if func_id in __environments[__active_environment]:
+            return
+        else:
+            __environments[__active_environment].append(func_id)
+        return method(*args, **kwargs)
+
+    return wrapper
+
+
+def once_per_class(method):
+    """
+    The specified method will be invoked only once for all instances
+    of a class within the environment.
+    """
+    def wrapper(*args, **kwargs):
+        if __active_environment is None:
+            raise ValueError("No Environment Active")
+
+        func_id = repr(method.func_name) + repr(args[0].__class__)
+
+        if func_id in __environments[__active_environment]:
+            return
+        else:
+            __environments[__active_environment].append(func_id)
+        return method(*args, **kwargs)
+
+    return wrapper
+
+
+def once(method):
+
+    """
+    The specified method will be invoked only once within the
+    environment.
+    """
+    def wrapper(*args, **kwargs):
+        if __active_environment is None:
+            raise ValueError("No Environment Active")
+
+        func_id = repr(method.func_name)
+        # Store the least derived class, which isn't object, to account
+        # for subclasses.
+        func_id += repr(getmro(args[0].__class__)[-2])
+
+        if func_id in __environments[__active_environment]:
+            return
+        else:
+            __environments[__active_environment].append(func_id)
+        return method(*args, **kwargs)
+
+    return wrapper