diff --git a/.gitattributes b/.gitattributes
index a3551495ed88e390322059de0db8a6f4db690a7f..5cacfbd2c454252bc13797a681b37512db351662 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2668,6 +2668,7 @@ LCS/PyCommon/postgres.py -text
 LCS/PyCommon/test/python-coverage.sh eol=lf
 LCS/PyCommon/test/t_dbcredentials.run eol=lf
 LCS/PyCommon/test/t_dbcredentials.sh eol=lf
+LCS/PyCommon/test/t_methodtrigger.sh eol=lf
 LCS/PyCommon/util.py -text
 LCS/Tools/src/checkcomp.py -text
 LCS/Tools/src/countalllines -text
diff --git a/LCS/PyCommon/CMakeLists.txt b/LCS/PyCommon/CMakeLists.txt
index 42cf8512e8926b7335609fc647cfa424befb37e8..6fc29b3e2de25fb95aa74915ee03af9fbab874c4 100644
--- a/LCS/PyCommon/CMakeLists.txt
+++ b/LCS/PyCommon/CMakeLists.txt
@@ -10,6 +10,7 @@ add_subdirectory(test)
 set(_py_files
   dbcredentials.py
   factory.py
+  methodtrigger.py
   util.py
   postgres.py
   datetimeutils.py)
diff --git a/LCS/PyCommon/methodtrigger.py b/LCS/PyCommon/methodtrigger.py
new file mode 100644
index 0000000000000000000000000000000000000000..800d8d11ea19f00c3c7f1bb0cad9d6f2801c3faf
--- /dev/null
+++ b/LCS/PyCommon/methodtrigger.py
@@ -0,0 +1,68 @@
+from threading import Lock, Condition
+
+__all__ = ["MethodTrigger"]
+
+class MethodTrigger:
+  """
+    Set a flag when a specific method is called, possibly asynchronously. Caller can wait on this flag.
+    
+    Example:
+
+      class Foo(object):
+        def bar(self):
+          pass
+
+      foo = Foo()
+      trigger = MethodTrigger(foo, "bar")
+
+      if trigger.wait(): # Waits for 10 seconds for foo.bar() to get called
+        print "foo.bar() got called"
+      else
+        # This will happen, as foo.bar() wasn't called
+        print "foo.bar() did not get called"
+
+    Calls that were made before the trigger has been installed will not get recorded.
+  """
+
+  def __init__(self, obj, method):
+    assert isinstance(obj, object), "Object %s does not derive from object." % (obj,)
+
+    self.obj = obj
+    self.method = method
+    self.old_func = obj.__getattribute__(method)
+
+    self.called = False
+    self.args = []
+    self.kwargs = {}
+
+    self.lock = Lock()
+    self.cond = Condition(self.lock)
+
+    # Patch the target method
+    obj.__setattr__(method, self.trigger)
+
+  def trigger(self, *args, **kwargs):
+    # Save the call parameters
+    self.args = args
+    self.kwargs = kwargs
+
+    # Call the original method
+    self.old_func(*args, **kwargs)
+
+    # Restore the original method
+    self.obj.__setattr__(self.method, self.old_func)
+
+    # Release waiting thread
+    with self.lock:
+      self.called = True
+      self.cond.notify()
+
+  def wait(self, timeout=10.0):
+    # Wait for method to get called
+    with self.lock:
+      if self.called:
+        return True
+
+      self.cond.wait(timeout)
+
+    return self.called
diff --git a/LCS/PyCommon/test/CMakeLists.txt b/LCS/PyCommon/test/CMakeLists.txt
index a2abf73a98a57ed76555c5beb9d870804ff264b8..79c9b43bfa8f22c32c1e1d4278b3ff298192a581 100644
--- a/LCS/PyCommon/test/CMakeLists.txt
+++ b/LCS/PyCommon/test/CMakeLists.txt
@@ -7,3 +7,4 @@ file(COPY
   DESTINATION ${CMAKE_BINARY_DIR}/bin)
 
 lofar_add_test(t_dbcredentials)
+lofar_add_test(t_methodtrigger)
diff --git a/LCS/PyCommon/test/t_methodtrigger.py b/LCS/PyCommon/test/t_methodtrigger.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b96ebcf6de523055e99d1094a2ea395cee0d25f
--- /dev/null
+++ b/LCS/PyCommon/test/t_methodtrigger.py
@@ -0,0 +1,124 @@
+import unittest
+from lofar.common.methodtrigger import MethodTrigger
+
+from threading import Thread
+import time
+
+class TestMethodTrigger(unittest.TestCase):
+  def setUp(self):
+    # Create a basic object
+    class TestClass(object):
+      def func(self):
+        pass
+
+    self.testobj = TestClass()
+
+    # Install trigger
+    self.trigger = MethodTrigger(self.testobj, "func")
+
+  def test_no_call(self):
+    """ Do not trigger. """
+
+    # Wait for trigger
+    self.assertFalse(self.trigger.wait(0.1))
+
+  def test_serial_call(self):
+    """ Trigger and wait serially. """
+
+    # Call function
+    self.testobj.func()
+
+    # Wait for trigger
+    self.assertTrue(self.trigger.wait(0.1))
+
+  def test_parallel_call(self):
+    """ Trigger and wait in parallel. """
+
+    class wait_thread(Thread):
+      def __init__(self, trigger):
+        Thread.__init__(self)
+        self.result = None
+        self.trigger = trigger
+
+      def run(self):
+        self.result = self.trigger.wait(1.0)
+
+    class call_thread(Thread):
+      def __init__(self,func):
+        Thread.__init__(self)
+        self.func = func
+
+      def run(self):
+        time.sleep(0.5)
+        self.func()
+
+    # Start threads
+    t1 = wait_thread(self.trigger)
+    t1.start()
+    t2 = call_thread(self.testobj.func)
+    t2.start()
+
+    # Wait for them to finish
+    t1.join()
+    t2.join()
+
+    # Inspect result
+    self.assertTrue(t1.result)
+
+class TestArgs(unittest.TestCase):
+  def setUp(self):
+    # Create a basic object
+    class TestClass(object):
+      def func(self, a, b, c=None, d=None):
+        pass
+
+    self.testobj = TestClass()
+
+    # Install trigger
+    self.trigger = MethodTrigger(self.testobj, "func")
+
+  def test_args(self):
+    """ Trigger and check args. """
+
+    # Call function
+    self.testobj.func(1, 2)
+
+    # Wait for trigger
+    self.assertTrue(self.trigger.wait(0.1))
+
+    # Check stored arguments
+    self.assertEqual(self.trigger.args, (1, 2))
+
+  def test_kwargs(self):
+    """ Trigger and check kwargs. """
+
+    # Call function
+    self.testobj.func(a=1, b=2)
+
+    # Wait for trigger
+    self.assertTrue(self.trigger.wait(0.1))
+
+    # Check stored arguments
+    self.assertEqual(self.trigger.kwargs, {"a": 1, "b": 2})
+
+  def test_full(self):
+    """ Trigger and check both args and kwargs. """
+
+    # Call function
+    self.testobj.func(1, 2, c=3, d=4)
+
+    # Wait for trigger
+    self.assertTrue(self.trigger.wait(0.1))
+
+    # Check stored arguments
+    self.assertEqual(self.trigger.args, (1, 2))
+    self.assertEqual(self.trigger.kwargs, {"c": 3, "d": 4})
+
+def main(argv):
+  unittest.main(verbosity=2)
+
+if __name__ == "__main__":
+  # run all tests
+  import sys
+  main(sys.argv[1:])
+
diff --git a/LCS/PyCommon/test/t_methodtrigger.sh b/LCS/PyCommon/test/t_methodtrigger.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c786a2cbcdafae4571c5b6fba84fa21c96381ad6
--- /dev/null
+++ b/LCS/PyCommon/test/t_methodtrigger.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+./runctest.sh t_methodtrigger