diff --git a/.gitattributes b/.gitattributes
index 22fdef416baa5eb45ab667231b40b8edb199cb62..d6f9072fcda479d0ff0720e28b0abea69c3b6ce3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2239,6 +2239,7 @@ CMake/variants/variants.dop282 -text
 CMake/variants/variants.fs0 -text
 CMake/variants/variants.gpu01 -text
 CMake/variants/variants.gpu1 -text
+CMake/variants/variants.lhn002 -text
 CMake/variants/variants.node501 -text
 CMake/variants/variants.node502 -text
 CMake/variants/variants.node503 -text
@@ -2444,6 +2445,27 @@ LCS/MSLofar/test/tBeamTables.in_during_filled -text
 LCS/MSLofar/test/tBeamTables.in_hd/CS001-iHBADeltas.conf -text
 LCS/MSLofar/test/tBeamTables.in_hd/DE601-iHBADeltas.conf -text
 LCS/MSLofar/test/tBeamTables.in_hd/RS106-iHBADeltas.conf -text
+LCS/MessageBus/data/feedback_dp_44833.txt -text
+LCS/MessageBus/data/feedback_dp_empty.txt -text
+LCS/MessageBus/data/feedback_dp_no_ids.txt -text
+LCS/MessageBus/data/feedback_dp_xml_error.txt -text
+LCS/MessageBus/data/task_spec_system_78958.txt -text
+LCS/MessageBus/data/task_spec_system_empty.txt -text
+LCS/MessageBus/data/task_spec_system_no_ids.txt -text
+LCS/MessageBus/data/task_spec_system_xml_error.txt -text
+LCS/MessageBus/include/MessageBus/Protocols/TaskSpecificationSystem.h -text
+LCS/MessageBus/src/LofarMsgTemplate.txt -text
+LCS/MessageBus/src/Message.cc -text
+LCS/MessageBus/src/__init__.py -text
+LCS/MessageBus/src/basemsgbus.py -text
+LCS/MessageBus/src/msgbus.py -text
+LCS/MessageBus/test/tMessage.cc -text
+LCS/MessageBus/test/tMsgBus.cc -text
+LCS/MessageBus/test/tMsgBus.run eol=lf
+LCS/MessageBus/test/tMsgBus.sh eol=lf
+LCS/MessageDaemons/src/MessageRouter -text
+LCS/MessageDaemons/src/MessageRouter.conf.ccu001 -text
+LCS/MessageDaemons/src/MessageRouter.conf.ccu099 -text
 LCS/Tools/src/checkcomp.py -text
 LCS/Tools/src/countalllines -text
 LCS/Tools/src/countlines -text
@@ -4136,7 +4158,9 @@ RTCP/Cobalt/GPUProc/test/Kernels/tKernelPerformance.run eol=lf
 RTCP/Cobalt/GPUProc/test/Kernels/tKernelPerformance.sh eol=lf
 RTCP/Cobalt/GPUProc/test/Kernels/visualizeBeamformer.py eol=lf
 RTCP/Cobalt/GPUProc/test/Pipelines/tCorrelatorPipelineProcessObs.sh eol=lf
+RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.queue -text
 RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run eol=lf
+RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run2.in eol=lf
 RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.sh eol=lf
 RTCP/Cobalt/GPUProc/test/SubbandProcs/plot_arrays.py eol=lf
 RTCP/Cobalt/GPUProc/test/SubbandProcs/tBeamFormerSubbandProcProcessSb.parset -text
@@ -4249,6 +4273,14 @@ RTCP/Cobalt/clAmdFft/samples/statisticalTimer.h -text
 RTCP/Cobalt/clAmdFft/samples/stdafx.cpp -text
 RTCP/Cobalt/clAmdFft/samples/stdafx.h -text
 RTCP/Cobalt/clAmdFft/samples/targetver.h -text
+SAS/Feedback_Service/CMakeLists.txt -text
+SAS/Feedback_Service/package.dox -text
+SAS/Feedback_Service/src/CMakeLists.txt -text
+SAS/Feedback_Service/src/Feedback.cc -text
+SAS/Feedback_Service/src/Feedback.h -text
+SAS/Feedback_Service/src/FeedbackMain.cc -text
+SAS/Feedback_Service/src/FeedbackService.conf -text
+SAS/Feedback_Service/src/fb_data_44883.txt -text
 SAS/OTB/OTB-distribution/assembly.xml -text
 SAS/OTB/OTB-distribution/pom.xml -text
 SAS/OTB/OTB/assembly.xml -text
@@ -4571,6 +4603,7 @@ SubSystems/LAPS_CEP/test/tExampleTest.sh eol=lf
 SubSystems/Online_Cobalt/install/install_DAL.sh eol=lf
 SubSystems/Online_Cobalt/install/install_IERS.sh eol=lf
 SubSystems/Online_Cobalt/install/install_casacore.sh eol=lf
+SubSystems/Online_Cobalt/install/install_qpid.sh eol=lf
 SubSystems/Online_Cobalt/install/lofarsys/bash_profile -text
 SubSystems/Online_Cobalt/install/lofarsys/bashrc -text
 SubSystems/Online_Cobalt/install/postinstall.sh eol=lf
@@ -4598,6 +4631,8 @@ SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.outp
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/SB2.cfloat.raw -text
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/SB3.cfloat.raw -text
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/SB4.cfloat.raw -text
+SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.processing -text
+SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.state -text
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.parset -text
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.run eol=lf
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.sh eol=lf
@@ -4617,17 +4652,17 @@ SubSystems/Online_Cobalt/test/Correlator/tCorrelate_3sec_2st_5sb.output/SB4.cflo
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_3sec_2st_5sb.parset -text
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_3sec_2st_5sb.run eol=lf
 SubSystems/Online_Cobalt/test/Correlator/tCorrelate_3sec_2st_5sb.sh eol=lf
-SubSystems/Online_Cobalt/test/MockOnlineControl.sh eol=lf
-SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_failure_1 -text
-SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_success_1 -text
-SubSystems/Online_Cobalt/test/tMACfeedback.run eol=lf
-SubSystems/Online_Cobalt/test/tMACfeedback.sh eol=lf
 SubSystems/Online_Cobalt/test/tProductionParsets.in_parsets/CorrProc_173014.param -text
 SubSystems/Online_Cobalt/test/tProductionParsets.in_parsets/CorrProc_196344-CygAf009-225SAPS.cleaned.param -text
 SubSystems/Online_Cobalt/test/tProductionParsets.run eol=lf
 SubSystems/Online_Cobalt/test/tProductionParsets.sh eol=lf
 SubSystems/Online_Cobalt/test/tRTmetadataToFile.run eol=lf
 SubSystems/Online_Cobalt/test/tRTmetadataToFile.sh eol=lf
+SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_failure_1 -text
+SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_success_1 -text
+SubSystems/Online_Cobalt/test/tStatusFeedback.run eol=lf
+SubSystems/Online_Cobalt/test/tStatusFeedback.run2.in eol=lf
+SubSystems/Online_Cobalt/test/tStatusFeedback.sh eol=lf
 SubSystems/Online_Cobalt/test/tgenerateStationStreams.run eol=lf
 SubSystems/Online_Cobalt/test/tgenerateStationStreams.sh eol=lf
 SubSystems/Online_Cobalt/test/tstartBGL.in_parset -text
diff --git a/CEP/Pipeline/framework/lofarpipe/CMakeLists.txt b/CEP/Pipeline/framework/lofarpipe/CMakeLists.txt
index e5a6089bcab31fcf053d6ef9c623afae58f8353b..6ecc2a1b27e09bb7958fe47506ac0453f8c557b4 100644
--- a/CEP/Pipeline/framework/lofarpipe/CMakeLists.txt
+++ b/CEP/Pipeline/framework/lofarpipe/CMakeLists.txt
@@ -26,7 +26,6 @@ python_install(
   support/lofarnode.py
   support/loggingdecorators.py
   support/mac.py
-  support/mac_feedback.py
   support/parset.py
   support/pipelinelogging.py
   support/remotecommand.py
diff --git a/CEP/Pipeline/framework/lofarpipe/support/baserecipe.py b/CEP/Pipeline/framework/lofarpipe/support/baserecipe.py
index c72f155f50936a2ad3ec1109093566697edffddb..2c34a2fad60206e3a2bc423fd4237900ba4b1e4c 100644
--- a/CEP/Pipeline/framework/lofarpipe/support/baserecipe.py
+++ b/CEP/Pipeline/framework/lofarpipe/support/baserecipe.py
@@ -45,7 +45,7 @@ class BaseRecipe(RecipeIngredients, WSRTrecipe):
         # Environment variables we like to pass on to the node script.
         self.environment = dict(
             (k, v) for (k, v) in os.environ.iteritems()
-                if k.endswith('PATH') or k.endswith('ROOT')
+                if k.endswith('PATH') or k.endswith('ROOT') or k == 'QUEUE_PREFIX'
         )
 
     @property
diff --git a/CEP/Pipeline/framework/lofarpipe/support/control.py b/CEP/Pipeline/framework/lofarpipe/support/control.py
index 2d85dc179f7f20dba54e881a69533a797e8b2bae..ce89b9ea70992c51b7157fe43ee1e1a8bf401cf2 100644
--- a/CEP/Pipeline/framework/lofarpipe/support/control.py
+++ b/CEP/Pipeline/framework/lofarpipe/support/control.py
@@ -6,6 +6,7 @@
 #                                                             Marcel Loose, 2012
 #                                                                loose@astron.nl
 # ------------------------------------------------------------------------------
+import os
 import sys
 import re
 import traceback
@@ -13,7 +14,11 @@ import traceback
 from lofarpipe.support.stateful import StatefulRecipe
 from lofarpipe.support.lofarexceptions import PipelineException
 from lofarpipe.support.xmllogging import get_active_stack
-import lofarpipe.support.mac_feedback as mac_feedback
+from lofar.parameterset import parameterset
+import lofar.messagebus.msgbus
+from lofar.messagebus.protocols.taskfeedbackdataproducts import TaskFeedbackDataproducts
+from lofar.messagebus.protocols.taskfeedbackprocessing import TaskFeedbackProcessing
+from lofar.messagebus.protocols.taskfeedbackstate import TaskFeedbackState
 
 #                                             Standalone Pipeline Control System
 # ------------------------------------------------------------------------------
@@ -22,7 +27,7 @@ class control(StatefulRecipe):
     """
     Basic pipeline control framework.
 
-    Define a pipeline by subclassing and provding a body for the
+    Define a pipeline by subclassing and providing a body for the
     :meth:`pipeline_logic`.
 
     This class provides little, but can be specialised to eg provide a
@@ -30,46 +35,77 @@ class control(StatefulRecipe):
     """
     inputs = {}
 
-    def _send_mac_feedback(self, status):
+    def __init__(self):
+      super(control, self).__init__()
+      
+      self.parset = parameterset()
+      self.momID = 0
+      self.sasID = 0
+
+    def usage(self):
+        """
+        Display usage information
+        """
+        print >> sys.stderr, "Usage: %s <parset-file>  [options]" % sys.argv[0]
+        return 1
+
+    def send_feedback_processing(self, feedback):
+        """
+        Send processing feedback information back to LOFAR.
+
+        `feedback` must be a parameterset
+        """
+
+        if self.feedback_method == "messagebus":
+          bus = lofar.messagebus.msgbus.ToBus("lofar.task.feedback.processing")
+          msg = TaskFeedbackProcessing(
+            "lofarpipe.support.control",
+            "",
+            "Processing feedback from the pipeline framework",
+            self.momID,
+            self.sasID,
+            feedback)
+
+          bus.send(msg)
+
+    def send_feedback_dataproducts(self, feedback):
         """
-        Send status information back to MAC, but only if the Python controller
-        host to send this information to was given as input argument.
+        Send dataproduct feedback information back to LOFAR.
+
+        `feedback` must be a parameterset
+        """
+
+        if self.feedback_method == "messagebus":
+          bus = lofar.messagebus.msgbus.ToBus("lofar.task.feedback.dataproducts")
+          msg = TaskFeedbackDataproducts(
+            "lofarpipe.support.control",
+            "",
+            "Dataproduct feedback from the pipeline framework",
+            self.momID,
+            self.sasID,
+            feedback)
+
+          bus.send(msg)
+
+    def _send_feedback_status(self, status):
+        """
+        Send status information back to LOFAR.
+
         `status` must be an integer; 0 indicates success, any other value
         indicates failure.
-        The port number is calculated as 22000 + observationNr%1000. 
-        We need to extract this number from the job-name, which should be equal
-        to "Observation" + str(observationNr).
         """
-        try:
-            host = self.inputs['args'][1]
-        except IndexError:
-            self.logger.warn(
-                "No MAC Python controller host specified. "
-                "Not sending status feedback to MAC"
-            )
-            return
-        # Determine port number to use.
-        match = re.findall(r'^Observation(\d+)$', self.inputs['job_name'])
-        if match:
-            port = 25000 + int(match[0]) % 7000
-            self.logger.info(
-                "Sending status feedback to MAC [%s:%s] (status: %s)" %
-                (host, port, status)
-            )
-        else:
-            self.logger.warn(
-                r"Job-name does not match with pattern '^Observation(\d+)$'. "
-                "Not sending status feedback to MAC"
-            )
-            return
-        # Send feedback information
-        try:
-            mac_feedback.send_status(host, port, status)
-        except IOError, error:
-            self.logger.warn(
-                "Failed to send status feedback to MAC [%s:%s]: %s" %
-                (host, port, error)
-            )
+
+        if self.feedback_method == "messagebus":
+          bus = lofar.messagebus.msgbus.ToBus("lofar.task.feedback.state")
+          msg = TaskFeedbackState(
+            "lofarpipe.support.control",
+            "",
+            "Status feedback from the pipeline framework",
+            self.momID,
+            self.sasID,
+            status == 0)
+
+          bus.send(msg)
 
     def pipeline_logic(self):
         """
@@ -78,8 +114,40 @@ class control(StatefulRecipe):
         raise NotImplementedError
 
     def go(self):
+        # Read the parset-file that was given as input argument
+        try:
+            parset_file = os.path.abspath(self.inputs['args'][0])
+        except IndexError:
+            return self.usage()
+        self.parset.adoptFile(parset_file)
+        # Set job-name to basename of parset-file w/o extension, if it's not
+        # set on the command-line with '-j' or '--job-name'
+        if not 'job_name' in self.inputs:
+            self.inputs['job_name'] = (
+                os.path.splitext(os.path.basename(parset_file))[0]
+            )
+
+        # we can call our parent now that we have a job_name
         super(control, self).go()
+
+        # we now have a self.config -- read our settings
+        try:
+          self.feedback_method = self.config.get('feedback', 'method')
+        except:
+          self.feedback_method = "messagebus"
+
+        if self.feedback_method == "messagebus" and not lofar.messagebus.msgbus.enabled:
+          self.logger.error("Feedback over messagebus requested, but messagebus support is not enabled or functional")
+          return 1
+
+        # Pull several parameters from the parset
+        self.momID = self.parset.getString("ObsSW.Observation.momID", "")  # Note: 0 if obs was copied in Scheduler
+        self.sasID = self.parset.getString("ObsSW.Observation.otdbID", "") # SAS ID
+
+        # Start the pipeline
         self.logger.info("LOFAR Pipeline (%s) starting." % self.name)
+        self.logger.info("SASID = %s, MOMID = %s, Feedback method = %s" % (self.sasID, self.momID, self.feedback_method))
+
         try:
             self.pipeline_logic()
         except Exception, message:
@@ -98,10 +166,12 @@ class control(StatefulRecipe):
 
             self.logger.error("*******************************************")
 
-            self._send_mac_feedback(1)
+            # Emit process status
+            self._send_feedback_status(1)
             return 1
         else:
-            self._send_mac_feedback(0)
+            # Emit process status
+            self._send_feedback_status(0)
             return 0
         finally:
             # always print a xml stats file
diff --git a/CEP/Pipeline/framework/lofarpipe/support/lofaringredient.py b/CEP/Pipeline/framework/lofarpipe/support/lofaringredient.py
index df9ca7e230b961d5bc195211f8613c8106c06771..e6f6006242c8920664c82e7ffadcf37c0e6b16b5 100644
--- a/CEP/Pipeline/framework/lofarpipe/support/lofaringredient.py
+++ b/CEP/Pipeline/framework/lofarpipe/support/lofaringredient.py
@@ -11,6 +11,7 @@ from UserDict import DictMixin
 
 from lofarpipe.cuisine.ingredient import WSRTingredient
 from lofarpipe.support.utilities import string_to_list, is_iterable
+from lofar.parameterset import parameterset
 
 #       These are currently only used by lofarrecipe.run_task to provide default
 #              input and output dicts based on copying metadata from the parent.
@@ -194,6 +195,13 @@ class DictField(Field):
     def is_valid(self, value):
         return isinstance(value, dict)
 
+class ParsetField(Field):
+    """
+    A Field which accepts a parameterset object.
+    """
+    def is_valid(self, value):
+        return isinstance(value, parameterset)
+
 class FileList(ListField):
     """
     A Field which accepts a list of extant filenames.
diff --git a/CEP/Pipeline/framework/lofarpipe/support/mac_feedback.py b/CEP/Pipeline/framework/lofarpipe/support/mac_feedback.py
deleted file mode 100644
index baa2561991687ac2da905590a2871bd8ae0b3e7f..0000000000000000000000000000000000000000
--- a/CEP/Pipeline/framework/lofarpipe/support/mac_feedback.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#                                                         LOFAR IMAGING PIPELINE
-#
-#                                                   MAC Status Feedback QuickFix
-#                                                             Marcel Loose, 2012
-#                                                                loose@astron.nl
-# ------------------------------------------------------------------------------
-
-"""
-This module implements the quick fix (Redmine issue #3633) for the pipeline
-status feedback to MAC. 
-"""
-
-import random
-import socket
-import time
-
-def __try_connect(host, port, tries=5, min_timeout=1.0, max_timeout=5.0):
-    """
-    Try to connect to `host`:`port` up time `tries` times, using a random
-    timeout interval ([`min_timeout` .. `max_timeout`) seconds ) between
-    retries.
-    Return a socket object.
-    Raises `socket.error` if all connect tries fail.
-    """
-    # Create a socket (SOCK_STREAM means a TCP socket)
-    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    while True:
-        tries -= 1
-        try:
-            sock.connect((host, port))
-        except socket.error, err:
-            print("Could not connect to %s:%s (got %s)" %
-                  (host, str(port), str(err)))
-            if tries > 0:
-                timeout = random.uniform(min_timeout, max_timeout)
-                print("Retrying in %f seconds (%d more %s)." %
-                      (timeout, tries, "try" if tries==1 else "tries"))
-                time.sleep(timeout)
-            else:
-                raise IOError(err)
-        else:
-            return sock
-
-
-def send_status(host, port, status):
-    """
-    Send the pipeline status to a TCP listener at `host`:`port`. If `status` is
-    non-zero, send the string 'ABORT'; otherwise send the string 'FINISHED'.
-    """
-    message = "FINISHED" if status == 0 else "ABORT"
-    sock = __try_connect(host, port)
-    sock.sendall(message)
-    sock.close()
-
-
-if __name__ == "__main__":
-    """
-    Simple command line test.
-    Usage: python mac_feedback.py [<host>] [<port>] [<status>]
-    """
-    import sys
-    host = str(sys.argv[1]) if len(sys.argv) > 1 else "localhost"
-    port = int(sys.argv[2]) if len(sys.argv) > 2 else 9999
-    stat = int(sys.argv[3]) if len(sys.argv) > 3 else 0
-    send_status(host, port, stat)
-
-
diff --git a/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py b/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
index d2ce444a39cddd741a0132b3e7c24276e82a3d53..963ee22660ab255a8d1badfc0f5f6df68a733b1f 100644
--- a/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
+++ b/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
@@ -252,7 +252,8 @@ class ComputeJob(object):
                     "PATH": os.environ.get('PATH'),
                     "PYTHONPATH": os.environ.get('PYTHONPATH'),
                     "LD_LIBRARY_PATH": os.environ.get('LD_LIBRARY_PATH'),
-                    "LOFARROOT" : os.environ.get('LOFARROOT')
+                    "LOFARROOT" : os.environ.get('LOFARROOT'),
+                    "QUEUE_PREFIX" : os.environ.get('QUEUE_PREFIX','')
                 },
                 arguments = [id, jobhost, jobport]
             )
diff --git a/CEP/Pipeline/recipes/sip/bin/calibration_pipeline.py b/CEP/Pipeline/recipes/sip/bin/calibration_pipeline.py
index a6d35a7bd03fe2cdb010e3ec5f0645b515b58885..733c5dd90cb6417cc2f0f0ee8c934f531927e56e 100755
--- a/CEP/Pipeline/recipes/sip/bin/calibration_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/calibration_pipeline.py
@@ -31,23 +31,13 @@ class calibration_pipeline(control):
     4. Create a sourcedb from the user-supplied sky model, and an empty parmdb.
     5. Run BBS to calibrate the data.
     6. Copy the MS's to their final output destination.
-    7. Create feedback file for further processing by the LOFAR framework (MAC)
+    7. Create feedback for further processing by the LOFAR framework
     """
 
     def __init__(self):
         super(calibration_pipeline, self).__init__()
-        self.parset = parameterset()
         self.input_data = {}
         self.output_data = {}
-        self.parset_feedback_file = None
-
-
-    def usage(self):
-        """
-        Display usage
-        """
-        print >> sys.stderr, "Usage: %s [options] <parset-file>" % sys.argv[0]
-        return 1
 
 
     def _get_io_product_specs(self):
@@ -98,28 +88,6 @@ class calibration_pipeline(control):
             )
 
 
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not self.inputs.has_key('job_name'):
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0])
-
-        # Call the base-class's `go()` method.
-        return super(calibration_pipeline, self).go()
-
-
     @mail_log_on_exception
     def pipeline_logic(self):
         """
@@ -294,31 +262,27 @@ class calibration_pipeline(control):
             )
 
         # *********************************************************************
-        # 7. Create feedback file for further processing by the LOFAR framework
+        # 7. Create feedback for further processing by the LOFAR framework
         #    a. get metadata of the measurement sets
         #    b. get metadata of the instrument models
-        #    c. join the two files and write the final feedback file
-        correlated_metadata = os.path.join(parset_dir, "correlated.metadata")
-        instrument_metadata = os.path.join(parset_dir, "instrument.metadata")
+        #    c. join the two and write the final feedback
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", output_correlated_mapfile,
-                parset_file=correlated_metadata,
+            correlated_metadata = self.run_task("get_metadata", output_correlated_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')),
-                product_type="Correlated")
+                product_type="Correlated")["metadata"]
 
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", output_instrument_mapfile,
-                parset_file=instrument_metadata,
+            instrument_metadata = self.run_task("get_metadata", output_instrument_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')),
-                product_type="InstrumentModel")
+                product_type="InstrumentModel")["metadata"]
 
-        parset = parameterset(correlated_metadata)
-        parset.adoptFile(instrument_metadata)
-        parset.writeFile(self.parset_feedback_file)
+        self.send_feedback_processing(parameterset())
+        self.send_feedback_dataproducts(correlated_metadata)
+        self.send_feedback_dataproducts(instrument_metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/imaging_pipeline.py b/CEP/Pipeline/recipes/sip/bin/imaging_pipeline.py
index fa2f6e071981bfae11fb21ac6e4932c6995d753f..269bea6a1072d68f2db48ab4b3e10882205536dc 100755
--- a/CEP/Pipeline/recipes/sip/bin/imaging_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/imaging_pipeline.py
@@ -81,7 +81,7 @@ class imaging_pipeline(control):
        and results are collected an added to the casa image. The images created
        are converted from casa to HDF5 and copied to the correct output
        location.
-    7. Export meta data: An outputfile with meta data is generated ready for
+    7. Export meta data: meta data is generated ready for
        consumption by the LTA and/or the LOFAR framework.
 
 
@@ -97,41 +97,13 @@ class imaging_pipeline(control):
         Initialize member variables and call superclass init function
         """
         control.__init__(self)
-        self.parset = parameterset()
         self.input_data = DataMap()
         self.target_data = DataMap()
         self.output_data = DataMap()
         self.scratch_directory = None
-        self.parset_feedback_file = None
         self.parset_dir = None
         self.mapfile_dir = None
 
-    def usage(self):
-        """
-        Display usage information
-        """
-        print >> sys.stderr, "Usage: %s <parset-file>  [options]" % sys.argv[0]
-        return 1
-
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not 'job_name' in self.inputs:
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0]
-            )
-        return super(imaging_pipeline, self).go()
-
     @mail_log_on_exception
     def pipeline_logic(self):
         """
@@ -231,14 +203,16 @@ class imaging_pipeline(control):
 
         # *********************************************************************
         # (7) Get metadata
-        # Create a parset-file containing the metadata for MAC/SAS
-        self.run_task("get_metadata", placed_data_image_map,
-            parset_file = self.parset_feedback_file,
+        # Create a parset containing the metadata for MAC/SAS
+        metadata = self.run_task("get_metadata", placed_data_image_map,
             parset_prefix = (
                 full_parset.getString('prefix') +
                 full_parset.fullModuleName('DataProducts')
             ),
-            product_type = "SkyImage")
+            product_type = "SkyImage")["metadata"]
+
+        self.send_feedback_processing(parameterset())
+        self.send_feedback_dataproducts(metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/long_baseline_pipeline.py b/CEP/Pipeline/recipes/sip/bin/long_baseline_pipeline.py
index 8ccd77e892d4c817047dbe0ebc8ee22e78110ce7..7dcc5600358151311284a430f495c7dc13ceb465 100644
--- a/CEP/Pipeline/recipes/sip/bin/long_baseline_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/long_baseline_pipeline.py
@@ -52,7 +52,7 @@ class msss_imager_pipeline(control):
        single large measurement set and perform flagging, RFI and bad station
        exclusion.
 
-    2. Generate meta information feedback files based on dataproduct information
+    2. Generate meta information feedback based on dataproduct information
        and parset/configuration data
 
     **Per subband-group, the following output products will be delivered:**
@@ -64,40 +64,13 @@ class msss_imager_pipeline(control):
         Initialize member variables and call superclass init function
         """
         control.__init__(self)
-        self.parset = parameterset()
         self.input_data = DataMap()
         self.target_data = DataMap()
         self.output_data = DataMap()
         self.scratch_directory = None
-        self.parset_feedback_file = None
         self.parset_dir = None
         self.mapfile_dir = None
 
-    def usage(self):
-        """
-        Display usage information
-        """
-        print >> sys.stderr, "Usage: %s <parset-file>  [options]" % sys.argv[0]
-        return 1
-
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not 'job_name' in self.inputs:
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0]
-            )
-        return super(msss_imager_pipeline, self).go()
 
     @mail_log_on_exception
     def pipeline_logic(self):
@@ -178,30 +151,17 @@ class msss_imager_pipeline(control):
                                            str(subbands_per_subbandgroup))
         toplevel_meta_data.replace("subbandGroupsPerMS", 
                                            str(subbandgroups_per_ms))
-
-        toplevel_meta_data_path = os.path.join(
-                self.parset_dir, "toplevel_meta_data.parset")
-
-        try:
-            toplevel_meta_data.writeFile(toplevel_meta_data_path)
-            self.logger.info("Wrote meta data to: " + 
-                    toplevel_meta_data_path)
-        except RuntimeError, err:
-            self.logger.error(
-              "Failed to write toplevel meta information parset: %s" % str(
-                                    toplevel_meta_data_path))
-            return 1
-
         
         # Create a parset-file containing the metadata for MAC/SAS at nodes
-        self.run_task("get_metadata", output_ms_mapfile,
-            parset_file = self.parset_feedback_file,
+        metadata = self.run_task("get_metadata", output_ms_mapfile,
             parset_prefix = (
                 full_parset.getString('prefix') +
                 full_parset.fullModuleName('DataProducts')
             ),
-            toplevel_meta_data_path=toplevel_meta_data_path, 
-            product_type = "Correlated")
+            product_type = "Correlated")["metadata"]
+
+        self.send_feedback_processing(toplevel_meta_data)
+        self.send_feedback_dataproducts(metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/msss_calibrator_pipeline.py b/CEP/Pipeline/recipes/sip/bin/msss_calibrator_pipeline.py
index 15d9632db40dc08ab1454e498d88a3c59c7cb2fa..893c16ff40237d413ba6d4b9a8cd3c1b95f23d2b 100755
--- a/CEP/Pipeline/recipes/sip/bin/msss_calibrator_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/msss_calibrator_pipeline.py
@@ -37,7 +37,7 @@ class msss_calibrator_pipeline(control):
        parset, and the sourcedb made earlier
     5. Perform gain correction on the created instrument table
     6. Copy corrected MS's to their final output destination
-    7. Create output for consumption by the LOFAR framework
+    7. Create metadata for consumption by the LOFAR framework
 
     **Per subband-group, the following output products will be delivered:**
 
@@ -48,18 +48,8 @@ class msss_calibrator_pipeline(control):
 
     def __init__(self):
         control.__init__(self)
-        self.parset = parameterset()
         self.input_data = {}
         self.output_data = {}
-        self.parset_feedback_file = None
-
-
-    def usage(self):
-        """
-        Display usage
-        """
-        print >> sys.stderr, "Usage: %s [options] <parset-file>" % sys.argv[0]
-        return 1
 
 
     def _get_io_product_specs(self):
@@ -110,28 +100,6 @@ class msss_calibrator_pipeline(control):
             )
 
 
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not self.inputs.has_key('job_name'):
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0])
-
-        # Call the base-class's `go()` method.
-        return super(msss_calibrator_pipeline, self).go()
-
-
     @mail_log_on_exception
     def pipeline_logic(self):
         """
@@ -309,31 +277,27 @@ class msss_calibrator_pipeline(control):
             )
 
         # *********************************************************************
-        # 7. Create feedback file for further processing by the LOFAR framework
+        # 7. Create feedback for further processing by the LOFAR framework
         #    a. get metadata of the measurement sets
         #    b. get metadata of the instrument models
-        #    c. join the two files and write the final feedback file
-        correlated_metadata = os.path.join(parset_dir, "correlated.metadata")
-        instrument_metadata = os.path.join(parset_dir, "instrument.metadata")
+        #    c. join the two and write the final feedback
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", output_correlated_mapfile,
-                parset_file=correlated_metadata,
+            correlated_metadata = self.run_task("get_metadata", output_correlated_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')),
-                product_type="Correlated")
+                product_type="Correlated")["metadata"]
 
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", output_instrument_mapfile,
-                parset_file=instrument_metadata,
+            instrument_metadata = self.run_task("get_metadata", output_instrument_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')),
-                product_type="InstrumentModel")
+                product_type="InstrumentModel")["metadata"]
 
-        parset = parameterset(correlated_metadata)
-        parset.adoptFile(instrument_metadata)
-        parset.writeFile(self.parset_feedback_file)
+        self.send_feedback_processing(parameterset())
+        self.send_feedback_dataproducts(correlated_metadata)
+        self.send_feedback_dataproducts(instrument_metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/msss_imager_pipeline.py b/CEP/Pipeline/recipes/sip/bin/msss_imager_pipeline.py
index 42c6a13db83c7ebdcef935928ccf85699fb2d4bd..29d05237a0ff5d5954c9168b100734d73ebb2194 100755
--- a/CEP/Pipeline/recipes/sip/bin/msss_imager_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/msss_imager_pipeline.py
@@ -77,7 +77,7 @@ class msss_imager_pipeline(control):
        and results are collected an added to the casa image. The images created
        are converted from casa to HDF5 and copied to the correct output
        location.
-    7. Export meta data: An outputfile with meta data is generated ready for
+    7. Export meta data: meta data is generated ready for
        consumption by the LTA and/or the LOFAR framework.
 
 
@@ -93,40 +93,13 @@ class msss_imager_pipeline(control):
         Initialize member variables and call superclass init function
         """
         control.__init__(self)
-        self.parset = parameterset()
         self.input_data = DataMap()
         self.target_data = DataMap()
         self.output_data = DataMap()
         self.scratch_directory = None
-        self.parset_feedback_file = None
         self.parset_dir = None
         self.mapfile_dir = None
 
-    def usage(self):
-        """
-        Display usage information
-        """
-        print >> sys.stderr, "Usage: %s <parset-file>  [options]" % sys.argv[0]
-        return 1
-
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not 'job_name' in self.inputs:
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0]
-            )
-        return super(msss_imager_pipeline, self).go()
 
     @mail_log_on_exception
     def pipeline_logic(self):
@@ -239,29 +212,17 @@ class msss_imager_pipeline(control):
         toplevel_meta_data = parameterset()
         toplevel_meta_data.replace("numberOfMajorCycles", 
                                            str(number_of_major_cycles))
-        toplevel_meta_data_path = os.path.join(
-                self.parset_dir, "toplevel_meta_data.parset")
 
-        try:
-            toplevel_meta_data.writeFile(toplevel_meta_data_path)
-            self.logger.info("Wrote meta data to: " + 
-                    toplevel_meta_data_path)
-        except RuntimeError, err:
-            self.logger.error(
-              "Failed to write toplevel meta information parset: %s" % str(
-                                    toplevel_meta_data_path))
-            return 1
-
-        
-        # Create a parset-file containing the metadata for MAC/SAS at nodes
-        self.run_task("get_metadata", placed_data_image_map,
-            parset_file = self.parset_feedback_file,
+        # Create a parset containing the metadata for MAC/SAS at nodes
+        metadata = self.run_task("get_metadata", placed_data_image_map,
             parset_prefix = (
                 full_parset.getString('prefix') +
                 full_parset.fullModuleName('DataProducts')
             ),
-            toplevel_meta_data_path=toplevel_meta_data_path, 
-            product_type = "SkyImage")
+            product_type = "SkyImage")["metadata"]
+
+        self.send_feedback_processing(toplevel_meta_data)
+        self.send_feedback_dataproducts(metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/msss_target_pipeline.py b/CEP/Pipeline/recipes/sip/bin/msss_target_pipeline.py
index 59c853ad7843cddbc1823d0e2b4e5cce98a1da4f..2cf67ccc934ba7b4c950beeba79ae8d455487f3e 100755
--- a/CEP/Pipeline/recipes/sip/bin/msss_target_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/msss_target_pipeline.py
@@ -38,7 +38,7 @@ class msss_target_pipeline(control):
     5. Run BBS using the instrument file from the target observation, to
        correct for instrumental effects
     6. Copy the MS's to their final output destination.
-    7. Create feedback file for further processing by the LOFAR framework (MAC)
+    7. Create feedback for further processing by the LOFAR framework
 
     **Per subband-group, the following output products will be delivered:**
 
@@ -48,18 +48,8 @@ class msss_target_pipeline(control):
 
     def __init__(self):
         control.__init__(self)
-        self.parset = parameterset()
         self.input_data = {}
         self.output_data = {}
-        self.parset_feedback_file = None
-
-
-    def usage(self):
-        """
-        Display usage information
-        """
-        print >> sys.stderr, "Usage: %s [options] <parset-file>" % sys.argv[0]
-        return 1
 
 
     def _get_io_product_specs(self):
@@ -171,29 +161,6 @@ class msss_target_pipeline(control):
             )
 
 
-    def go(self):
-        """
-        Read the parset-file that was given as input argument, and set the
-        jobname before calling the base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-        
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not self.inputs.has_key('job_name'):
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0]
-            )
-
-        # Call the base-class's `go()` method.
-        return super(msss_target_pipeline, self).go()
-
-
     @mail_log_on_exception
     def pipeline_logic(self):
         """
@@ -345,17 +312,17 @@ class msss_target_pipeline(control):
             )
 
         # *********************************************************************
-        # 7. Create feedback file for further processing by the LOFAR framework
-        # (MAC)
-        # Create a parset-file containing the metadata for MAC/SAS
+        # 7. Create feedback for further processing by the LOFAR framework
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", corrected_mapfile,
-                parset_file=self.parset_feedback_file,
+            metadata = self.run_task("get_metadata", corrected_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')
                 ),
-                product_type="Correlated")
+                product_type="Correlated")["metadata"]
+
+        self.send_feedback_processing(parameterset())
+        self.send_feedback_dataproducts(metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/preprocessing_pipeline.py b/CEP/Pipeline/recipes/sip/bin/preprocessing_pipeline.py
index 6039d9211d34f4a2baa6de011af3f909a57be235..a5f8a75db9e26f429aa64c055a1fc834da0a1fbc 100755
--- a/CEP/Pipeline/recipes/sip/bin/preprocessing_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/preprocessing_pipeline.py
@@ -30,19 +30,9 @@ class preprocessing_pipeline(control):
 
     def __init__(self):
         super(preprocessing_pipeline, self).__init__()
-        self.parset = parameterset()
         self.input_data = []
         self.output_data = []
         self.io_data_mask = []
-        self.parset_feedback_file = None
-
-
-    def usage(self):
-        """
-        Display usage
-        """
-        print >> sys.stderr, "Usage: %s [options] <parset-file>" % sys.argv[0]
-        return 1
 
 
     def _get_io_product_specs(self):
@@ -109,28 +99,6 @@ class preprocessing_pipeline(control):
 #                )
 #            )
 
-    def go(self):
-        """
-        Read the parset-file that was given as input argument;
-        set jobname, and input/output data products before calling the
-        base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not self.inputs.has_key('job_name'):
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0])
-
-        # Call the base-class's `go()` method.
-        return super(preprocessing_pipeline, self).go()
-
 
     @mail_log_on_exception
     def pipeline_logic(self):
@@ -232,15 +200,15 @@ class preprocessing_pipeline(control):
 
         # *********************************************************************
         # 6. Create feedback file for further processing by the LOFAR framework
-        # (MAC)
-        # Create a parset-file containing the metadata for MAC/SAS
+        # Create a parset containing the metadata
         with duration(self, "get_metadata"):
-            self.run_task("get_metadata", output_data_mapfile,
-                parset_file=self.parset_feedback_file,
+            metadata = self.run_task("get_metadata", output_data_mapfile,
                 parset_prefix=(
                     self.parset.getString('prefix') +
                     self.parset.fullModuleName('DataProducts')),
-                product_type="Correlated")
+                product_type="Correlated")["metadata"]
+
+        self.send_feedback_dataproducts(metadata)
 
         return 0
 
diff --git a/CEP/Pipeline/recipes/sip/bin/pulsar_pipeline.py b/CEP/Pipeline/recipes/sip/bin/pulsar_pipeline.py
index 6b54ec10b66b0de8d2fbc95cad197564c7e8246f..d70a1b8cac550aac6518ffe3bb2b4e104818c1f9 100755
--- a/CEP/Pipeline/recipes/sip/bin/pulsar_pipeline.py
+++ b/CEP/Pipeline/recipes/sip/bin/pulsar_pipeline.py
@@ -34,33 +34,8 @@ class pulsar_pipeline(control):
 
     def __init__(self):
         super(pulsar_pipeline, self).__init__()
-        self.parset = parameterset()
         self.input_data = {}
         self.output_data = {}
-        self.parset_feedback_file = None
-
-
-    def go(self):
-        """
-        Read the parset-file that was given as input argument;
-        set jobname, and input/output data products before calling the
-        base-class's `go()` method.
-        """
-        try:
-            parset_file = os.path.abspath(self.inputs['args'][0])
-        except IndexError:
-            return self.usage()
-        self.parset.adoptFile(parset_file)
-        self.parset_feedback_file = parset_file + "_feedback"
-
-        # Set job-name to basename of parset-file w/o extension, if it's not
-        # set on the command-line with '-j' or '--job-name'
-        if not self.inputs.has_key('job_name'):
-            self.inputs['job_name'] = (
-                os.path.splitext(os.path.basename(parset_file))[0])
-                
-        # Call the base-class's `go()` method.
-        return super(pulsar_pipeline, self).go()
   
 
     def _get_io_product_specs(self):
@@ -120,6 +95,17 @@ class pulsar_pipeline(control):
         """
         # *********************************************************************
         # 1. Prepare phase, collect data from parset and input mapfiles.
+        #
+        # Note that PULP will read many of these fields directly. That makes
+        # the following fields, and possibly others, part of the API towards
+        # PULP:
+        #
+        # self.config
+        # self.logger
+        # self.input_data
+        # self.output_data
+        # self.parset_feedback_file
+        # self.job_dir
 
         # Get input/output-data products specifications.
         self._get_io_product_specs()
@@ -164,11 +150,29 @@ class pulsar_pipeline(control):
           
         if (not self.incoherentStokesEnabled):
           sys.argv.append("--noIS")       
+
+        # Tell PULP where to write the feedback to
+        self.parset_feedback_file =  "%s_feedback" % (self.parset_file,)
        
         # Run the pulsar pipeline
         self.logger.debug("Starting pulp with: " + join(sys.argv))
-        p = pulp.pulp(self)
-        return p.go()
+        p = pulp.pulp(self) # TODO: MUCK self to capture the API
+
+	# NOTE: PULP returns 0 on SUCCESS!!
+        if p.go():
+          self.logger.error("PULP did not succeed. Bailing out!")
+          return 0
+
+        # Read and forward the feedback
+        try:
+          metadata = parameterset(self.parset_feedback_file)
+        except IOError, e:
+          self.logger.error("Could not read feedback from %s: %s" % (metadata_file,e))
+          return 0
+
+        self.send_feedback_dataproducts(metadata)
+
+        return 1
 
     
 if __name__ == '__main__':
diff --git a/CEP/Pipeline/recipes/sip/bin/startPython.sh b/CEP/Pipeline/recipes/sip/bin/startPython.sh
index dd1fb545237af6c2f1fad935094c38b6bd4e9b45..0aed7151de359ced6ca908e7c1f0829bc8a48d2c 100755
--- a/CEP/Pipeline/recipes/sip/bin/startPython.sh
+++ b/CEP/Pipeline/recipes/sip/bin/startPython.sh
@@ -27,8 +27,7 @@ logFile=/opt/lofar/var/log/startPython.log
 
 usage()
 {
-  echo "Usage: $0 <pythonProgram> <parsetname> <MAC-Python-control-host> \\"
-  echo "         <MAC-Python-control-listener> <MAC-Python-control-server>"
+  echo "Usage: $0 <pythonProgram> <parsetname>"
   exit 1
 }
 
@@ -41,10 +40,9 @@ usage()
 
 pythonProgram="${1}"
 parsetFile="${2}"
-controlHost="${3}"
 
 echo "**** $(date) ****" >> ${logFile}
-echo "Executing: $0 ${pythonProgram} ${parsetFile} ${controlHost}" >> ${logFile}
+echo "Executing: $0 ${pythonProgram} ${parsetFile}" >> ${logFile}
 
 use_pulp="$(getparsetvalue $parsetFile "ObsSW.Observation.processSubtype")"
 if [ "${use_pulp}" == "Pulsar Pipeline" ]; then 
@@ -53,6 +51,9 @@ if [ "${use_pulp}" == "Pulsar Pipeline" ]; then
 fi
 echo "Initializing Lofar" >> ${logFile}
 use Lofar
+echo "Initializing QPID" >> ${logFile}
+# TODO: implement 'use Qpid'
+source /data/qpid/.profile || source /opt/cep/qpid/.profile || echo "Could NOT load qpid .profile" >> ${logFile}
 
 # Try to reset the environment based on a parset software version value
 
@@ -81,14 +82,14 @@ if [ -n "$debug" ]; then
   echo "PATH=${PATH}" >> ${logFile}
   echo "PYTHONPATH=${PYTHONPATH}" >> ${logFile}
   echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >> ${logFile}
-  echo "${pythonProgram} ${programOptions} ${parsetFile} ${controlHost}" \
+  echo "${pythonProgram} ${programOptions} ${parsetFile}" \
     >> ${logFile}
 fi
 
 # Start the Python program in the background. 
 # This script should return ASAP so that MAC can set the task to ACTIVE.
 # STDERR will be redirected to the log-file.
-${pythonProgram} ${programOptions} ${parsetFile} ${controlHost} \
+${pythonProgram} ${programOptions} ${parsetFile} \
     1> /dev/null 2>> ${logFile} &
 
 # Check if the Python program died early. If so, this indicates an error.
diff --git a/CEP/Pipeline/recipes/sip/master/deprecated/bbs.py b/CEP/Pipeline/recipes/sip/master/deprecated/bbs.py
index d1f4a665e4adf7aa7fb7b48f065c1f4f1fb3cbb6..491d7c0860d8b9bf9c6ade44a1a23ff021f1121b 100644
--- a/CEP/Pipeline/recipes/sip/master/deprecated/bbs.py
+++ b/CEP/Pipeline/recipes/sip/master/deprecated/bbs.py
@@ -196,7 +196,7 @@ class bbs(BaseRecipe):
             #                                         already available on disk.
             # ------------------------------------------------------------------
             self.logger.debug("Building VDS file describing data for BBS run")
-            vds_dir = tempfile.mkdtemp()
+            vds_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             vds_file = os.path.join(vds_dir, "bbs.gvds")
             combineproc = utilities.spawn_process(
                 [
@@ -344,7 +344,7 @@ class bbs(BaseRecipe):
         """
         env = utilities.read_initscript(self.logger, self.inputs['initscript'])
         self.logger.info("Running BBS GlobalControl")
-        working_dir = tempfile.mkdtemp()
+        working_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         with CatchLog4CPlus(
             working_dir,
             self.logger.name + ".GlobalControl",
diff --git a/CEP/Pipeline/recipes/sip/master/get_metadata.py b/CEP/Pipeline/recipes/sip/master/get_metadata.py
index e34b94e0fef44d725d7a0f97daf1881352bc72b0..8367f97d54f085013864e8636b025c914d41d3c6 100644
--- a/CEP/Pipeline/recipes/sip/master/get_metadata.py
+++ b/CEP/Pipeline/recipes/sip/master/get_metadata.py
@@ -25,7 +25,7 @@ class get_metadata(BaseRecipe, RemoteCommandRecipeMixIn):
     2. Load mapfiles
     3. call node side of the recipe
     4. validate performance
-    5. Create the parset-file and write it to disk.  
+    5. Create the parset and return it.
     
     **Command line arguments**
 
@@ -36,23 +36,17 @@ class get_metadata(BaseRecipe, RemoteCommandRecipeMixIn):
             '--product-type',
             help="Data product type",
         ),
-        'parset_file': ingredient.StringField(
-            '--parset-file',
-            help="Path to the output parset file"
-        ),
         'parset_prefix': ingredient.StringField(
             '--parset-prefix',
             help="Prefix for each key in the output parset file",
             default=''
         ),
-        'toplevel_meta_data_path': ingredient.StringField(
-            '--toplevel-meta-data',
-            help="Path to parset with toplevel meta information, default = ''",
-            default=''
-        )
     }
 
     outputs = {
+        'metadata': ingredient.ParsetField(
+            help="parset containing obtained metadata"
+        )
     }
     
     # List of valid data product types.
@@ -117,17 +111,11 @@ class get_metadata(BaseRecipe, RemoteCommandRecipeMixIn):
         data.save(args[0])
 
         # ********************************************************************
-        # 5. Create the parset-file and write it to disk.        
+        # 5. Create the parset-file and return it to the caller
         parset = parameterset()
         prefix = "Output_%s_" % product_type
         parset.replace('%snrOf%s' % (global_prefix, prefix), str(len(jobs)))
 
-        # If there is meta data to add from the toplevel script
-        pipeline_meta_parset_path = self.inputs['toplevel_meta_data_path']
-        if pipeline_meta_parset_path != "":
-            pipeline_meta_parset = parameterset(pipeline_meta_parset_path)
-            parset.adoptCollection(pipeline_meta_parset)
-
         prefix = global_prefix + prefix
         for idx, job in enumerate(jobs):
             self.logger.debug("job[%d].results = %s" % (idx, job.results))
@@ -140,16 +128,8 @@ class get_metadata(BaseRecipe, RemoteCommandRecipeMixIn):
             parset.adoptCollection(meta_data_parset,
                                    '%s[%d].' % (prefix, idx))
 
-        try:
-
-            create_directory(os.path.dirname(self.inputs['parset_file']))
-            parset.writeFile(self.inputs['parset_file'])
-            self.logger.info("Wrote meta data to: " + 
-                             self.inputs['parset_file'])
-        except RuntimeError, err:
-            self.logger.error("Failed to write meta-data: %s" % str(err))
-            return 1
-
+        # Return result to caller
+        self.outputs["metadata"] = parset
         return 0
 
 
diff --git a/CEP/Pipeline/recipes/sip/master/new_bbs.py b/CEP/Pipeline/recipes/sip/master/new_bbs.py
index 02b99cb80765a3535edf758280e1dd32c93f1710..acdaa5f073b70c4b9840c4a0a87eeca60b34c0ec 100644
--- a/CEP/Pipeline/recipes/sip/master/new_bbs.py
+++ b/CEP/Pipeline/recipes/sip/master/new_bbs.py
@@ -355,7 +355,7 @@ class new_bbs(BaseRecipe):
         code.
         """
         self.logger.info("Running BBS GlobalControl")
-        working_dir = tempfile.mkdtemp()
+        working_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         with CatchLog4CPlus(
             working_dir,
             self.logger.name + ".GlobalControl",
diff --git a/CEP/Pipeline/recipes/sip/master/setupparmdb.py b/CEP/Pipeline/recipes/sip/master/setupparmdb.py
index e887d33b1ddcdd3db8a9e5a7c51c0a5d1361a4cd..ad54b38277b6376bfa188372f50da38107aeaecb 100644
--- a/CEP/Pipeline/recipes/sip/master/setupparmdb.py
+++ b/CEP/Pipeline/recipes/sip/master/setupparmdb.py
@@ -90,7 +90,8 @@ class setupparmdb(BaseRecipe, RemoteCommandRecipeMixIn):
 
         # generate a temp dir
         pdbdir = tempfile.mkdtemp(
-            dir=self.config.get("layout", "job_directory")
+            dir=self.config.get("layout", "job_directory"),
+            suffix=".%s" % (os.path.basename(__file__),)
         )
         pdbfile = os.path.join(pdbdir, self.inputs['suffix'])
 
diff --git a/CEP/Pipeline/recipes/sip/nodes/bbs_reducer.py b/CEP/Pipeline/recipes/sip/nodes/bbs_reducer.py
index d327ae04c4d29a9f4b9e747632f8e7ad15940914..64e3bb9054fd2b2b5d92c631760c023a43f2706c 100644
--- a/CEP/Pipeline/recipes/sip/nodes/bbs_reducer.py
+++ b/CEP/Pipeline/recipes/sip/nodes/bbs_reducer.py
@@ -46,7 +46,7 @@ class bbs_reducer(LOFARnodeTCP):
                 return 1
 
             # Run bbs-reducer. Catch log output from bbs-reducer and stdout.
-            scratch_dir = mkdtemp()
+            scratch_dir = mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             try:
                 cmd = [executable,
                        "--parmdb=%s" % parmdb, 
diff --git a/CEP/Pipeline/recipes/sip/nodes/deprecated/bbs.py b/CEP/Pipeline/recipes/sip/nodes/deprecated/bbs.py
index 6fbaca14092d505d086a556fd5dd9f5309a35f34..8ab25875631e5686dbf826d0e5e6b0b753c9c2b1 100644
--- a/CEP/Pipeline/recipes/sip/nodes/deprecated/bbs.py
+++ b/CEP/Pipeline/recipes/sip/nodes/deprecated/bbs.py
@@ -66,7 +66,7 @@ class bbs(LOFARnodeTCP):
             #                                                     Run the kernel
             #               Catch & log output from the kernel logger and stdout
             # ------------------------------------------------------------------
-            working_dir = mkdtemp()
+            working_dir = mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             env = read_initscript(self.logger, initscript)
             try:
                 cmd = [executable, parset_filename, "0"]
diff --git a/CEP/Pipeline/recipes/sip/nodes/deprecated/cimager.py b/CEP/Pipeline/recipes/sip/nodes/deprecated/cimager.py
index 4b1d715c61f61c18b801399586793372f8e85181..278d47336c6a92541392e1bfbcb4ef7f3a6c99a3 100644
--- a/CEP/Pipeline/recipes/sip/nodes/deprecated/cimager.py
+++ b/CEP/Pipeline/recipes/sip/nodes/deprecated/cimager.py
@@ -47,7 +47,7 @@ class cimager(LOFARnodeTCP):
                     self.logger.info("Image already exists: aborting.")
                     return 0
             try:
-                working_dir = mkdtemp()
+                working_dir = mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
                 #   If a time range has been specified, copy that section of the
                 #                                  input MS and only image that.
diff --git a/CEP/Pipeline/recipes/sip/nodes/deprecated/demixing.py b/CEP/Pipeline/recipes/sip/nodes/deprecated/demixing.py
index c72a5cf9e8f49c8e1276964bd4f436f35884556a..cbd49e5a281b14cc6f0c89d7532f042d6ab3c8e4 100644
--- a/CEP/Pipeline/recipes/sip/nodes/deprecated/demixing.py
+++ b/CEP/Pipeline/recipes/sip/nodes/deprecated/demixing.py
@@ -54,7 +54,7 @@ class demixing(LOFARnodeTCP):
 
     def _execute(self, cmd):
         try:
-            temp_dir = tempfile.mkdtemp()
+            temp_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             with CatchLog4CPlus(temp_dir,
                                 self.logger.name,
                                 os.path.basename(cmd[0])
diff --git a/CEP/Pipeline/recipes/sip/nodes/dppp.py b/CEP/Pipeline/recipes/sip/nodes/dppp.py
index de369323e889d343b29f7e794720b3d590ef3079..f77761729c52edc1e978753bec84419e063d34b1 100644
--- a/CEP/Pipeline/recipes/sip/nodes/dppp.py
+++ b/CEP/Pipeline/recipes/sip/nodes/dppp.py
@@ -142,7 +142,7 @@ class dppp(LOFARnodeTCP):
                     temp_parset_filename
                 )
                 try:
-                    working_dir = tempfile.mkdtemp()
+                    working_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             # ****************************************************************
             # 6. Run ndppp
                     cmd = [executable, temp_parset_filename, '1']
diff --git a/CEP/Pipeline/recipes/sip/nodes/gainoutliercorrection.py b/CEP/Pipeline/recipes/sip/nodes/gainoutliercorrection.py
index 03ee5128f5900c996aa9e8756d7a13d8b08793f3..db263daa8594159aae108df39faa2d69b087b1bf 100644
--- a/CEP/Pipeline/recipes/sip/nodes/gainoutliercorrection.py
+++ b/CEP/Pipeline/recipes/sip/nodes/gainoutliercorrection.py
@@ -77,7 +77,7 @@ class gainoutliercorrection(LOFARnodeTCP):
         self.logger.info(
             "Using the gainoutlier correction based on parmexportcal")
         try:
-            temp_dir = tempfile.mkdtemp()
+            temp_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             with CatchLog4CPlus(
                 temp_dir,
                 self.logger.name + '.' + os.path.basename(infile),
diff --git a/CEP/Pipeline/recipes/sip/nodes/imager_finalize.py b/CEP/Pipeline/recipes/sip/nodes/imager_finalize.py
index 81cc87d795acaf5b07bfafa27684f3b6e1430cbe..a06849c3dbdadb36aba4ca6d5c901b9c40eeb9cd 100644
--- a/CEP/Pipeline/recipes/sip/nodes/imager_finalize.py
+++ b/CEP/Pipeline/recipes/sip/nodes/imager_finalize.py
@@ -116,7 +116,7 @@ class imager_finalize(LOFARnodeTCP):
                 os.unlink(fits_output)
 
             try:
-                temp_dir = tempfile.mkdtemp()
+                temp_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
                 with CatchLog4CPlus(temp_dir,
                     self.logger.name + '.' + os.path.basename(awimager_output),
                             "image2fits") as logger:
diff --git a/CEP/Pipeline/recipes/sip/nodes/new_bbs.py b/CEP/Pipeline/recipes/sip/nodes/new_bbs.py
index a0ee543182e7e52ddf4abd582fa7b5c0df8b5755..0123140135f7cb5329e7b693017b1ef69088fcd6 100644
--- a/CEP/Pipeline/recipes/sip/nodes/new_bbs.py
+++ b/CEP/Pipeline/recipes/sip/nodes/new_bbs.py
@@ -75,7 +75,7 @@ class new_bbs(LOFARnodeTCP):
             #                                                     Run the kernel
             #               Catch & log output from the kernel logger and stdout
             # ------------------------------------------------------------------
-            working_dir = mkdtemp()
+            working_dir = mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             try:
                 self.logger.info("******** {0}".format(open(parset_file).read()))
                 cmd = [executable, parset_file, "0"]
diff --git a/CEP/Pipeline/recipes/sip/nodes/rficonsole.py b/CEP/Pipeline/recipes/sip/nodes/rficonsole.py
index d9869abff65bbdb1049ff4244dc07d70d82163a0..ceecf728f5941a97ab1e0089ee4735ff201569bb 100644
--- a/CEP/Pipeline/recipes/sip/nodes/rficonsole.py
+++ b/CEP/Pipeline/recipes/sip/nodes/rficonsole.py
@@ -27,7 +27,7 @@ class rficonsole(LOFARnodeTCP):
                 if not os.access(executable, os.X_OK):
                     raise ExecutableMissing(executable)
 
-                working_dir = tempfile.mkdtemp(dir=wd)
+                working_dir = tempfile.mkdtemp(dir=wd,suffix=".%s" % (os.path.basename(__file__),))
                 cmd = [executable, "-j", str(nthreads)]
                 if strategy:
                     if os.path.exists(strategy):
diff --git a/CEP/Pipeline/recipes/sip/nodes/setupsourcedb.py b/CEP/Pipeline/recipes/sip/nodes/setupsourcedb.py
index ee35999e2d938e85f86acfab0991718ec62c5e32..af1212d13c4fae1f88da87dc5bf6e9b3668b3b1b 100644
--- a/CEP/Pipeline/recipes/sip/nodes/setupsourcedb.py
+++ b/CEP/Pipeline/recipes/sip/nodes/setupsourcedb.py
@@ -49,7 +49,7 @@ class setupsourcedb(LOFARnodeTCP):
             shutil.rmtree(skydb, ignore_errors=True)
 
             self.logger.info("Creating skymodel: %s" % (skydb))
-            scratch_dir = tempfile.mkdtemp()
+            scratch_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
             try:
                 cmd = [executable,
                        "in=%s" % catalogue,
diff --git a/CEP/Pipeline/recipes/sip/pipeline.cfg.in b/CEP/Pipeline/recipes/sip/pipeline.cfg.in
index 8732c7a30820b5cd5c51e3140dc170f37a663c5d..2b311047dd96f45bd74332b997240099414d4d28 100644
--- a/CEP/Pipeline/recipes/sip/pipeline.cfg.in
+++ b/CEP/Pipeline/recipes/sip/pipeline.cfg.in
@@ -23,3 +23,10 @@ engine_lpath = %(lofarroot)s/lib:%(casaroot)s/lib:%(pyraproot)s/lib:%(hdf5root)s
 [logging]
 log_file = %(runtime_directory)s/%(job_name)s/logs/%(start_time)s/pipeline.log
 xml_stat_file = %(runtime_directory)s/%(job_name)s/logs/%(start_time)s/statistics.xml
+
+[feedback]
+# Method of providing feedback to LOFAR.
+# Valid options:
+#    messagebus    Send feedback and status using LCS/MessageBus
+#    none          Do NOT send feedback and status
+method = messagebus
diff --git a/CEP/Pipeline/test/recipes/helpers/WritableParmDB_test.py b/CEP/Pipeline/test/recipes/helpers/WritableParmDB_test.py
index adc4651d8490ebe63b5b0abf7419c4f1f0cc1b57..6da1b92ed44e36fb3e52fb68db66df1fc959a8e9 100644
--- a/CEP/Pipeline/test/recipes/helpers/WritableParmDB_test.py
+++ b/CEP/Pipeline/test/recipes/helpers/WritableParmDB_test.py
@@ -28,7 +28,7 @@ class writableParmdbTest(unittest.TestCase):
         super(writableParmdbTest, self).__init__(arg)
 
     def setUp(self):
-        self.tempDir = tempfile.mkdtemp()
+        self.tempDir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         self.tempParmDB = os.path.join(self.tempDir, "parmDB")
         self.writable_parmdb = writableParmdbWrapper(self.tempParmDB)
 
diff --git a/CEP/Pipeline/test/recipes/master/copier_test.py b/CEP/Pipeline/test/recipes/master/copier_test.py
index 518445c1a1ea456b6b4c612b63352c2d8fc409d4..b94b35ce06cf6f1e68eb92cfe4eb8d3b639a78b6 100644
--- a/CEP/Pipeline/test/recipes/master/copier_test.py
+++ b/CEP/Pipeline/test/recipes/master/copier_test.py
@@ -33,10 +33,10 @@ class copierTest(unittest.TestCase):
 
     def setUp(self):
         self.imager_create_dbs = copierWrapper()
-        self.test_path = temp_path = tempfile.mkdtemp()
+        self.test_path = temp_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
         pass
 
     def test_validate_mapfiles_norename(self):
@@ -120,10 +120,10 @@ class MasterNodeInterfaceTest(unittest.TestCase):
         super(MasterNodeInterfaceTest, self).__init__(arg)
 
     def setUp(self):
-        self.test_path = temp_path = tempfile.mkdtemp()
+        self.test_path = temp_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
         pass
 
     def test__init__raise_exception(self):
diff --git a/CEP/Pipeline/test/recipes/master/imager_bbs_test.py b/CEP/Pipeline/test/recipes/master/imager_bbs_test.py
index 5bc5e2edea0b8304e6aeaf7db602c59efd408da3..d85e0d7c74b8a25c52361f5af8778e28dc1c0f64 100644
--- a/CEP/Pipeline/test/recipes/master/imager_bbs_test.py
+++ b/CEP/Pipeline/test/recipes/master/imager_bbs_test.py
@@ -35,10 +35,10 @@ class imager_bbsTest(unittest.TestCase):
         super(imager_bbsTest, self).__init__(arg)
 
     def setUp(self):
-        self.test_path = temp_path = tempfile.mkdtemp()
+        self.test_path = temp_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
         pass
 
     def test_constructor(self):
diff --git a/CEP/Pipeline/test/recipes/master/imager_create_dbs_test.py b/CEP/Pipeline/test/recipes/master/imager_create_dbs_test.py
index af56368efd08f4a05146e517ce0e93fe6ca8c623..ca5b75912416ef0123b1dfaf485658d36a620877 100644
--- a/CEP/Pipeline/test/recipes/master/imager_create_dbs_test.py
+++ b/CEP/Pipeline/test/recipes/master/imager_create_dbs_test.py
@@ -35,10 +35,10 @@ class imager_create_dbsTest(unittest.TestCase):
         super(imager_create_dbsTest, self).__init__(arg)
 
     def setUp(self):
-        self.test_path = temp_path = tempfile.mkdtemp()
+        self.test_path = temp_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
         pass
 
     def test_validate_input_data(self):
diff --git a/CEP/Pipeline/test/recipes/master/imager_prepare_test.py b/CEP/Pipeline/test/recipes/master/imager_prepare_test.py
index a4504406a2d623a0294d0f62cc036bc78aed9c76..5eb2c34067c9ba0f3b49ac51667d794e370fb669 100644
--- a/CEP/Pipeline/test/recipes/master/imager_prepare_test.py
+++ b/CEP/Pipeline/test/recipes/master/imager_prepare_test.py
@@ -33,10 +33,10 @@ class imager_prepareTest(unittest.TestCase):
         super(imager_prepareTest, self).__init__(arg)
 
     def setUp(self):
-        self.test_path = temp_path = tempfile.mkdtemp()
+        self.test_path = temp_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
         pass
 
     def test_create_input_map_for_sbgroup_single_ms(self):
diff --git a/CEP/Pipeline/test/recipes/nodes/copier_test.py b/CEP/Pipeline/test/recipes/nodes/copier_test.py
index d72935df9584d0461aec7cc1de44f25b591d7fdd..fe67f3444fb0a67c210b07748c0d52463b9c9f2f 100644
--- a/CEP/Pipeline/test/recipes/nodes/copier_test.py
+++ b/CEP/Pipeline/test/recipes/nodes/copier_test.py
@@ -38,7 +38,7 @@ class copierTest(unittest.TestCase):
 
     def tearDown(self):
         pass
-        #shutil.rmtree(self.test_path)
+        shutil.rmtree(self.test_path)
 
 #    # refactor of copier means this test is not needed anymore. Comment out for 
 #    # now
@@ -49,7 +49,7 @@ class copierTest(unittest.TestCase):
 #        rsync return value
 #        
 #        """
-#        temp_dir = tempfile.mkdtemp()
+#        temp_dir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 #        path_to_unowned_dir = "/home/klijntest/testdir"  #
 #        file_to_copy = open(os.path.join(temp_dir, "test.txt"), 'w')
 #        file_to_copy.close()
diff --git a/CEP/Pipeline/test/recipes/nodes/gainoutliercorrection_test.py b/CEP/Pipeline/test/recipes/nodes/gainoutliercorrection_test.py
index 60b446fd50913463b85b5820b0cfd66d37f19a96..014fce027a85e125bf6d2cb80be6ce8704dedd84 100644
--- a/CEP/Pipeline/test/recipes/nodes/gainoutliercorrection_test.py
+++ b/CEP/Pipeline/test/recipes/nodes/gainoutliercorrection_test.py
@@ -30,7 +30,7 @@ class GainOutlierDetectionTest(unittest.TestCase):
         super(GainOutlierDetectionTest, self).__init__(arg)
 
     def setUp(self):
-        self.tempDir = tempfile.mkdtemp()
+        self.tempDir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
 
     def tearDown(self):
diff --git a/CEP/Pipeline/test/recipes/nodes/imager_bbs_test.py b/CEP/Pipeline/test/recipes/nodes/imager_bbs_test.py
index 9a17e1faf8b8dde5b0baea98b62b6831bef3602b..cb67c88998a4d59e4933e6c08ec88e735f321111 100644
--- a/CEP/Pipeline/test/recipes/nodes/imager_bbs_test.py
+++ b/CEP/Pipeline/test/recipes/nodes/imager_bbs_test.py
@@ -33,9 +33,10 @@ class imager_bbsTest(unittest.TestCase):
         super(imager_bbsTest, self).__init__(arg)
 
     def setUp(self):
-        self.test_path = tempfile.mkdtemp()
+        self.test_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
+        shutil.rmtree(self.test_path)
         pass
 
     def test_constructor(self):
diff --git a/CEP/Pipeline/test/recipes/nodes/imager_create_dbs_test.py b/CEP/Pipeline/test/recipes/nodes/imager_create_dbs_test.py
index bce1838dae1be5b2a20c6acb58003b1e5b1651ef..004cd81676eb1ad04fda512aec92d10cd995b22c 100644
--- a/CEP/Pipeline/test/recipes/nodes/imager_create_dbs_test.py
+++ b/CEP/Pipeline/test/recipes/nodes/imager_create_dbs_test.py
@@ -46,9 +46,10 @@ class ImagerCreateDBsTest(unittest.TestCase):
 
     def setUp(self):
         self.imager_create_dbs = ImagerCreateDBsTestWrapper()
-        self.test_path = tempfile.mkdtemp()
+        self.test_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
+        shutil.rmtree(self.test_path)
         pass
 
 # New version of gsm: Quick fix to allow tests to succeed
diff --git a/CEP/Pipeline/test/recipes/nodes/imager_prepare_test.py b/CEP/Pipeline/test/recipes/nodes/imager_prepare_test.py
index 85cc51057fc6a076ac197c9f24be3297c16fc756..35e61a823acbc5d50635faae89d9228840efb14b 100644
--- a/CEP/Pipeline/test/recipes/nodes/imager_prepare_test.py
+++ b/CEP/Pipeline/test/recipes/nodes/imager_prepare_test.py
@@ -40,9 +40,10 @@ class ImagerPrepareTest(unittest.TestCase):
 
     def setUp(self):
         self.ImagerPrepareTestWrapper = ImagerPrepareTestWrapper()
-        self.test_path = tempfile.mkdtemp()
+        self.test_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
 
     def tearDown(self):
+        shutil.rmtree(self.test_path)
         pass
 
     def test__copy_input_files_multi_file(self):
@@ -97,7 +98,7 @@ class ImagerPrepareTest(unittest.TestCase):
         """
         working_dir = ""
 
-        time_slice_dir_path = tempfile.mkdtemp()
+        time_slice_dir_path = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         slices_per_image = 2
         input_map = [("lce072", "test_file_path1"),
                          ("lce072", "test_file_path2"),
@@ -145,6 +146,8 @@ class ImagerPrepareTest(unittest.TestCase):
                 "time_slice_1.dppp.ms.ndppp.par")).read())
         self.assertTrue(parset_2_output == parset_2_content_expected,
                 "\n{0} != \n{1}".format(parset_2_output, parset_2_content_expected))
+        
+        shutil.rmtree(time_slice_dir_path)
 
 
 if __name__ == "__main__":
diff --git a/CEP/Pipeline/test/regression_tests/regression_test_runner.sh b/CEP/Pipeline/test/regression_tests/regression_test_runner.sh
index 5f439bfbe9cf73553688830a5423f6bd6e4723c1..6bd86a79813ddcbb5a3ce39ca575f0a4f40f5948 100755
--- a/CEP/Pipeline/test/regression_tests/regression_test_runner.sh
+++ b/CEP/Pipeline/test/regression_tests/regression_test_runner.sh
@@ -88,6 +88,7 @@ mkdir -p $"$WORKSPACE/installed/var/run/pipeline"
 use Lofar               # this is a weak point in the script we should be able to run without
 use Pythonlibs
 . $"$WORKSPACE/lofarinit.sh"  
+. /data/qpid/.profile
 
 # *****************************************************
 # 3) Clear old data:
@@ -150,6 +151,12 @@ sed -i  $"s|input_path2_placeholder|$WORKING_DIR/input_data|g" $"$WORKING_DIR/$P
 sed -i  $"s|output_path1_placeholder|$WORKING_DIR/output_data|g" $"$WORKING_DIR/$PIPELINE.parset"
 sed -i  $"s|output_path2_placeholder|$WORKING_DIR/output_data|g" $"$WORKING_DIR/$PIPELINE.parset"
 
+# setup the qpid environment (is a no-op if qpid is not installed)
+source $WORKSPACE/bin/MessageFuncs.sh
+create_queue lofar.task.feedback.state
+create_queue lofar.task.feedback.dataproducts
+create_queue lofar.task.feedback.processing
+
 # *********************************************************************
 # 5) Run the pipeline
 echo "Run the pipeline"
diff --git a/CEP/Pipeline/test/support/data_map_test.py b/CEP/Pipeline/test/support/data_map_test.py
index 17ad4c607ebb537455828066eae6b26a19135a75..5321e766e946f50cf085f57133a76e5b8c808cc0 100644
--- a/CEP/Pipeline/test/support/data_map_test.py
+++ b/CEP/Pipeline/test/support/data_map_test.py
@@ -33,7 +33,7 @@ class DataMapTest(unittest.TestCase):
         """
         Create scratch directory and create required input files in there.
         """
-        self.tmpdir = tempfile.mkdtemp()
+        self.tmpdir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         self.old_style_map_file = self._create_old_style_map_file()
         self.new_style_map_file = self._create_new_style_map_file()
         self.syntax_error_map_file = self._create_syntax_error_map_file()
@@ -155,7 +155,7 @@ class MultiDataMapTest(unittest.TestCase):
         """
         Create scratch directory and create required input files in there.
         """
-        self.tmpdir = tempfile.mkdtemp()
+        self.tmpdir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         self.old_style_map_file = self._create_old_style_map_file()
         self.new_style_map_file = self._create_new_style_map_file()
         self.syntax_error_map_file = self._create_syntax_error_map_file()
@@ -290,7 +290,7 @@ class HelperFunctionDataMapTest(unittest.TestCase):
         """
         Create scratch directory and create required input files in there.
         """
-        self.tmpdir = tempfile.mkdtemp()
+        self.tmpdir = tempfile.mkdtemp(suffix=".%s" % (os.path.basename(__file__),))
         self.old_style_map_file = self._create_old_style_map_file()
         self.new_style_map_file = self._create_new_style_map_file()
         self.syntax_error_map_file = self._create_syntax_error_map_file()
diff --git a/CMake/FindQPID.cmake b/CMake/FindQPID.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..75343f7a49d055cc3b6cd043e8873ae307532a98
--- /dev/null
+++ b/CMake/FindQPID.cmake
@@ -0,0 +1,63 @@
+# - Try to find QPID: Apache's implementation of the AMPQ protocol
+# Variables used by this module:
+#  QPID_ROOT_DIR     - QPID root directory
+# Variables defined by this module:
+#  QPID_FOUND        - system has QPID
+#  QPID_INCLUDE_DIR  - the QPID include directory (cached)
+#  QPID_INCLUDE_DIRS - the QPID include directories
+#                        (identical to QPID_INCLUDE_DIR)
+#  QPID_LIBRARY      - the QPID library (cached)
+#  QPID_LIBRARIES    - the QPID libraries
+#                        (identical to QPID_LIBRARY)
+#  QPID_RECEIVE_EXECUTABLE - the full path of qpid-receive
+#  QPID_SEND_EXECUTABLE    - the full path of qpid-send
+#  QPID_STAT_EXECUTABLE    - the full path of qpid-stat
+
+# Copyright (C) 2015
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id$
+
+if(NOT QPID_FOUND)
+
+  find_path(QPID_INCLUDE_DIR qpid/messaging/Connection.h
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES include)
+  find_library(QPID_MESSAGING_LIBRARY qpidmessaging
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES lib)
+  find_library(QPID_TYPES_LIBRARY qpidtypes
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES lib)
+
+  find_program(QPID_RECEIVE_EXECUTABLE qpid-receive
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES bin)
+  find_program(QPID_SEND_EXECUTABLE qpid-send
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES bin)
+  find_program(QPID_STAT_EXECUTABLE qpid-stat
+    HINTS ${QPID_ROOT_DIR} PATH_SUFFIXES bin)
+
+  set(QPID_LIBRARY ${QPID_MESSAGING_LIBRARY} ${QPID_TYPES_LIBRARY})
+
+  mark_as_advanced(QPID_INCLUDE_DIR QPID_LIBRARY)
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(QPID DEFAULT_MSG
+    QPID_LIBRARY QPID_INCLUDE_DIR)
+
+  set(QPID_INCLUDE_DIRS ${QPID_INCLUDE_DIR})
+  set(QPID_LIBRARIES ${QPID_LIBRARY})
+
+endif(NOT QPID_FOUND)
diff --git a/CMake/FindUUID.cmake b/CMake/FindUUID.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7fdac87a2aae3c3e6ce19e92ae5e3b67db80426f
--- /dev/null
+++ b/CMake/FindUUID.cmake
@@ -0,0 +1,49 @@
+# - Try to find libuuid: A library to generate UUIDs
+# Variables used by this module:
+#  UUID_ROOT_DIR     - QPID root directory
+# Variables defined by this module:
+#  UUID_FOUND        - system has UUID
+#  UUID_INCLUDE_DIR  - the UUID include directory (cached)
+#  UUID_INCLUDE_DIRS - the UUID include directories
+#                        (identical to UUID_INCLUDE_DIR)
+#  UUID_LIBRARY      - the UUID library (cached)
+#  UUID_LIBRARIES    - the UUID libraries
+#                        (identical to UUID_LIBRARY)
+
+# Copyright (C) 2015
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id$
+
+if(NOT UUID_FOUND)
+
+  find_path(UUID_INCLUDE_DIR uuid/uuid.h
+    HINTS ${UUID_ROOT_DIR} PATH_SUFFIXES include)
+  find_library(UUID_LIBRARY uuid
+    HINTS ${UUID_ROOT_DIR} PATH_SUFFIXES lib)
+
+  mark_as_advanced(UUID_INCLUDE_DIR UUID_LIBRARY)
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(UUID DEFAULT_MSG
+    UUID_LIBRARY UUID_INCLUDE_DIR)
+
+  set(UUID_INCLUDE_DIRS ${UUID_INCLUDE_DIR})
+  set(UUID_LIBRARIES ${UUID_LIBRARY})
+
+endif(NOT UUID_FOUND)
diff --git a/CMake/LofarPackageList.cmake b/CMake/LofarPackageList.cmake
index 309fc1ec0154caf538f729a922cc901665504d6d..ef3efc6d6b27c56120e115193dc0ed89140db356 100644
--- a/CMake/LofarPackageList.cmake
+++ b/CMake/LofarPackageList.cmake
@@ -1,7 +1,7 @@
 # - Create for each LOFAR package a variable containing the absolute path to
 # its source directory. 
 #
-# Generated by gen_LofarPackageList_cmake.sh at Tue Nov  4 09:18:08 CET 2014
+# Generated by gen_LofarPackageList_cmake.sh at Tue Jan 27 14:42:15 UTC 2015
 #
 #                      ---- DO NOT EDIT ----
 #
@@ -14,14 +14,6 @@
 #
 if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(LOFAR_PACKAGE_LIST_INCLUDED TRUE)
-  set(BBSKernel_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSKernel)
-  set(BBSControl_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSControl)
-  set(ExpIon_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/ExpIon)
-  set(pystationresponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/pystationresponse)
-  set(pyselfcal_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/pyselfcal)
-  set(BBSTools_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSTools)
-  set(ElementResponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/ElementResponse)
-  set(StationResponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/StationResponse)
   set(Calibration_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration)
   set(DP3_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/DP3)
   set(GSM_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/GSM)
@@ -33,6 +25,14 @@ if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(PyBDSM_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/PyBDSM)
   set(pyparmdb_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/pyparmdb)
   set(LAPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/LAPS)
+  set(BBSKernel_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSKernel)
+  set(BBSControl_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSControl)
+  set(ExpIon_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/ExpIon)
+  set(pystationresponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/pystationresponse)
+  set(pyselfcal_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/pyselfcal)
+  set(BBSTools_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/BBSTools)
+  set(ElementResponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/ElementResponse)
+  set(StationResponse_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration/StationResponse)
   set(DPPP_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/DP3/DPPP)
   set(TestDynDPPP_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/DP3/TestDynDPPP)
   set(PythonDPPP_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/DP3/PythonDPPP)
@@ -62,6 +62,8 @@ if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(ApplCommon_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/ApplCommon)
   set(Blob_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/Blob)
   set(Common_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/Common)
+  set(MessageBus_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/MessageBus)
+  set(MessageDaemons_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/MessageDaemons)
   set(MSLofar_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/MSLofar)
   set(pyparameterset_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/pyparameterset)
   set(pytools_SOURCE_DIR ${CMAKE_SOURCE_DIR}/LCS/pytools)
@@ -131,6 +133,7 @@ if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(Scheduler_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/Scheduler)
   set(jOTDB3_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/OTB/jOTDB3)
   set(OTB-Java_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/OTB/OTB)
+  set(SAS_Feedback_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/Feedback_Service)
   set(CCU_MAC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SubSystems/CCU_MAC)
   set(LCU_MAC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SubSystems/LCU_MAC)
   set(MCU_MAC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SubSystems/MCU_MAC)
diff --git a/CMake/PythonInstall.cmake b/CMake/PythonInstall.cmake
index b62fff3eaeb9e95fbbb98cac8a867add35615a35..ee464b09ab63ec17eb438588391b1c45b8ce7e32 100644
--- a/CMake/PythonInstall.cmake
+++ b/CMake/PythonInstall.cmake
@@ -83,14 +83,15 @@ macro(python_install)
     install(FILES ${_py} DESTINATION ${_inst_dir}/${_py_path})
     if(USE_PYTHON_COMPILATION)
       set(_py_code
-        "import py_compile"
-        "print('-- Byte-compiling: ${_inst_dir}/${_py}')"
-        "py_compile.compile('${_inst_dir}/${_py}', doraise=True)")
+        "import py_compile, os"
+        "destdir = os.environ.get('DESTDIR','')"
+        "print('-- Byte-compiling: %s${_inst_dir}/${_py}' % destdir)"
+        "py_compile.compile('%s${DESTDIR}${_inst_dir}/${_py}' % destdir, doraise=True)")
       install(CODE 
         "execute_process(COMMAND ${PYTHON_EXECUTABLE} -c \"${_py_code}\"
                        RESULT_VARIABLE _result)
        if(NOT _result EQUAL 0)
-         message(FATAL_ERROR \"Byte-compilation FAILED: ${_inst_dir}/${_py}\")
+         message(FATAL_ERROR \"Byte-compilation FAILED: \$ENV{DESTDIR}${_inst_dir}/${_py}\")
        endif(NOT _result EQUAL 0)")
     endif(USE_PYTHON_COMPILATION)
   endforeach(_py ${_py_files})
@@ -104,7 +105,7 @@ macro(python_install)
       "${PYTHON_BUILD_DIR}${_init_dir}/__init__.py")
     install(CODE 
       "execute_process(COMMAND ${CMAKE_COMMAND} -E touch 
-        \"${PYTHON_INSTALL_DIR}${_init_dir}/__init__.py\")")
+        \"\$ENV{DESTDIR}${PYTHON_INSTALL_DIR}${_init_dir}/__init__.py\")")
   endforeach(_dir ${_dir_list})
 
 endmacro(python_install)
diff --git a/CMake/TODO b/CMake/TODO
index 166c32bb70051053fb57bdd3a027622ed56c7107..79d64c794158a0b26c3d8fa1e091eb2ca9e188b0 100644
--- a/CMake/TODO
+++ b/CMake/TODO
@@ -30,9 +30,6 @@
   Currently, python sources are compiled during install. What's worse, 
   compilation failures are not reported, and no non-zero exit status is set.
 
-* Python byte-code compilation fails during install when using DESTDIR option
-  to specify a different install directory.
-
 * Add option DEPENDS to lofar_add_library() and lofar_add_executable(), which
   can be used to add additional dependencies. This is mainly useful for
   custom targets, because "normal" target dependencies are already handled by
diff --git a/CMake/gen_LofarPackageList_cmake.sh b/CMake/gen_LofarPackageList_cmake.sh
index ea5ceb395c6c1985e2dec9b838d28dda25edc42e..e1eed1e579f6cd0fc4681df91fcdedeae9f3a60a 100755
--- a/CMake/gen_LofarPackageList_cmake.sh
+++ b/CMake/gen_LofarPackageList_cmake.sh
@@ -28,13 +28,13 @@
 
 # Get the LOFAR source directory root
 script_dir=$(cd $(dirname $0) && pwd)
-lofar_root=$(echo $script_dir | sed -e "s|\(.*/LOFAR\)/.*|\1|")
+lofar_root=$script_dir/..
 
 # Just a safety net; this script must be inside the LOFAR tree.
-if test "$script_dir" = "$lofar_root"; then
-  echo "ERROR: $(basename $0) MUST be inside the LOFAR source tree!"
-  exit 1
-fi
+#if test "$script_dir" = "$lofar_root"; then
+#  echo "ERROR: $(basename $0) MUST be inside the LOFAR source tree!"
+#  exit 1
+#fi
 
 # Open the output file
 exec 3> $script_dir/LofarPackageList.cmake
diff --git a/CMake/variants/variants.RS005C b/CMake/variants/variants.RS005C
index 34cff54b9059065e815d1923e096fa3b89e75007..d655bb6d000a5d7c7756acc6cfaaafc6ff60df66 100644
--- a/CMake/variants/variants.RS005C
+++ b/CMake/variants/variants.RS005C
@@ -20,6 +20,9 @@ set(MATLAB_ROOT_DIR /usr/local/matlab-2008a)
 # Path to JAVA
 set(ENV{JAVA_HOME} /usr/local/jdk1.6.0_29)
 
+# Path to Qpid
+set(QPID_ROOT_DIR /opt/qpid)
+
 # Ignore warnings matching the following pattern(s)
 set(CTEST_CUSTOM_WARNING_EXCEPTION
   "/boost/date_time/time_facet.hpp:[0-9]+: warning: unused parameter"
diff --git a/CMake/variants/variants.cbt001 b/CMake/variants/variants.cbt001
index 979c48fb3ed81fd935f06dba833783b9c37f85ab..f79a4cd2a4a46f82fc50a0dfb8ada617fe50aab8 100644
--- a/CMake/variants/variants.cbt001
+++ b/CMake/variants/variants.cbt001
@@ -14,6 +14,7 @@ option(USE_CUDA      "Use CUDA"      ON)
 set(CASACORE_ROOT_DIR /localhome/lofar/casacore-1.7.0)
 set(MPI_ROOT_DIR /opt/openmpi)
 set(DAL_ROOT_DIR /localhome/lofar/DAL)
+set(QPID_ROOT_DIR /localhome/lofar/qpid)
 #set(VALGRIND_ROOT_DIR       /globalhome/lofarsystem/cobalt-root)
 
 #set(GNU_C         /globalhome/amesfoort/cbtroot/bin/gcc-4.8)
diff --git a/CMake/variants/variants.kis001 b/CMake/variants/variants.kis001
index be8b6c767181ceda9beb9baacefdaaeee0ddecfc..2c6781578ce25f71252d0cf83084750dbe151db0 100644
--- a/CMake/variants/variants.kis001
+++ b/CMake/variants/variants.kis001
@@ -5,6 +5,7 @@ set(ENV{JAVA_HOME} /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0)
 #set(PVSS_ROOT_DIR /opt/pvss/pvss2_v3.7)
 set(PVSS_ROOT_DIR /opt/WinCC_OA/3.10)
 set(LOG4CPLUS_ROOT_DIR "/usr/local/log4cplus")
+set(QPID_ROOT_DIR /opt/qpid)
 
 set(CTEST_CUSTOM_WARNING_EXCEPTION 
   "/boost/date_time/time_facet.hpp:[0-9]+: warning: unused parameter"
diff --git a/CMake/variants/variants.lhn001 b/CMake/variants/variants.lhn001
index 1b2617ece3ef679fa088e55693233bd4b90b93f7..ab8bf36cc2f9b427241c1be2ba46d61b16093faf 100644
--- a/CMake/variants/variants.lhn001
+++ b/CMake/variants/variants.lhn001
@@ -4,6 +4,8 @@ set(DAL_ROOT_DIR /opt/cep/dal/current)
 
 set(PYRAP_ROOT_DIR /opt/cep/pyrap)
 
+set(QPID_ROOT_DIR /opt/cep/qpid)
+
 set(WCSLIB_ROOT_DIR /opt/cep/wcslib)
 
 set(LOG4CXX_ROOT_DIR /opt/cep/LofIm/external/log4cxx)
diff --git a/CMake/variants/variants.lhn002 b/CMake/variants/variants.lhn002
deleted file mode 100644
index 1b2617ece3ef679fa088e55693233bd4b90b93f7..0000000000000000000000000000000000000000
--- a/CMake/variants/variants.lhn002
+++ /dev/null
@@ -1,21 +0,0 @@
-set(CASACORE_ROOT_DIR /opt/cep/casacore)
-set(CASAREST_ROOT_DIR /opt/cep/casarest)
-set(DAL_ROOT_DIR /opt/cep/dal/current)
-
-set(PYRAP_ROOT_DIR /opt/cep/pyrap)
-
-set(WCSLIB_ROOT_DIR /opt/cep/wcslib)
-
-set(LOG4CXX_ROOT_DIR /opt/cep/LofIm/external/log4cxx)
-set(LOG4CPLUS_ROOT_DIR /opt/cep/lofar/external/log4cplus)
-
-#set(ENV{JAVA_HOME} /usr/lib/jvm/java-1.5.0-sun)
-
-set(CTEST_CUSTOM_WARNING_EXCEPTION
-  "/log4cxx/helpers/objectptr.h:[0-9]+: warning: base class"
-  "/log4cxx/helpers/objectptr.h:[0-9]+: warning: dereferencing type-punned pointer"
-)
-
-# Drop the now default C++ debug compile flag -D_GLIBCXX_DEBUG, because Python
-# (or Boost.Python) barfs on it (glibc detected: python free(): invalid pointer)
-set(GNU_CXX_FLAGS_DEBUG  "-g")
diff --git a/CMake/variants/variants.lhn002 b/CMake/variants/variants.lhn002
new file mode 120000
index 0000000000000000000000000000000000000000..92890f596ce0939cfafa22bdd2337914338bdd0a
--- /dev/null
+++ b/CMake/variants/variants.lhn002
@@ -0,0 +1 @@
+variants.lhn001
\ No newline at end of file
diff --git a/CMake/variants/variants.locus102 b/CMake/variants/variants.locus102
index ec7471769b4689da707dea90afe625bd4ea0a0a6..7f28ed3d162f7f7f5f0e11e47a37b0d221f63dac 100644
--- a/CMake/variants/variants.locus102
+++ b/CMake/variants/variants.locus102
@@ -3,6 +3,7 @@ option(BUILD_SHARED_LIBS        "Build shared libraries"      ON)
 set(CASACORE_ROOT_DIR /opt/cep/casacore)
 set(CASAREST_ROOT_DIR /opt/cep/casarest)
 set(DAL_ROOT_DIR /opt/cep/dal/current)
+set(QPID_ROOT_DIR /data/qpid)
 
 set(PYRAP_ROOT_DIR /opt/cep/pyrap)
 
diff --git a/CMake/variants/variants.sas099 b/CMake/variants/variants.sas099
index b3e304975595f76dd4e1cb386490bcd6f4f20c4a..15a7c9289aa6fea7fb9e334aaa1f4a9eed6690a1 100644
--- a/CMake/variants/variants.sas099
+++ b/CMake/variants/variants.sas099
@@ -1,5 +1,6 @@
 set(ENV{JAVA_HOME} /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0)
 set(PVSS_ROOT_DIR /opt/pvss/pvss2_v3.7)
+set(QPID_ROOT_DIR /opt/qpid)
 
 set(CTEST_CUSTOM_WARNING_EXCEPTION 
   "/boost/date_time/time_facet.hpp:[0-9]+: warning: unused parameter"
diff --git a/LCS/CMakeLists.txt b/LCS/CMakeLists.txt
index a973e43d1cdc30d44029f40a0cf0ca93e39fe254..eaf721a214020ba8ed6cfc3118664179f15592c1 100644
--- a/LCS/CMakeLists.txt
+++ b/LCS/CMakeLists.txt
@@ -5,6 +5,8 @@ lofar_add_package(AMC)            # Astronomical Measures Conversions
 lofar_add_package(ApplCommon)     # Application common stuff
 lofar_add_package(Blob)           # Binary Large Objects
 lofar_add_package(Common)         # Common stuff
+lofar_add_package(MessageBus)     # Support for QPID message exchange
+lofar_add_package(MessageDaemons) # Daemons to do message routing and handling
 lofar_add_package(MSLofar)        # MS for LOFAR based on ICD
 lofar_add_package(pyparameterset) # Python ParameterSet bindings
 lofar_add_package(pytools)        # Python tools
diff --git a/LCS/MessageBus/CMakeLists.txt b/LCS/MessageBus/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3c6af3f13d0d9e7ee2e1d315057ee705657dfd80
--- /dev/null
+++ b/LCS/MessageBus/CMakeLists.txt
@@ -0,0 +1,10 @@
+# $Id$
+
+lofar_package(MessageBus 1.0 DEPENDS Common)
+
+include(LofarFindPackage)
+lofar_find_package(QPID)
+
+add_subdirectory(include/MessageBus)
+add_subdirectory(src)
+add_subdirectory(test)
diff --git a/LCS/MessageBus/data/feedback_dp_44833.txt b/LCS/MessageBus/data/feedback_dp_44833.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e6a7627720e1a4fcd441bdf2695137b23c75118f
--- /dev/null
+++ b/LCS/MessageBus/data/feedback_dp_44833.txt
@@ -0,0 +1,40 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>lofar.observation.start</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>mySubSystem</name>
+         <user>user</user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>some test message</summary>
+      </source>
+      <ids>
+         <momid>12345</momid>
+         <sasid>44883</sasid>
+      </ids>
+   </header>
+   <payload>
+Observation.Correlator.channelWidth=3051.7578125
+Observation.Correlator.channelsPerSubband=64
+Observation.Correlator.integrationInterval=1.00139008
+Observation.DataProducts.Output_Correlated_[0].SAP=0
+Observation.DataProducts.Output_Correlated_[0].centralFrequency=115039062.500000
+Observation.DataProducts.Output_Correlated_[0].channelWidth=3051.757812
+Observation.DataProducts.Output_Correlated_[0].channelsPerSubband=64
+Observation.DataProducts.Output_Correlated_[0].duration=119.165420
+Observation.DataProducts.Output_Correlated_[0].fileFormat=AIPS++/CASA
+Observation.DataProducts.Output_Correlated_[0].filename=L257915_SAP000_SB000_uv.MS
+Observation.DataProducts.Output_Correlated_[0].integrationInterval=1.001390
+Observation.DataProducts.Output_Correlated_[0].location=locus001:/data/L257915/
+Observation.DataProducts.Output_Correlated_[0].percentageWritten=100
+Observation.DataProducts.Output_Correlated_[0].size=268083200
+Observation.DataProducts.Output_Correlated_[0].startTime=2015-01-15 09:32:09
+Observation.DataProducts.Output_Correlated_[0].stationSubband=77
+Observation.DataProducts.Output_Correlated_[0].subband=0
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/feedback_dp_empty.txt b/LCS/MessageBus/data/feedback_dp_empty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c8bb9a44d8a26a87fea2ea595b24daeec526bc1
--- /dev/null
+++ b/LCS/MessageBus/data/feedback_dp_empty.txt
@@ -0,0 +1,23 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>lofar.observation.start</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>mySubSystem</name>
+         <user>user</user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>some test message</summary>
+      </source>
+      <ids>
+         <momid>12345</momid>
+         <sasid>44883</sasid>
+      </ids>
+   </header>
+   <payload>
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/feedback_dp_no_ids.txt b/LCS/MessageBus/data/feedback_dp_no_ids.txt
new file mode 100644
index 0000000000000000000000000000000000000000..101d55bcf0b4bc087b7e4cb04a5b1d330ece29ab
--- /dev/null
+++ b/LCS/MessageBus/data/feedback_dp_no_ids.txt
@@ -0,0 +1,40 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>lofar.observation.start</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>mySubSystem</name>
+         <user>user</user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>some test message</summary>
+      </source>
+      <ids>
+         <momid></momid>
+         <sasid></sasid>
+      </ids>
+   </header>
+   <payload>
+Observation.Correlator.channelWidth=3051.7578125
+Observation.Correlator.channelsPerSubband=64
+Observation.Correlator.integrationInterval=1.00139008
+Observation.DataProducts.Output_Correlated_[0].SAP=0
+Observation.DataProducts.Output_Correlated_[0].centralFrequency=115039062.500000
+Observation.DataProducts.Output_Correlated_[0].channelWidth=3051.757812
+Observation.DataProducts.Output_Correlated_[0].channelsPerSubband=64
+Observation.DataProducts.Output_Correlated_[0].duration=119.165420
+Observation.DataProducts.Output_Correlated_[0].fileFormat=AIPS++/CASA
+Observation.DataProducts.Output_Correlated_[0].filename=L257915_SAP000_SB000_uv.MS
+Observation.DataProducts.Output_Correlated_[0].integrationInterval=1.001390
+Observation.DataProducts.Output_Correlated_[0].location=locus001:/data/L257915/
+Observation.DataProducts.Output_Correlated_[0].percentageWritten=100
+Observation.DataProducts.Output_Correlated_[0].size=268083200
+Observation.DataProducts.Output_Correlated_[0].startTime=2015-01-15 09:32:09
+Observation.DataProducts.Output_Correlated_[0].stationSubband=77
+Observation.DataProducts.Output_Correlated_[0].subband=0
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/feedback_dp_xml_error.txt b/LCS/MessageBus/data/feedback_dp_xml_error.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e7ebf05ed491bfb68e6db14b3476647223bca9c
--- /dev/null
+++ b/LCS/MessageBus/data/feedback_dp_xml_error.txt
@@ -0,0 +1,40 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>lofar.observation.start</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>mySubSystem</name>
+         <user>user</user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>some test message</summary>
+      </source>
+      <ids>
+         <momid>12345</momid>
+         <sasid>44883</sasid>
+      </ids>
+   </header>
+   <payload_illegal_tag>
+Observation.Correlator.channelWidth=3051.7578125
+Observation.Correlator.channelsPerSubband=64
+Observation.Correlator.integrationInterval=1.00139008
+Observation.DataProducts.Output_Correlated_[0].SAP=0
+Observation.DataProducts.Output_Correlated_[0].centralFrequency=115039062.500000
+Observation.DataProducts.Output_Correlated_[0].channelWidth=3051.757812
+Observation.DataProducts.Output_Correlated_[0].channelsPerSubband=64
+Observation.DataProducts.Output_Correlated_[0].duration=119.165420
+Observation.DataProducts.Output_Correlated_[0].fileFormat=AIPS++/CASA
+Observation.DataProducts.Output_Correlated_[0].filename=L257915_SAP000_SB000_uv.MS
+Observation.DataProducts.Output_Correlated_[0].integrationInterval=1.001390
+Observation.DataProducts.Output_Correlated_[0].location=locus001:/data/L257915/
+Observation.DataProducts.Output_Correlated_[0].percentageWritten=100
+Observation.DataProducts.Output_Correlated_[0].size=268083200
+Observation.DataProducts.Output_Correlated_[0].startTime=2015-01-15 09:32:09
+Observation.DataProducts.Output_Correlated_[0].stationSubband=77
+Observation.DataProducts.Output_Correlated_[0].subband=0
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/task_spec_system_78958.txt b/LCS/MessageBus/data/task_spec_system_78958.txt
new file mode 100644
index 0000000000000000000000000000000000000000..04fa392015cd5eb81a5d8dbe1f4fc5107505ec0c
--- /dev/null
+++ b/LCS/MessageBus/data/task_spec_system_78958.txt
@@ -0,0 +1,308 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.specification.system</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>LOFAR.MACScheduler</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary></summary>
+      </source>
+      <ids>
+         <momid>180785</momid>
+         <sasid>78958</sasid>
+      </ids>
+   </header>
+   <payload>
+Clock160.channelWidth=610.3515625
+Clock160.samplesPerSecond=155648
+Clock160.subbandWidth=156.250
+Clock160.systemClock=160
+Clock200.channelWidth=762.939453125
+Clock200.samplesPerSecond=196608
+Clock200.subbandWidth=195.3125
+Clock200.systemClock=200
+ObsSW.Observation.AnaBeam[0].angle1=0.5141401557033334
+ObsSW.Observation.AnaBeam[0].angle2=1.085720371180154
+ObsSW.Observation.AnaBeam[0].directionType=J2000
+ObsSW.Observation.AnaBeam[0].duration=1920
+ObsSW.Observation.AnaBeam[0].rank=1
+ObsSW.Observation.AnaBeam[0].startTime=
+ObsSW.Observation.AnaBeam[0].target=
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle1=0.514140156
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle2=1.085720371
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].dispersionMeasure=1.23456789
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle1=0.403039045
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle2=1.07461926
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].dispersionMeasure=1.1223344
+ObsSW.Observation.Beam[0].angle1=0.5141401557033334
+ObsSW.Observation.Beam[0].angle2=1.085720371180154
+ObsSW.Observation.Beam[0].directionType=J2000
+ObsSW.Observation.Beam[0].duration=1920
+ObsSW.Observation.Beam[0].momID=180786
+ObsSW.Observation.Beam[0].nrTabRings=3
+ObsSW.Observation.Beam[0].nrTiedArrayBeams=2
+ObsSW.Observation.Beam[0].startTime=
+ObsSW.Observation.Beam[0].subbandList=[200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443]
+ObsSW.Observation.Beam[0].tabRingSize=4.0
+ObsSW.Observation.Beam[0].target=BF Target
+ObsSW.Observation.Campaign.CO_I="Vermaas-Scientist,  Nico"
+ObsSW.Observation.Campaign.PI="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.contact="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.name="test-lofar"
+ObsSW.Observation.Campaign.title="test-lofar"
+ObsSW.Observation.DataProducts.Input_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Input_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Input_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Input_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Input_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Input_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_Correlated.namemask=
+ObsSW.Observation.DataProducts.Input_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Input_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Input_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Input_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Input_SkyImage.skip=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_Correlated.archived=false
+ObsSW.Observation.DataProducts.Output_Correlated.deleted=false
+ObsSW.Observation.DataProducts.Output_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Output_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Output_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Output_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Output_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Output_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Correlated.namemask=
+ObsSW.Observation.DataProducts.Output_Correlated.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Correlated.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.archived=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.deleted=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.retentiontime=14
+ObsSW.Observation.DataProducts.Output_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.archived=false
+ObsSW.Observation.DataProducts.Output_Pulsar.deleted=false
+ObsSW.Observation.DataProducts.Output_Pulsar.dirmask=
+ObsSW.Observation.DataProducts.Output_Pulsar.enabled=false
+ObsSW.Observation.DataProducts.Output_Pulsar.filenames=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.identifications=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.locations=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.namemask=
+ObsSW.Observation.DataProducts.Output_Pulsar.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Pulsar.skip=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.archived=false
+ObsSW.Observation.DataProducts.Output_SkyImage.deleted=false
+ObsSW.Observation.DataProducts.Output_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Output_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Output_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Output_SkyImage.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.retentiontime=14
+ObsSW.Observation.DataProducts.Output_SkyImage.skip=[]
+ObsSW.Observation.Dataslots.DataslotInfo.DataslotList=[]
+ObsSW.Observation.Dataslots.DataslotInfo.RSPBoardList=[]
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.nrChannelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.nrChannelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.integrationTime=1.0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrChannelsPerSubband=16
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.blockSize=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctClocks=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._executable=CN_Processing
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._nodes=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._startstopType=bgl
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc.workingdir=/opt/lofar/bin/
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.extraInfo=["OLAP","PIC"]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.procesOrder=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.processes=["CorrProc"]
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.channelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.channelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.integrationTime=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrChannelsPerSubband=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.PencilInfo.flysEye=false
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl._hostname=CCU001
+ObsSW.Observation.ObservationControl.OnlineControl.applOrder=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.applications=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionHost=lhn001.cep2.lofar
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionProgram=/opt/cep/pyautoplot/bin/launch-msplots.sh
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.CoincidenceTime=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.DoDirectionFit=none
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MaxFitVariance=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MinElevation=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.NoCoincChann=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.ParamExtension=
+ObsSW.Observation.ObservationControl.StationControl._hostname=[DE602]
+ObsSW.Observation.ObservationControl.StationControl.tbbPiggybackAllowed=true
+ObsSW.Observation.ObservationControl._hostname=MCU001
+ObsSW.Observation.ObservationControl.heartbeatInterval=10
+ObsSW.Observation.Scheduler.contactEmail=
+ObsSW.Observation.Scheduler.contactName=
+ObsSW.Observation.Scheduler.contactPhone=
+ObsSW.Observation.Scheduler.firstPossibleDay=0
+ObsSW.Observation.Scheduler.fixedDay=false
+ObsSW.Observation.Scheduler.fixedTime=false
+ObsSW.Observation.Scheduler.lastPossibleDay=0
+ObsSW.Observation.Scheduler.late=false
+ObsSW.Observation.Scheduler.nightTimeWeightFactor=0
+ObsSW.Observation.Scheduler.predMaxTimeDif=
+ObsSW.Observation.Scheduler.predMinTimeDif=
+ObsSW.Observation.Scheduler.predecessors=[]
+ObsSW.Observation.Scheduler.priority=0.0
+ObsSW.Observation.Scheduler.reason=
+ObsSW.Observation.Scheduler.referenceFrame=0
+ObsSW.Observation.Scheduler.reservation=0
+ObsSW.Observation.Scheduler.storageSelectionMode=1
+ObsSW.Observation.Scheduler.taskDuration=1920
+ObsSW.Observation.Scheduler.taskID=0
+ObsSW.Observation.Scheduler.taskName=My Trigger Obs
+ObsSW.Observation.Scheduler.taskType=0
+ObsSW.Observation.Scheduler.windowMaximumTime=
+ObsSW.Observation.Scheduler.windowMinimumTime=
+ObsSW.Observation.TBB.TBBsetting.RCUs=[]
+ObsSW.Observation.TBB.TBBsetting.baselevel=127
+ObsSW.Observation.TBB.TBBsetting.filter=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.operatingMode=1
+ObsSW.Observation.TBB.TBBsetting.startlevel=7
+ObsSW.Observation.TBB.TBBsetting.stoplevel=7
+ObsSW.Observation.TBB.TBBsetting.subbandList=[]
+ObsSW.Observation.TBB.TBBsetting.triggerMode=1
+ObsSW.Observation.TBB.TBBsetting.window=1M
+ObsSW.Observation.VirtualInstrument.minimalNrStations=1
+ObsSW.Observation.VirtualInstrument.partitionList=["R00"]
+ObsSW.Observation.VirtualInstrument.stationList=[DE602]
+ObsSW.Observation.VirtualInstrument.stationSet=Custom
+ObsSW.Observation.antennaArray=HBA
+ObsSW.Observation.antennaSet=HBA_ZERO
+ObsSW.Observation.bandFilter=HBA_110_190
+ObsSW.Observation.channelsPerSubband=16
+ObsSW.Observation.claimPeriod=25
+ObsSW.Observation.clockMode=<<Clock200
+ObsSW.Observation.momID=180785
+ObsSW.Observation.nrAnaBeams=1
+ObsSW.Observation.nrBeams=1
+ObsSW.Observation.nrBitsPerSample=16
+ObsSW.Observation.nrTBBSettings=0
+ObsSW.Observation.originID=78795
+ObsSW.Observation.otdbID=78958
+ObsSW.Observation.preparePeriod=25
+ObsSW.Observation.processSubtype=Beam Observation
+ObsSW.Observation.processType=Observation
+ObsSW.Observation.sampleClock=200
+ObsSW.Observation.startTime=2015-02-04 11:27:00
+ObsSW.Observation.stopTime=2015-02-04 12:12:12
+ObsSW.Observation.strategy=default
+ObsSW.Observation.topologyID=
+Version.number=28583
+_DPname=LOFAR_ObsSW_TempObs0001
+prefix=LOFAR.
+
+   </payload>
+</message>
\ No newline at end of file
diff --git a/LCS/MessageBus/data/task_spec_system_empty.txt b/LCS/MessageBus/data/task_spec_system_empty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..03504e63c63421be3960efdd089cb666558a4a62
--- /dev/null
+++ b/LCS/MessageBus/data/task_spec_system_empty.txt
@@ -0,0 +1,23 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.specification.system</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>LOFAR.MACScheduler</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary></summary>
+      </source>
+      <ids>
+         <momid>180785</momid>
+         <sasid>78958</sasid>
+      </ids>
+   </header>
+   <payload>
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/task_spec_system_no_ids.txt b/LCS/MessageBus/data/task_spec_system_no_ids.txt
new file mode 100644
index 0000000000000000000000000000000000000000..edf31e7e7e59af0994dcc96293eea33e63ddbb96
--- /dev/null
+++ b/LCS/MessageBus/data/task_spec_system_no_ids.txt
@@ -0,0 +1,308 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.specification.system</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>LOFAR.MACScheduler</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary></summary>
+      </source>
+      <ids>
+         <momid></momid>
+         <sasid></sasid>
+      </ids>
+   </header>
+   <payload>
+Clock160.channelWidth=610.3515625
+Clock160.samplesPerSecond=155648
+Clock160.subbandWidth=156.250
+Clock160.systemClock=160
+Clock200.channelWidth=762.939453125
+Clock200.samplesPerSecond=196608
+Clock200.subbandWidth=195.3125
+Clock200.systemClock=200
+ObsSW.Observation.AnaBeam[0].angle1=0.5141401557033334
+ObsSW.Observation.AnaBeam[0].angle2=1.085720371180154
+ObsSW.Observation.AnaBeam[0].directionType=J2000
+ObsSW.Observation.AnaBeam[0].duration=1920
+ObsSW.Observation.AnaBeam[0].rank=1
+ObsSW.Observation.AnaBeam[0].startTime=
+ObsSW.Observation.AnaBeam[0].target=
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle1=0.514140156
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle2=1.085720371
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].dispersionMeasure=1.23456789
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle1=0.403039045
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle2=1.07461926
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].dispersionMeasure=1.1223344
+ObsSW.Observation.Beam[0].angle1=0.5141401557033334
+ObsSW.Observation.Beam[0].angle2=1.085720371180154
+ObsSW.Observation.Beam[0].directionType=J2000
+ObsSW.Observation.Beam[0].duration=1920
+ObsSW.Observation.Beam[0].momID=180786
+ObsSW.Observation.Beam[0].nrTabRings=3
+ObsSW.Observation.Beam[0].nrTiedArrayBeams=2
+ObsSW.Observation.Beam[0].startTime=
+ObsSW.Observation.Beam[0].subbandList=[200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443]
+ObsSW.Observation.Beam[0].tabRingSize=4.0
+ObsSW.Observation.Beam[0].target=BF Target
+ObsSW.Observation.Campaign.CO_I="Vermaas-Scientist,  Nico"
+ObsSW.Observation.Campaign.PI="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.contact="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.name="test-lofar"
+ObsSW.Observation.Campaign.title="test-lofar"
+ObsSW.Observation.DataProducts.Input_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Input_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Input_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Input_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Input_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Input_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_Correlated.namemask=
+ObsSW.Observation.DataProducts.Input_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Input_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Input_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Input_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Input_SkyImage.skip=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_Correlated.archived=false
+ObsSW.Observation.DataProducts.Output_Correlated.deleted=false
+ObsSW.Observation.DataProducts.Output_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Output_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Output_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Output_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Output_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Output_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Correlated.namemask=
+ObsSW.Observation.DataProducts.Output_Correlated.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Correlated.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.archived=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.deleted=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.retentiontime=14
+ObsSW.Observation.DataProducts.Output_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.archived=false
+ObsSW.Observation.DataProducts.Output_Pulsar.deleted=false
+ObsSW.Observation.DataProducts.Output_Pulsar.dirmask=
+ObsSW.Observation.DataProducts.Output_Pulsar.enabled=false
+ObsSW.Observation.DataProducts.Output_Pulsar.filenames=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.identifications=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.locations=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.namemask=
+ObsSW.Observation.DataProducts.Output_Pulsar.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Pulsar.skip=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.archived=false
+ObsSW.Observation.DataProducts.Output_SkyImage.deleted=false
+ObsSW.Observation.DataProducts.Output_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Output_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Output_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Output_SkyImage.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.retentiontime=14
+ObsSW.Observation.DataProducts.Output_SkyImage.skip=[]
+ObsSW.Observation.Dataslots.DataslotInfo.DataslotList=[]
+ObsSW.Observation.Dataslots.DataslotInfo.RSPBoardList=[]
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.nrChannelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.nrChannelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.integrationTime=1.0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrChannelsPerSubband=16
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.blockSize=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctClocks=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._executable=CN_Processing
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._nodes=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._startstopType=bgl
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc.workingdir=/opt/lofar/bin/
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.extraInfo=["OLAP","PIC"]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.procesOrder=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.processes=["CorrProc"]
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.channelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.channelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.integrationTime=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrChannelsPerSubband=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.PencilInfo.flysEye=false
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl._hostname=CCU001
+ObsSW.Observation.ObservationControl.OnlineControl.applOrder=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.applications=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionHost=lhn001.cep2.lofar
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionProgram=/opt/cep/pyautoplot/bin/launch-msplots.sh
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.CoincidenceTime=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.DoDirectionFit=none
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MaxFitVariance=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MinElevation=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.NoCoincChann=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.ParamExtension=
+ObsSW.Observation.ObservationControl.StationControl._hostname=[DE602]
+ObsSW.Observation.ObservationControl.StationControl.tbbPiggybackAllowed=true
+ObsSW.Observation.ObservationControl._hostname=MCU001
+ObsSW.Observation.ObservationControl.heartbeatInterval=10
+ObsSW.Observation.Scheduler.contactEmail=
+ObsSW.Observation.Scheduler.contactName=
+ObsSW.Observation.Scheduler.contactPhone=
+ObsSW.Observation.Scheduler.firstPossibleDay=0
+ObsSW.Observation.Scheduler.fixedDay=false
+ObsSW.Observation.Scheduler.fixedTime=false
+ObsSW.Observation.Scheduler.lastPossibleDay=0
+ObsSW.Observation.Scheduler.late=false
+ObsSW.Observation.Scheduler.nightTimeWeightFactor=0
+ObsSW.Observation.Scheduler.predMaxTimeDif=
+ObsSW.Observation.Scheduler.predMinTimeDif=
+ObsSW.Observation.Scheduler.predecessors=[]
+ObsSW.Observation.Scheduler.priority=0.0
+ObsSW.Observation.Scheduler.reason=
+ObsSW.Observation.Scheduler.referenceFrame=0
+ObsSW.Observation.Scheduler.reservation=0
+ObsSW.Observation.Scheduler.storageSelectionMode=1
+ObsSW.Observation.Scheduler.taskDuration=1920
+ObsSW.Observation.Scheduler.taskID=0
+ObsSW.Observation.Scheduler.taskName=My Trigger Obs
+ObsSW.Observation.Scheduler.taskType=0
+ObsSW.Observation.Scheduler.windowMaximumTime=
+ObsSW.Observation.Scheduler.windowMinimumTime=
+ObsSW.Observation.TBB.TBBsetting.RCUs=[]
+ObsSW.Observation.TBB.TBBsetting.baselevel=127
+ObsSW.Observation.TBB.TBBsetting.filter=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.operatingMode=1
+ObsSW.Observation.TBB.TBBsetting.startlevel=7
+ObsSW.Observation.TBB.TBBsetting.stoplevel=7
+ObsSW.Observation.TBB.TBBsetting.subbandList=[]
+ObsSW.Observation.TBB.TBBsetting.triggerMode=1
+ObsSW.Observation.TBB.TBBsetting.window=1M
+ObsSW.Observation.VirtualInstrument.minimalNrStations=1
+ObsSW.Observation.VirtualInstrument.partitionList=["R00"]
+ObsSW.Observation.VirtualInstrument.stationList=[DE602]
+ObsSW.Observation.VirtualInstrument.stationSet=Custom
+ObsSW.Observation.antennaArray=HBA
+ObsSW.Observation.antennaSet=HBA_ZERO
+ObsSW.Observation.bandFilter=HBA_110_190
+ObsSW.Observation.channelsPerSubband=16
+ObsSW.Observation.claimPeriod=25
+ObsSW.Observation.clockMode=<<Clock200
+ObsSW.Observation.momID=180785
+ObsSW.Observation.nrAnaBeams=1
+ObsSW.Observation.nrBeams=1
+ObsSW.Observation.nrBitsPerSample=16
+ObsSW.Observation.nrTBBSettings=0
+ObsSW.Observation.originID=78795
+ObsSW.Observation.otdbID=78958
+ObsSW.Observation.preparePeriod=25
+ObsSW.Observation.processSubtype=Beam Observation
+ObsSW.Observation.processType=Observation
+ObsSW.Observation.sampleClock=200
+ObsSW.Observation.startTime=2015-02-04 11:27:00
+ObsSW.Observation.stopTime=2015-02-04 12:12:12
+ObsSW.Observation.strategy=default
+ObsSW.Observation.topologyID=
+Version.number=28583
+_DPname=LOFAR_ObsSW_TempObs0001
+prefix=LOFAR.
+
+   </payload>
+</message>
diff --git a/LCS/MessageBus/data/task_spec_system_xml_error.txt b/LCS/MessageBus/data/task_spec_system_xml_error.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7db2d5a631ae5c68d2c3ffbc85bdc97a4f3846ef
--- /dev/null
+++ b/LCS/MessageBus/data/task_spec_system_xml_error.txt
@@ -0,0 +1,308 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.specification.system</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>LOFAR.MACScheduler</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary></summary>
+      </source>
+      <ids>
+         <momid>180785</momid>
+         <sasid>78958</sasid>
+      </ids>
+   </header>
+   <wrong_payload_tag>
+Clock160.channelWidth=610.3515625
+Clock160.samplesPerSecond=155648
+Clock160.subbandWidth=156.250
+Clock160.systemClock=160
+Clock200.channelWidth=762.939453125
+Clock200.samplesPerSecond=196608
+Clock200.subbandWidth=195.3125
+Clock200.systemClock=200
+ObsSW.Observation.AnaBeam[0].angle1=0.5141401557033334
+ObsSW.Observation.AnaBeam[0].angle2=1.085720371180154
+ObsSW.Observation.AnaBeam[0].directionType=J2000
+ObsSW.Observation.AnaBeam[0].duration=1920
+ObsSW.Observation.AnaBeam[0].rank=1
+ObsSW.Observation.AnaBeam[0].startTime=
+ObsSW.Observation.AnaBeam[0].target=
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle1=0.514140156
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].angle2=1.085720371
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[0].dispersionMeasure=1.23456789
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle1=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].absoluteAngle2=0
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle1=0.403039045
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].angle2=1.07461926
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].coherent=true
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].directionType=J2000
+ObsSW.Observation.Beam[0].TiedArrayBeam[1].dispersionMeasure=1.1223344
+ObsSW.Observation.Beam[0].angle1=0.5141401557033334
+ObsSW.Observation.Beam[0].angle2=1.085720371180154
+ObsSW.Observation.Beam[0].directionType=J2000
+ObsSW.Observation.Beam[0].duration=1920
+ObsSW.Observation.Beam[0].momID=180786
+ObsSW.Observation.Beam[0].nrTabRings=3
+ObsSW.Observation.Beam[0].nrTiedArrayBeams=2
+ObsSW.Observation.Beam[0].startTime=
+ObsSW.Observation.Beam[0].subbandList=[200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443]
+ObsSW.Observation.Beam[0].tabRingSize=4.0
+ObsSW.Observation.Beam[0].target=BF Target
+ObsSW.Observation.Campaign.CO_I="Vermaas-Scientist,  Nico"
+ObsSW.Observation.Campaign.PI="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.contact="Verhoef, Ir. Bastiaan"
+ObsSW.Observation.Campaign.name="test-lofar"
+ObsSW.Observation.Campaign.title="test-lofar"
+ObsSW.Observation.DataProducts.Input_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Input_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Input_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Input_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Input_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Input_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_Correlated.namemask=
+ObsSW.Observation.DataProducts.Input_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.enabled=false
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Input_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Input_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Input_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Input_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Input_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Input_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Input_SkyImage.skip=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_CoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_CoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_CoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_CoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_CoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_Correlated.archived=false
+ObsSW.Observation.DataProducts.Output_Correlated.deleted=false
+ObsSW.Observation.DataProducts.Output_Correlated.dirmask=
+ObsSW.Observation.DataProducts.Output_Correlated.enabled=false
+ObsSW.Observation.DataProducts.Output_Correlated.filenames=[]
+ObsSW.Observation.DataProducts.Output_Correlated.identifications=[]
+ObsSW.Observation.DataProducts.Output_Correlated.locations=[]
+ObsSW.Observation.DataProducts.Output_Correlated.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Correlated.namemask=
+ObsSW.Observation.DataProducts.Output_Correlated.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Correlated.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Correlated.skip=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.archived=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.deleted=false
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.dirmask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.enabled=true
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.filenames=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.identifications=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.locations=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.namemask=
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.retentiontime=14
+ObsSW.Observation.DataProducts.Output_IncoherentStokes.skip=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.archived=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.deleted=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.dirmask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.enabled=false
+ObsSW.Observation.DataProducts.Output_InstrumentModel.filenames=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.identifications=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.locations=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.namemask=
+ObsSW.Observation.DataProducts.Output_InstrumentModel.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_InstrumentModel.retentiontime=14
+ObsSW.Observation.DataProducts.Output_InstrumentModel.skip=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.archived=false
+ObsSW.Observation.DataProducts.Output_Pulsar.deleted=false
+ObsSW.Observation.DataProducts.Output_Pulsar.dirmask=
+ObsSW.Observation.DataProducts.Output_Pulsar.enabled=false
+ObsSW.Observation.DataProducts.Output_Pulsar.filenames=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.identifications=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.locations=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.namemask=
+ObsSW.Observation.DataProducts.Output_Pulsar.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_Pulsar.retentiontime=14
+ObsSW.Observation.DataProducts.Output_Pulsar.skip=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.archived=false
+ObsSW.Observation.DataProducts.Output_SkyImage.deleted=false
+ObsSW.Observation.DataProducts.Output_SkyImage.dirmask=
+ObsSW.Observation.DataProducts.Output_SkyImage.enabled=false
+ObsSW.Observation.DataProducts.Output_SkyImage.filenames=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.identifications=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.locations=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.mountpoints=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.namemask=
+ObsSW.Observation.DataProducts.Output_SkyImage.percentageWritten=[]
+ObsSW.Observation.DataProducts.Output_SkyImage.retentiontime=14
+ObsSW.Observation.DataProducts.Output_SkyImage.skip=[]
+ObsSW.Observation.Dataslots.DataslotInfo.DataslotList=[]
+ObsSW.Observation.Dataslots.DataslotInfo.RSPBoardList=[]
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.nrChannelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.nrChannelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.BeamFormer.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.integrationTime=1.0
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.Correlator.nrChannelsPerSubband=16
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.blockSize=1
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.correctClocks=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.Cobalt.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._executable=CN_Processing
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._nodes=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc._startstopType=bgl
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.CorrProc.workingdir=/opt/lofar/bin/
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl._hostname=bgstfen
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.extraInfo=["OLAP","PIC"]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.procesOrder=[]
+ObsSW.Observation.ObservationControl.OnlineControl.CorrAppl.processes=["CorrProc"]
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.channelsPerSubband=0
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.subbandsPerFile=243
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.timeIntegrationFactor=15
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_CoherentStokes.which=I
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.channelsPerSubband=2
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.subbandsPerFile=241
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.timeIntegrationFactor=17
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.CNProc_IncoherentStokes.which=IQUV
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.integrationTime=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrBlocksPerIntegration=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.Correlator.nrChannelsPerSubband=1
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.PencilInfo.flysEye=false
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.coherentDedisperseChannels=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.correctBandPass=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.delayCompensation=true
+ObsSW.Observation.ObservationControl.OnlineControl.OLAP.realTime=true
+ObsSW.Observation.ObservationControl.OnlineControl._hostname=CCU001
+ObsSW.Observation.ObservationControl.OnlineControl.applOrder=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.applications=["CorrAppl"]
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionHost=lhn001.cep2.lofar
+ObsSW.Observation.ObservationControl.OnlineControl.inspectionProgram=/opt/cep/pyautoplot/bin/launch-msplots.sh
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.CoincidenceTime=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.DoDirectionFit=none
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MaxFitVariance=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.MinElevation=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.NoCoincChann=0
+ObsSW.Observation.ObservationControl.StationControl.TBBControl.ParamExtension=
+ObsSW.Observation.ObservationControl.StationControl._hostname=[DE602]
+ObsSW.Observation.ObservationControl.StationControl.tbbPiggybackAllowed=true
+ObsSW.Observation.ObservationControl._hostname=MCU001
+ObsSW.Observation.ObservationControl.heartbeatInterval=10
+ObsSW.Observation.Scheduler.contactEmail=
+ObsSW.Observation.Scheduler.contactName=
+ObsSW.Observation.Scheduler.contactPhone=
+ObsSW.Observation.Scheduler.firstPossibleDay=0
+ObsSW.Observation.Scheduler.fixedDay=false
+ObsSW.Observation.Scheduler.fixedTime=false
+ObsSW.Observation.Scheduler.lastPossibleDay=0
+ObsSW.Observation.Scheduler.late=false
+ObsSW.Observation.Scheduler.nightTimeWeightFactor=0
+ObsSW.Observation.Scheduler.predMaxTimeDif=
+ObsSW.Observation.Scheduler.predMinTimeDif=
+ObsSW.Observation.Scheduler.predecessors=[]
+ObsSW.Observation.Scheduler.priority=0.0
+ObsSW.Observation.Scheduler.reason=
+ObsSW.Observation.Scheduler.referenceFrame=0
+ObsSW.Observation.Scheduler.reservation=0
+ObsSW.Observation.Scheduler.storageSelectionMode=1
+ObsSW.Observation.Scheduler.taskDuration=1920
+ObsSW.Observation.Scheduler.taskID=0
+ObsSW.Observation.Scheduler.taskName=My Trigger Obs
+ObsSW.Observation.Scheduler.taskType=0
+ObsSW.Observation.Scheduler.windowMaximumTime=
+ObsSW.Observation.Scheduler.windowMinimumTime=
+ObsSW.Observation.TBB.TBBsetting.RCUs=[]
+ObsSW.Observation.TBB.TBBsetting.baselevel=127
+ObsSW.Observation.TBB.TBBsetting.filter=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter0_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff0=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff1=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff2=0
+ObsSW.Observation.TBB.TBBsetting.filter1_coeff3=0
+ObsSW.Observation.TBB.TBBsetting.operatingMode=1
+ObsSW.Observation.TBB.TBBsetting.startlevel=7
+ObsSW.Observation.TBB.TBBsetting.stoplevel=7
+ObsSW.Observation.TBB.TBBsetting.subbandList=[]
+ObsSW.Observation.TBB.TBBsetting.triggerMode=1
+ObsSW.Observation.TBB.TBBsetting.window=1M
+ObsSW.Observation.VirtualInstrument.minimalNrStations=1
+ObsSW.Observation.VirtualInstrument.partitionList=["R00"]
+ObsSW.Observation.VirtualInstrument.stationList=[DE602]
+ObsSW.Observation.VirtualInstrument.stationSet=Custom
+ObsSW.Observation.antennaArray=HBA
+ObsSW.Observation.antennaSet=HBA_ZERO
+ObsSW.Observation.bandFilter=HBA_110_190
+ObsSW.Observation.channelsPerSubband=16
+ObsSW.Observation.claimPeriod=25
+ObsSW.Observation.clockMode=<<Clock200
+ObsSW.Observation.momID=180785
+ObsSW.Observation.nrAnaBeams=1
+ObsSW.Observation.nrBeams=1
+ObsSW.Observation.nrBitsPerSample=16
+ObsSW.Observation.nrTBBSettings=0
+ObsSW.Observation.originID=78795
+ObsSW.Observation.otdbID=78958
+ObsSW.Observation.preparePeriod=25
+ObsSW.Observation.processSubtype=Beam Observation
+ObsSW.Observation.processType=Observation
+ObsSW.Observation.sampleClock=200
+ObsSW.Observation.startTime=2015-02-04 11:27:00
+ObsSW.Observation.stopTime=2015-02-04 12:12:12
+ObsSW.Observation.strategy=default
+ObsSW.Observation.topologyID=
+Version.number=28583
+_DPname=LOFAR_ObsSW_TempObs0001
+prefix=LOFAR.
+
+   </payload>
+</message>
diff --git a/LCS/MessageBus/include/MessageBus/CMakeLists.txt b/LCS/MessageBus/include/MessageBus/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1e71faa1a0f684b4f4911acf23d82d5c5f708723
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/CMakeLists.txt
@@ -0,0 +1,13 @@
+# $Id$
+
+# Create symbolic link to include directory.
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}/include/${PACKAGE_NAME})
+
+# Install header files.
+install(FILES
+  MsgBus.h
+  DESTINATION include/${PACKAGE_NAME})
+
+add_subdirectory(Protocols)
diff --git a/LCS/MessageBus/include/MessageBus/Message.h b/LCS/MessageBus/include/MessageBus/Message.h
new file mode 100644
index 0000000000000000000000000000000000000000..1117ac5545c76d88e1bcbc1d10339ac3ab214120
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Message.h
@@ -0,0 +1,130 @@
+//# Message.h: Wrapper for messages to be exchanged using QPID.
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_MESSAGE_H
+#define LOFAR_MESSAGEBUS_MESSAGE_H
+
+#ifdef HAVE_QPID
+#include <qpid/messaging/Message.h>
+#include <qpid/types/Variant.h>
+
+#include <string>
+#include <ostream>
+
+namespace LOFAR {
+
+// Name of the system sending these messages
+static const std::string system = "LOFAR";
+
+// Version of the header we write
+static const std::string headerVersion = "1.0.0";
+
+class Message
+{
+public:
+  // Construct a message
+  Message() {};
+
+  // With header info
+  Message(
+    // Name of the service or process producing this message
+    const std::string &from,
+
+    // End-user responsible for this request (if applicable)
+    const std::string &forUser,
+
+    // Human-readable summary describing this request
+    const std::string &summary,
+
+    // Protocol of the contents of the message
+    const std::string &protocol,
+
+    // Version of the protocol we're using to describe the payload
+    const std::string &protocolVersion,
+
+    // momID of the information (if available)
+    const std::string &momID,
+
+    // sasID of the information (if available)
+    const std::string &sasID
+  );
+
+  // Parse a message
+  Message(const qpid::messaging::Message qpidMsg) : itsQpidMsg(qpidMsg) {};
+
+  // Read a message from disk (header + payload)
+  Message(const std::string &rawContent);
+
+  // Set the payload, supporting various types
+  void setXMLPayload (const std::string                &payload);
+  void setTXTPayload (const std::string                &payload);
+  void setMapPayload (const qpid::types::Variant::Map  &payload);
+  void setListPayload(const qpid::types::Variant::List &payload);
+
+  virtual ~Message();
+
+  // Return properties of the constructed or received message
+  std::string system() const		  { return (getXMLvalue("message.header.system")); }
+  std::string headerVersion() const   { return (getXMLvalue("message.header.version")); }
+  std::string protocol() const		  { return (getXMLvalue("message.header.protocol.name")); }
+  std::string protocolVersion() const { return (getXMLvalue("message.header.protocol.version")); }
+  std::string from() const			  { return (getXMLvalue("message.header.source.name")); }
+  std::string forUser() const		  { return (getXMLvalue("message.header.source.user")); }
+  std::string uuid() const			  { return (getXMLvalue("message.header.source.uuid")); }
+  std::string summary() const		  { return (getXMLvalue("message.header.source.summary")); }
+  std::string timestamp() const		  { return (getXMLvalue("message.header.source.timestamp")); }
+  std::string momid() const			  { return (getXMLvalue("message.header.ids.momid")); }
+  std::string sasid() const			  { return (getXMLvalue("message.header.ids.sasid")); }
+  std::string payload() const		  { return (getXMLvalue("message.payload")); }
+  std::string header() const		  { return (getXMLvalue("message.header")); }
+
+  // Construct the given fields as a QPID message
+  qpid::messaging::Message& qpidMsg() { return (itsQpidMsg); }
+
+  // Return the raw message (header + payload)
+  std::string rawContent() const { return (itsQpidMsg.getContent()); }
+
+  // Return a short (one line) description of the message
+  std::string short_desc() const;
+
+  // function for printing
+  std::ostream& print (std::ostream& os) const;
+
+  // Very simple XML parser to get a key from the XML content.
+  std::string getXMLvalue(const std::string& key) const;
+
+private:
+  // -- datamembers -- 
+  qpid::messaging::Message itsQpidMsg;
+};
+
+inline std::ostream &operator<<(std::ostream &os, const Message &msg)
+{	
+	return (msg.print(os));
+}
+
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/include/MessageBus/MsgBus.h b/LCS/MessageBus/include/MessageBus/MsgBus.h
new file mode 100644
index 0000000000000000000000000000000000000000..849c43bad7fe060c9db19ebf47ae8dd56835cca3
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/MsgBus.h
@@ -0,0 +1,90 @@
+//# MsgBus.h: Wrapper for QPID clients to send and receive AMQP messages.
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_MSGBUS_H
+#define LOFAR_MESSAGEBUS_MSGBUS_H
+
+#ifdef HAVE_QPID
+#include <qpid/messaging/Connection.h>
+#include <qpid/messaging/Message.h>
+#include <qpid/messaging/Receiver.h>
+#include <qpid/messaging/Sender.h>
+#include <qpid/messaging/Session.h>
+#include <qpid/messaging/Address.h>
+
+#include <Common/Exception.h>
+#include <MessageBus/Message.h>
+
+#include <map>
+#include <string>
+
+namespace LOFAR {
+
+EXCEPTION_CLASS(MessageBusException, LOFAR::Exception);
+
+namespace MessageBus {
+  // Generic initialisation of the Messaging framework
+  void init();
+}
+
+class FromBus
+{
+public:
+  FromBus(const std::string &address="testqueue" , const std::string &options="; {create: never}", const std::string &broker = "amqp:tcp:127.0.0.1:5672") ;
+  ~FromBus(void);
+  bool addQueue(const std::string &address="testqueue", const std::string &options="; {create: never}");
+
+  bool getMessage(LOFAR::Message &msg, double timeout = 0.0); // timeout 0.0 means blocking
+
+  void ack   (LOFAR::Message &msg);
+  void nack  (LOFAR::Message &msg);
+  void reject(LOFAR::Message &msg);
+
+private:
+  qpid::messaging::Connection itsConnection;
+  qpid::messaging::Session    itsSession;
+
+  int itsNrMissingACKs;
+};
+
+class ToBus
+{
+public:
+  ToBus(const std::string &address="testqueue" , const std::string &options="; {create: never}", const std::string &broker = "amqp:tcp:127.0.0.1:5672") ;
+  ~ToBus(void);
+
+  void send(const std::string &msg);
+  void send(LOFAR::Message &msg);
+
+private:
+  // -- datamambers --
+  qpid::messaging::Connection itsConnection;
+  qpid::messaging::Session itsSession;
+  qpid::messaging::Sender itsSender;
+};
+
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/include/MessageBus/Protocols/CMakeLists.txt b/LCS/MessageBus/include/MessageBus/Protocols/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..09c3af9f8cb3681828a27571c6429bd60acccf2c
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Protocols/CMakeLists.txt
@@ -0,0 +1,14 @@
+# $Id$
+
+# Create symbolic link to include directory.
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_BINARY_DIR}/include/${PACKAGE_NAME}/Protocols)
+
+# Install header files.
+install(FILES
+  TaskFeedbackDataproducts.h
+  TaskFeedbackProcessing.h
+  TaskFeedbackState.h
+  TaskSpecificationSystem.h
+  DESTINATION include/${PACKAGE_NAME}/Protocols)
diff --git a/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackDataproducts.h b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackDataproducts.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c43c1ae6892b44a1300a6745c69f8bac6b26ee3
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackDataproducts.h
@@ -0,0 +1,98 @@
+//# TaskFeedbackDataproducts.h: Protocol for emission of dataproducts feedback information
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_TASK_FEEDBACK_DATAPRODUCTS_H
+#define LOFAR_MESSAGEBUS_TASK_FEEDBACK_DATAPRODUCTS_H
+
+#ifdef HAVE_QPID
+#include <MessageBus/Message.h>
+#include <Common/ParameterSet.h>
+
+namespace LOFAR {
+
+namespace Protocols {
+
+class TaskFeedbackDataproducts: public Message
+{
+public:
+  TaskFeedbackDataproducts(
+    // Name of the service or process producing this message
+    const std::string &from,
+
+    // End-user responsible for this request (if applicable)
+    const std::string &forUser,
+
+    // Human-readable summary describing this request
+    const std::string &summary,
+
+    // Identifiers for the context of this message
+    const std::string &momID,
+    const std::string &sasID,
+
+    // Payload: a parset containing the generated feedback
+    const ParameterSet &feedback
+  ):
+  Message(
+    from,
+    forUser,
+    summary,
+    "task.feedback.dataproducts",
+    "1.0.0",
+    momID,
+    sasID)
+  {
+    std::string buffer;
+
+    feedback.writeBuffer(buffer);
+    setTXTPayload(buffer);
+  }
+
+  // Parse a message
+  TaskFeedbackDataproducts(const qpid::messaging::Message qpidMsg)
+  :
+    Message(qpidMsg)
+  {
+  }
+
+  // Read a message from disk (header + payload)
+  TaskFeedbackDataproducts(const std::string &rawContent)
+  :
+    Message(rawContent)
+  {
+  }
+
+  ParameterSet feedback() const {
+    ParameterSet result;
+    result.adoptBuffer(payload());
+
+    return result;
+  }
+};
+
+} // namespace Protocols
+
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackProcessing.h b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackProcessing.h
new file mode 100644
index 0000000000000000000000000000000000000000..4fcec26201f88f26089f41653516944c66ec04a4
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackProcessing.h
@@ -0,0 +1,98 @@
+//# TaskFeedbackProcessing.h: Protocol for emission of processing feedback information
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_TASK_FEEDBACK_PROCESSING_H
+#define LOFAR_MESSAGEBUS_TASK_FEEDBACK_PROCESSING_H
+
+#ifdef HAVE_QPID
+#include <MessageBus/Message.h>
+#include <Common/ParameterSet.h>
+
+namespace LOFAR {
+
+namespace Protocols {
+
+class TaskFeedbackProcessing: public Message
+{
+public:
+  TaskFeedbackProcessing(
+    // Name of the service or process producing this message
+    const std::string &from,
+
+    // End-user responsible for this request (if applicable)
+    const std::string &forUser,
+
+    // Human-readable summary describing this request
+    const std::string &summary,
+
+    // Identifiers for the context of this message
+    const std::string &momID,
+    const std::string &sasID,
+
+    // Payload: a parset containing the generated feedback
+    const ParameterSet &feedback
+  ):
+  Message(
+    from,
+    forUser,
+    summary,
+    "task.feedback.processing",
+    "1.0.0",
+    momID,
+    sasID)
+  {
+    std::string buffer;
+
+    feedback.writeBuffer(buffer);
+    setTXTPayload(buffer);
+  }
+
+  // Parse a message
+  TaskFeedbackProcessing(const qpid::messaging::Message qpidMsg)
+  :
+    Message(qpidMsg)
+  {
+  }
+
+  // Read a message from disk (header + payload)
+  TaskFeedbackProcessing(const std::string &rawContent)
+  :
+    Message(rawContent)
+  {
+  }
+
+  ParameterSet feedback() const {
+    ParameterSet result;
+    result.adoptBuffer(payload());
+
+    return result;
+  }
+};
+
+} // namespace Protocols
+
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackState.h b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackState.h
new file mode 100644
index 0000000000000000000000000000000000000000..5777f4f6fd82dbc40ca3a3adae27f6360f21727e
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Protocols/TaskFeedbackState.h
@@ -0,0 +1,101 @@
+//# TaskFeedbackState.h: Protocol for emission of status feedback information
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_TASK_FEEDBACK_STATUS_H
+#define LOFAR_MESSAGEBUS_TASK_FEEDBACK_STATUS_H
+
+#ifdef HAVE_QPID
+#include <MessageBus/Message.h>
+#include <Common/ParameterSet.h>
+#include <Common/StringUtil.h>
+
+namespace LOFAR {
+
+namespace Protocols {
+
+class TaskFeedbackState: public Message
+{
+public:
+  TaskFeedbackState(
+    // Name of the service or process producing this message
+    const std::string &from,
+
+    // End-user responsible for this request (if applicable)
+    const std::string &forUser,
+
+    // Human-readable summary describing this request
+    const std::string &summary,
+
+    // Identifiers for the context of this message
+    const std::string &momID,
+    const std::string &sasID,
+
+    // Payload: a boolean indicating success
+    bool success
+  ):
+  Message(
+    from,
+    forUser,
+    summary,
+    "task.feedback.state",
+    "1.0.0",
+    momID,
+    sasID)
+  {
+    setXMLPayload(formatString(
+      "<task>\n"
+      "  <type>observation</type>\n"
+      "  <state>%s</state>\n"
+      "</task>",
+      success ? "finished" : "aborted"));
+  }
+
+  // Parse a message
+  TaskFeedbackState(const qpid::messaging::Message qpidMsg)
+  :
+    Message(qpidMsg)
+  {
+  }
+
+  // Read a message from disk (header + payload)
+  TaskFeedbackState(const std::string &rawContent)
+  :
+    Message(rawContent)
+  {
+  }
+
+  ParameterSet feedback() const {
+    ParameterSet result;
+    result.adoptBuffer(payload());
+
+    return result;
+  }
+};
+
+} // namespace Protocols
+
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/include/MessageBus/Protocols/TaskSpecificationSystem.h b/LCS/MessageBus/include/MessageBus/Protocols/TaskSpecificationSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..c67b9c8fc4efd2e211bd74a60432bdba2eddeec6
--- /dev/null
+++ b/LCS/MessageBus/include/MessageBus/Protocols/TaskSpecificationSystem.h
@@ -0,0 +1,84 @@
+//# TaskSpecificationSystem.h: Protocol for emission of status feedback information
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id: TaskSpecificationSystem.h 30864 2015-02-03 16:07:56Z mol $
+
+#ifndef LOFAR_MESSAGEBUS_TASK_SPECIFICATION_SYSTEM_H
+#define LOFAR_MESSAGEBUS_TASK_SPECIFICATION_SYSTEM_H
+
+#ifdef HAVE_QPID
+#include <MessageBus/Message.h>
+#include <Common/ParameterSet.h>
+#include <Common/StringUtil.h>
+
+namespace LOFAR {
+namespace Protocols {
+
+class TaskSpecificationSystem: public Message
+{
+public:
+    TaskSpecificationSystem(
+						// Name of the service or process producing this message
+						const std::string &from,
+
+						// End-user responsible for this request (if applicable)
+						const std::string &forUser,
+
+						// Human-readable summary describing this request
+						const std::string &summary,
+
+						// Identifiers for the context of this message
+						const std::string &momID,
+						const std::string &sasID,
+
+						// Payload: a parset containing the generated feedback
+						const ParameterSet &feedback
+					  ): 
+		Message( from, forUser, summary, "task.specification.system", "1.0.0", momID, sasID)
+	{
+   		std::string buffer;
+		feedback.writeBuffer(buffer);
+		setTXTPayload(buffer);
+	}
+
+	// Parse a message
+	TaskSpecificationSystem(const qpid::messaging::Message qpidMsg) :
+	    Message(qpidMsg)
+	{ }
+
+	// Read a message from disk (header + payload)
+	TaskSpecificationSystem(const std::string &rawContent) :
+		Message(rawContent)
+	{ }
+
+	ParameterSet specfications() const {
+		ParameterSet result;
+		result.adoptBuffer(payload());
+		return result;
+	}
+};
+
+  } // namespace Protocols
+} // namespace LOFAR
+
+#endif
+
+#endif
+
diff --git a/LCS/MessageBus/src/CMakeLists.txt b/LCS/MessageBus/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e8062864899dc5048adb5fcc42620b8d8d9ea9fc
--- /dev/null
+++ b/LCS/MessageBus/src/CMakeLists.txt
@@ -0,0 +1,28 @@
+# $Id$
+
+include(LofarPackageVersion)
+include(PythonInstall)
+
+set(messagebus_LIB_SRCS
+  Package__Version.cc
+  LogSink.cc
+  MsgBus.cc
+  Message.cc)
+
+set(messagebus_PROGRAMS
+)
+
+lofar_add_library(messagebus ${messagebus_LIB_SRCS})
+
+foreach(prog ${messagebus_PROGRAMS})
+  lofar_add_bin_program(${prog} ${prog}.cc)
+endforeach(prog ${messagebus_PROGRAMS})
+
+python_install(
+  __init__.py
+  msgbus.py
+  basemsgbus.py
+  message.py
+  DESTINATION lofar/messagebus)
+
+add_subdirectory(protocols)
diff --git a/LCS/MessageBus/src/LofarMsgTemplate.txt b/LCS/MessageBus/src/LofarMsgTemplate.txt
new file mode 100644
index 0000000000000000000000000000000000000000..796df813bad773dca7782f7fc60567ca0bb34e2d
--- /dev/null
+++ b/LCS/MessageBus/src/LofarMsgTemplate.txt
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>%s</name>
+         <version>%s</version>
+      </protocol>
+      <source>
+         <name>%s</name>
+         <user>%s</user>
+         <uuid>%s</uuid>
+         <timestamp>%s</timestamp>
+         <summary>%s</summary>
+      </source>
+      <ids>
+         <momid>%s</momid>
+         <sasid>%s</sasid>
+      </ids>
+   </header>
+   <payload>
+%s
+   </payload>
+</message>
diff --git a/LCS/MessageBus/src/LogSink.cc b/LCS/MessageBus/src/LogSink.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9e698119ebd12d8dd313617a98ef5067d92c2c80
--- /dev/null
+++ b/LCS/MessageBus/src/LogSink.cc
@@ -0,0 +1,90 @@
+#include "lofar_config.h"
+
+#include "LogSink.h"
+#include <Common/LofarLogger.h>
+
+#include <Common/SystemUtil.h>
+#include <Common/StringUtil.h>
+#include <string>
+#include <sstream>
+
+#ifdef HAVE_QPID
+#include <qpid/messaging/Logger.h>
+
+using namespace qpid::messaging;
+
+namespace LOFAR {
+
+  class QpidLogSink: public LoggerOutput {
+  public:
+    QpidLogSink() {
+    }
+
+    virtual void log(Level level, bool user, const char* file, int line, const char* function, const std::string& message) {
+      (void)user;
+
+      // shorten filename to reduce spam
+      std::string filename = basename(file);
+
+      // remove trailing \n from message (and other white space while we're at it)
+      std::string trimmed_message = message;
+      rtrim(trimmed_message, " \t\n");
+
+      // construct log message
+      std::stringstream msg;
+      msg << function << "(): " << trimmed_message << " (" << filename << ":" << line << ")";
+
+      // emit at the right level
+      switch(level) {
+        case trace:
+        case debug:
+          LOG_DEBUG(msg.str());
+          break;
+
+        case info:
+        case notice:
+          LOG_INFO(msg.str());
+          break;
+
+        case warning:
+          LOG_WARN(msg.str());
+          break;
+
+        case error:
+          LOG_ERROR(msg.str());
+          break;
+
+        case critical:
+          LOG_FATAL(msg.str());
+          break;
+      }
+    }
+  };
+
+  static QpidLogSink qpidLogSink;
+
+  void qpidlogsink_init() {
+    const char *argv[] = {
+      // Name of program (dummy)
+      "a.out",
+
+      // QPID logger configuration parameters (see Logger::configure)
+
+      // Disable all default QPID sinks
+      "--log-to-stdout", "off",
+      "--log-to-stderr", "off",
+
+      // Trim the log messages
+      "--log-time", "off"
+    };
+    int argc = sizeof argv / sizeof argv[0];
+
+    Logger::configure(argc, argv);
+
+    // Add the LOFAR logger as a sink for QPID
+    Logger::setOutput(qpidLogSink);
+  }
+
+} // namespace LOFAR
+
+#endif
diff --git a/LCS/MessageBus/src/LogSink.h b/LCS/MessageBus/src/LogSink.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddddee4c8dcb620abdcf2ef4506b87888ed9e50f
--- /dev/null
+++ b/LCS/MessageBus/src/LogSink.h
@@ -0,0 +1,37 @@
+//# LogSink.h: Wrapper to initialise the QPID library
+//#
+//# Copyright (C) 2015
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_MESSAGEBUS_LOGSINK_H
+#define LOFAR_MESSAGEBUS_LOGSINK_H
+
+namespace LOFAR {
+
+#ifdef HAVE_QPID
+
+void qpidlogsink_init();
+
+#endif
+
+} // namespace LOFAR
+
+#endif
+
diff --git a/LCS/MessageBus/src/Message.cc b/LCS/MessageBus/src/Message.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2993229754a543729f77c8335b4bc87873a755bb
--- /dev/null
+++ b/LCS/MessageBus/src/Message.cc
@@ -0,0 +1,194 @@
+//#  Message.cc: one_line_description
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: $
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <Common/lofar_string.h>
+#include <Common/StringUtil.h>
+#include <MessageBus/Message.h>
+
+#include <qpid/types/Uuid.h>
+
+#include <time.h>
+
+
+namespace LOFAR {
+  using namespace StringUtil;
+
+const string LOFAR_MSG_TEMPLATE = "\
+<message>\n\
+   <header>\n\
+      <system>LOFAR</system>\n\
+      <version>1.0.0</version>\n\
+      <protocol>\n\
+         <name>%s</name>\n\
+         <version>%s</version>\n\
+      </protocol>\n\
+      <source>\n\
+         <name>%s</name>\n\
+         <user>%s</user>\n\
+         <uuid>%s</uuid>\n\
+         <timestamp>%s</timestamp>\n\
+         <summary>%s</summary>\n\
+      </source>\n\
+      <ids>\n\
+         <momid>%s</momid>\n\
+         <sasid>%s</sasid>\n\
+      </ids>\n\
+   </header>\n\
+   <payload>\n\
+%s\n\
+   </payload>\n\
+</message>";
+
+static string _timestamp() {
+  // Get now (in seconds since epoch)
+  time_t now = time(NULL);
+
+  // Dissect into components (year, month, etc)
+  struct tm now_tm;
+  gmtime_r(&now, &now_tm);
+
+  // Convert to string
+  char buffer[64];
+  if (strftime(buffer, sizeof buffer, "%FT%T", &now_tm) == 0)
+    buffer[0] = 0;
+
+  return buffer;
+}
+
+static string _uuid() {
+  qpid::types::Uuid uuid(true);
+  return uuid.str();
+}
+
+Message::Message(const std::string &from,
+				 const std::string &forUser,
+				 const std::string &summary,
+				 const std::string &protocol,
+				 const std::string &protocolVersion,
+				 const std::string &momid,
+				 const std::string &sasid) 
+{	
+	itsQpidMsg.setContent(formatString(LOFAR_MSG_TEMPLATE.c_str(), protocol.c_str(), protocolVersion.c_str(),
+										from.c_str(), forUser.c_str(), _uuid().c_str(), _timestamp().c_str(), summary.c_str(), 
+										momid.c_str(), sasid.c_str(), "%s"));
+  itsQpidMsg.setContentType("text/plain");
+  itsQpidMsg.setDurable(true);
+}
+
+// Read a message from disk (header + payload)
+Message::Message(const std::string &rawContent)
+{
+	itsQpidMsg.setContent(rawContent);
+}
+
+Message::~Message()
+{}
+
+void Message::setXMLPayload (const std::string         &payload)
+{
+	itsQpidMsg.setContent(formatlString(itsQpidMsg.getContent().c_str(), payload.c_str()));
+}
+
+void Message::setTXTPayload (const std::string         &payload)
+{
+	itsQpidMsg.setContent(formatlString(itsQpidMsg.getContent().c_str(), payload.c_str()));
+}
+
+void Message::setMapPayload (const qpid::types::Variant::Map  &payload)
+{
+
+}
+
+void Message::setListPayload(const qpid::types::Variant::List &payload)
+{
+
+}
+
+std::string Message::short_desc() const
+{
+  return formatString("[%s] %s", uuid().c_str(), summary().c_str());
+}
+
+//
+// print
+//
+std::ostream& Message::print (std::ostream& os) const
+{
+	os << "system         : " << system() << endl;
+    os << "systemversion  : " << headerVersion() << endl;
+    os << "protocolName   : " << protocol() << endl;
+    os << "protocolVersion: " << protocolVersion() << endl;
+    os << "summary        : " << summary() << endl;
+    os << "timestamp      : " << timestamp() << endl;
+    os << "source         : " << from() << endl;
+    os << "user           : " << forUser() << endl;
+    os << "uuid           : " << uuid() << endl;
+    os << "momid          : " << momid() << endl;
+    os << "sasid          : " << sasid() << endl;
+    os << "payload        : " << payload() << endl;
+  os << "BEGIN FULL PACKET" << endl;
+  os << itsQpidMsg.getContent() << endl;
+  os << "END FULL PACKET" << endl;
+	return (os);
+}
+
+//
+// getXMLvalue(tag)
+//
+string Message::getXMLvalue(const string& key) const
+{
+	// get copy of content
+	vector<string>	labels = split(key, '.');
+	string			content(itsQpidMsg.getContent());
+
+	// loop over subkeys
+	string::size_type	offset = 0;
+	string::size_type	begin = string::npos;
+	string::size_type	end = string::npos;
+	string				startTag;
+	for (size_t i = 0; i <  labels.size(); ++i) {
+		// define tags to find
+		startTag = string("<"+labels[i]+">");
+		// search begin tag
+		begin  = content.find(startTag, offset);
+		if (begin == string::npos) {
+			return ("???");
+		}
+		offset = begin;
+	}
+	// search end tag
+	string stopTag ("</"+labels[labels.size()-1]+">");
+	begin+=startTag.size();
+	end = content.find(stopTag, begin);
+	if (end == string::npos) {
+		return ("???");
+	}
+	return (content.substr(begin, end - begin));
+}
+
+
+} // namespace LOFAR
diff --git a/LCS/MessageBus/src/MsgBus.cc b/LCS/MessageBus/src/MsgBus.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e40584cb3cee3a477a324811060f3411d77b1463
--- /dev/null
+++ b/LCS/MessageBus/src/MsgBus.cc
@@ -0,0 +1,177 @@
+#include "lofar_config.h"
+
+#include <MessageBus/MsgBus.h>
+#include "LogSink.h"
+#include <Common/LofarLogger.h>
+
+#ifdef HAVE_QPID
+#include <qpid/types/Exception.h>
+#include <qpid/messaging/exceptions.h>
+#include <stdlib.h>
+
+using namespace qpid::messaging;
+
+namespace LOFAR {
+
+  static Duration TimeOutDuration(double secs)
+  {
+    if (secs > 0.0)
+      return (Duration)(1000.0 * secs);
+
+    return Duration::FOREVER;
+  }
+
+  static std::string queue_prefix()
+  {
+    char *prefix = getenv("QUEUE_PREFIX");
+
+    if (!prefix)
+      return "";
+
+    return prefix;
+  }
+
+  namespace MessageBus {
+    void init() {
+      qpidlogsink_init();
+    }
+  }
+
+  FromBus::FromBus(const std::string &address, const std::string &options, const std::string &broker)
+  try:
+    itsConnection(broker,"{reconnect:true}"),
+    itsNrMissingACKs(0)
+  {
+    LOG_DEBUG_STR("[FromBus] Connecting to broker " << broker);
+    itsConnection.open();
+    LOG_INFO_STR("[FromBus] Connected to broker " << itsConnection.getUrl());
+
+    itsSession = itsConnection.createSession();
+
+    addQueue(address, options);
+  } catch(const qpid::types::Exception &ex) {
+    THROW(MessageBusException, ex.what());
+  }
+
+ 
+  FromBus::~FromBus(void)
+  {
+    if (itsNrMissingACKs) {
+      LOG_ERROR_STR("[FromBus] " << itsNrMissingACKs << " messages not ACK'ed");
+	}
+
+    try {
+      // Make sure all requests are finished
+
+      // connection.close() closes all senders, receivers, and sessions as well.
+      itsConnection.close();
+    } catch(const qpid::types::Exception &ex) {
+      LOG_FATAL_STR("Exception in destructor, cannot guarantee message delivery: " << ex.what());
+    }
+  }
+
+  bool FromBus::getMessage(LOFAR::Message &msg, double timeout) // timeout 0.0 means blocking
+  {
+    Receiver next;
+	qpid::messaging::Message qmsg;
+
+    LOG_DEBUG_STR("[FromBus] Waiting for message");
+    if (itsSession.nextReceiver(next,TimeOutDuration(timeout))) {
+        LOG_DEBUG_STR("[FromBus] Message available on queue " << next.getName());
+        itsNrMissingACKs++;
+        if (next.get(qmsg)) {
+			msg = LOFAR::Message(qmsg);
+            LOG_INFO_STR("[FromBus] Message received on queue " << next.getName() << ": " << msg.short_desc());
+			return true;
+		} else {
+          LOG_ERROR_STR("[FromBus] Could not retrieve available message on queue " << next.getName());
+        }
+    }
+    return false;
+  }
+
+  void FromBus::ack(LOFAR::Message &msg)
+  {
+     itsSession.acknowledge(msg.qpidMsg());
+     itsNrMissingACKs --;
+
+     LOG_INFO_STR("[FromBus] Message ACK'ed: " << msg.short_desc());
+  }
+
+  void FromBus::nack(LOFAR::Message &msg)
+  {
+     itsSession.release(msg.qpidMsg());
+     itsNrMissingACKs--;
+
+     LOG_ERROR_STR("[FromBus] Message NACK'ed: " << msg.short_desc());
+  }
+
+  void FromBus::reject(LOFAR::Message &msg)
+  {
+     itsSession.reject(msg.qpidMsg());
+     itsNrMissingACKs --;
+
+     LOG_ERROR_STR("[FromBus] Message rejected: " << msg.short_desc());
+  }
+
+  bool FromBus::addQueue(const std::string &address, const std::string &options)
+  {
+     try
+     {
+        Address addr(queue_prefix()+address+options);
+        Receiver receiver = itsSession.createReceiver(addr);
+        receiver.setCapacity(1);
+
+        LOG_INFO_STR("[FromBus] Receiver started at queue " << receiver.getName());
+     } catch(const qpid::types::Exception &ex) {
+       //THROW(MessageBusException, ex.what());
+       return false;
+     }
+     return true;
+  }
+
+  ToBus::ToBus(const std::string &address, const std::string &options, const std::string &broker) 
+  try:
+    itsConnection(broker,"{reconnect:true}")
+  {
+    LOG_DEBUG_STR("[ToBus] Connecting to broker " << broker);
+    itsConnection.open();
+    LOG_INFO_STR("[ToBus] Connected to broker " << itsConnection.getUrl());
+
+    itsSession = itsConnection.createSession();
+    Address addr(queue_prefix()+address+options);
+    itsSender = itsSession.createSender(addr);
+    LOG_INFO_STR("[ToBus] Sender created at queue " << itsSender.getName());
+  } catch(const qpid::types::Exception &ex) {
+    THROW(MessageBusException, ex.what());
+  }
+
+  ToBus::~ToBus(void)
+  {
+
+    try {
+      // Make sure all requests are finished
+
+      // connection.close() closes all senders, receivers, and sessions as well.
+      itsConnection.close();
+    } catch(const qpid::types::Exception &ex) {
+      LOG_FATAL_STR("Exception in destructor, cannot guarantee message delivery: " << ex.what());
+    }
+  }
+
+  void ToBus::send(const std::string &msg)
+  {
+    LOFAR::Message tosend(msg);
+    itsSender.send(tosend.qpidMsg(), true);
+    LOG_INFO_STR("[ToBus] Message sent to queue " << itsSender.getName() << ": " << tosend.short_desc());
+  }
+
+  void ToBus::send(LOFAR::Message& msg)
+  {
+    itsSender.send(msg.qpidMsg(), true);
+    LOG_INFO_STR("[ToBus] Message sent to queue " << itsSender.getName() << ": " << msg.short_desc());
+  }
+
+} // namespace LOFAR
+
+#endif
diff --git a/LCS/MessageBus/src/__init__.py b/LCS/MessageBus/src/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3bcbe73ef576c7f93974459df18e6da942628cd6
--- /dev/null
+++ b/LCS/MessageBus/src/__init__.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id: __init__.py 29911 2014-08-12 14:45:14Z klijn $
diff --git a/LCS/MessageBus/src/basemsgbus.py b/LCS/MessageBus/src/basemsgbus.py
new file mode 100644
index 0000000000000000000000000000000000000000..d51c21f3b4747cc9dfeb90842dd81271f1375576
--- /dev/null
+++ b/LCS/MessageBus/src/basemsgbus.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# id.. TDB
+from qpid.messaging import *
+ 
+# Candidate for a config file
+broker="127.0.0.1" 
+address=""
+options=""
+ # "create:always, node: { type: queue, durable: True}"
+ 
+class ToBus:
+    def __init__(self, address, broker=broker, options=options):
+        self.connection = Connection(broker)
+        self.connection.reconnect = True
+ 
+        try:
+            self.connection.open()
+            self.session = self.connection.session() 
+            #self.receiver = self.session.receiver("%s;{%s}" %(address,options))
+	    #self.receiver.capacity = 32
+            self.sender = self.session.sender(address)
+ 
+        except MessagingError,m:
+            print " OMG!!"
+            print m
+ 
+    def sendstr(self,messagetxt,subject="",reply_to=""):
+        msg = Message(messgaetxt)
+        msg.subject=subject
+        msg.durable=True
+        if (reply_to != ""):
+           msg.reply_to=reply_to
+        self.sender.send(msg)
+
+    def send(self,msg):
+        if msg is None:
+          print( " attempt to send None object!")
+        else:
+          msg.durable=True # force durable messages
+          self.sender.send(msg)
+        
+ 
+class FromBus:
+    def __init__(self, address=address, broker=broker, options=options):
+        self.connection = Connection(broker)
+        self.connection.reconnect = True
+ 
+        try:
+            self.connection.open()
+            self.session = self.connection.session() 
+            self.receiver = self.session.receiver("%s;{%s}" %(address,options))
+            #self.address = self.receiver.address
+	    self.receiver.capacity = 1
+ 
+        except MessagingError,m:
+            print " OMG!!"
+            print m
+ 
+    def get(self,timeout=None):
+	try:
+        	self.msg= self.receiver.fetch(timeout)
+	except exceptions.Empty, e:
+                self.msg = None
+        return self.msg
+        #.content, self.msg.subject
+ 
+    def ack(self,msg):
+        if msg is None:
+          print(" Ack on None object!")
+        else:
+          self.session.acknowledge(msg)
+ 
+class BusReply:
+    def __init__(self, address="Reply", broker=broker, options=options):
+        self.address = "%s%s ; { %s }" %(str(uuid4()),address,options)
+        self.connection = Connection(broker)
+        self.connection.reconnect = True
+ 
+        try:
+            self.connection.open()
+            self.session = self.connection.session()
+            self.receiver = self.session.receiver(self.address)
+            self.address = self.receiver.source
+            #self.receiver.capacity = 32
+ 
+        except MessagingError,m:
+            print " OMG!!"
+            print m
+ 
+    def get(self,timeout=None):
+        try:
+                self.msg= self.receiver.fetch(timeout)
+        except exceptions.Empty, e:
+                return "None" , "None"
+        return self.msg.content, self.msg.subject
+ 
+    def ack(self):
+          self.session.acknowledge()
+ 
+class MultiReceiveBus:
+    def __init__(self, handler, address=address, broker=broker, options=options):
+        self.connection = Connection(broker)
+        self.connection.reconnect = True
+        self.handlers={}
+        try:
+            self.connection.open()
+            self.session = self.connection.session()
+            receiver = self.session.receiver("%s;{%s}" %(address,options))
+            receiver.capacity = 1 #32
+            self.handlers[receiver] = handler
+ 
+        except MessagingError,m:
+            print " OMG!!"
+            print m
+ 
+    def add(self,handler,address,options=options):
+        try:
+            receiver=self.session.receiver("%s;{%s}" %(address,options))
+            receiver.capacity = 1 #32
+            self.handlers[receiver]=handler
+        except MessagingError,m:
+            print "Error adding receiver"
+            print m
+ 
+    def HandleMessages(self):
+        while True:
+                print "waiting for messages"
+                receiver = self.session.next_receiver()
+                print "got incoming message"
+                handler = self.handlers[receiver]
+                msg = receiver.fetch()
+                handler(self,msg.content,msg.subject)
+ 
+    def ack(self,msg):
+          self.session.acknowledge(msg)
+
diff --git a/LCS/MessageBus/src/message.py b/LCS/MessageBus/src/message.py
new file mode 100644
index 0000000000000000000000000000000000000000..793f256b8e3bb300dcad37c919ddb265b96009ea
--- /dev/null
+++ b/LCS/MessageBus/src/message.py
@@ -0,0 +1,214 @@
+#!/usr/bin/python
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+import qpid.messaging
+import xml.dom.minidom as xml
+import xml.parsers.expat as expat
+import datetime
+
+LOFAR_MSG_TEMPLATE = """
+<message>
+   <header>
+      <system/>
+      <version/>
+      <protocol>
+         <name/>
+         <version/>
+      </protocol>
+      <source>
+         <name/>
+         <user/>
+         <uuid/>
+         <timestamp/>
+         <summary/>
+      </source>
+      <ids>
+         <momid/>
+         <sasid/>
+      </ids>
+   </header>
+   <payload>
+   </payload>
+</message>"""
+
+def _timestamp():
+  """
+    Return the current time as YYYY-MM-DDTHH:MM:SS
+  """
+  now = datetime.datetime.now()
+  return now.strftime("%FT%T")
+
+def _uuid():
+  """
+    Return an UUID
+  """
+  return str(qpid.messaging.uuid4())
+
+class MessageException(Exception):
+    pass
+
+class Message(object):
+    def __init__(self, from_="", forUser="", summary="", protocol="", protocolVersion="", momid="", sasid="", qpidMsg=None):
+
+      for name, element in self._property_list().iteritems():
+        self._add_property(name, element)
+
+      if qpidMsg is None:
+        self.document = xml.parseString(LOFAR_MSG_TEMPLATE)
+        self._qpidMsg = qpid.messaging.Message(content_type="text/plain", durable=True)
+        self.dirty    = True
+
+        # Set properties provided by constructor
+        self.system          = "LOFAR"
+        self.headerVersion   = "1.0.0"
+        self.protocol        = protocol
+        self.protocolVersion = protocolVersion
+        self.from_           = from_
+        self.forUser         = forUser
+        self.summary         = summary
+        self.uuid            = _uuid()
+        self.timestamp       = _timestamp()
+        self.momid           = momid
+        self.sasid           = sasid
+      else:
+        self._qpidMsg = qpidMsg
+        self.dirty    = False
+
+        # Set properties by provided qpidMsg
+        try:
+          # Replace literal << in the content, which is occasionally inserted by the C++
+          # code as part of the Parset ("Observation.Clock=<<Clock200")
+          self.document = xml.parseString(qpidMsg.content.replace("<<","&lt;&lt;"))
+        except expat.ExpatError, e:
+          print "Could not parse XML message content: ", e, msg.content
+          raise MessageException(e)
+
+    def _add_property(self, name, element):
+      def getter(self):
+        return self._getXMLdata(element)
+      def setter(self, value):
+        self._setXMLdata(element, str(value))
+
+      setattr(self.__class__, name, property(getter, setter))
+
+    def _property_list(self):
+      """ List of XML elements that are exposed as properties. """
+      return { 
+        "system":          "message.header.system",
+        "headerVersion":   "message.header.version",
+        "protocol":        "message.header.protocol.name",
+        "protocolVersion": "message.header.protocol.version",
+        "from_":           "message.header.source.name",
+        "forUser":         "message.header.source.user",
+        "uuid":            "message.header.source.uuid",
+        "summary":         "message.header.source.summary",
+        "timestamp":       "message.header.source.timestamp",
+        "momid":           "message.header.ids.momid",
+        "sasid":           "message.header.ids.sasid",
+        "payload":         "message.payload",
+        "header":          "message.header",
+      }
+
+    """ API (apart from properties). """
+
+    def __repr__(self):
+      return "Message(%s %s)" % (self.protocol, self.protocolVersion)
+
+    def __str__(self):
+      return ("system         : %s\n" % (self.system,) +
+              "systemversion  : %s\n" % (self.headerVersion,) +
+              "protocol       : %s\n" % (self.protocol,) +
+              "protocolVersion: %s\n" % (self.protocolVersion,) +
+              "summary        : %s\n" % (self.summary,) +
+              "timestamp      : %s\n" % (self.timestamp,) +
+              "source         : %s\n" % (self.from_,) +
+              "user           : %s\n" % (self.forUser,) +
+              "uuid           : %s\n" % (self.uuid,) +
+              "momid          : %s\n" % (self.momid,) +
+              "sasid          : %s\n" % (self.sasid,) +
+              "payload        : %s\n" % (self.payload,)
+             )
+
+    def qpidMsg(self):
+      """ Construct the QPID message content. """
+
+      if self.dirty:
+        self._qpidMsg.content = self.document.toxml()
+
+      return self._qpidMsg
+
+    """ XML support functions. See also lofarpipe/support/xmllogging.py. """
+
+    def _get_child(self, node, name):
+      """ Return a specific child node. """
+
+      for child in node.childNodes:
+        if child.nodeName == name and child.nodeType == child.ELEMENT_NODE:
+          return child
+
+      return None
+
+    def _get_data(self, node):
+      """ Return the textual content of a node. """
+
+      data = []
+      for child in node.childNodes:
+        if child.nodeType == child.TEXT_NODE:
+          data.append(child.data)
+
+      return ''.join(data)
+
+    def _set_data(self, node, data):
+      """ Set the textual content of a node. """
+
+      newchild = self.document.createTextNode(data)
+
+      for child in node.childNodes:
+        if child.nodeType == child.TEXT_NODE:
+          node.replaceChild(newchild, child)
+          break;
+      else:
+        node.appendChild(newchild)
+
+      self.dirty = True
+
+    def _getXMLnode(self, name):
+      """ Return a node given by its dot-separated path name.
+          So a.b.c returns the inner node of <a><b><c></c></b></a>. """
+      parts = name.split(".")
+      node = self.document
+
+      for p in parts:
+        node = self._get_child(node,p)
+
+        if node is None:
+          return None
+
+      return node
+
+    def _getXMLdata(self, name):
+      return self._get_data(self._getXMLnode(name))
+
+    def _setXMLdata(self, name, data):
+      return self._set_data(self._getXMLnode(name), data)
+
+if __name__ == "__main__":
+  m = Message("FROM", "FORUSER", "SUMMARY", "PROTOCOL", "1.2.3", "11111", "22222")
+  print str(m)
+  print m.document.toxml()
+
diff --git a/LCS/MessageBus/src/msgbus.py b/LCS/MessageBus/src/msgbus.py
new file mode 100644
index 0000000000000000000000000000000000000000..a17c2ac2bde0927fafa46cf0e7075994e1957333
--- /dev/null
+++ b/LCS/MessageBus/src/msgbus.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python
+# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# id.. TDB
+
+try:
+  import qpid.messaging
+  enabled = True
+except ImportError:
+  enabled = False
+
+import os
+import signal
+import lofar.messagebus.message as message
+
+# Candidate for a config file
+broker="127.0.0.1" 
+options="create:never"
+
+class BusException(Exception):
+    pass
+
+class Session:
+    def __init__(self, broker):
+        self.connection = qpid.messaging.Connection(broker)
+        self.connection.reconnect = True
+
+        try:
+            self.connection.open()
+            self.session = self.connection.session() 
+        except qpid.messaging.MessagingError, m:
+            raise BusException(m)
+
+    def __del__(self):
+        # NOTE: session.close() freezes under certain error conditions,
+        # f.e. opening a receiver on a non-existing queue.
+        # This seems to happen whenever a Python exception was thrown
+        # by the qpid wrapper.
+        #
+        # We set a timeout to prevent freezing, which obviously leads
+        # to data loss if the stall was legit.
+        try:
+          self.connection.close(5.0)
+        except qpid.messaging.exceptions.Timeout, t:
+          raise BusException(t)
+
+    def address(self, queue, options):
+        return "%s%s; {%s}" % (self._queue_prefix(), queue, options)
+
+    def _queue_prefix(self):
+      return os.environ.get("QUEUE_PREFIX", "")
+
+class ToBus(Session):
+    def __init__(self, queue, options=options, broker=broker):
+        Session.__init__(self, broker)
+
+        try:
+            self.sender = self.session.sender(self.address(queue, options))
+        except qpid.messaging.MessagingError, m:
+            raise BusException(m)
+
+    def send(self, msg):
+        try:
+            self.sender.send(msg.qpidMsg())
+        except qpid.messaging.SessionError, m:
+            raise BusException(m)
+
+class FromBus(Session):
+    def __init__(self, queue, options=options, broker=broker):
+        Session.__init__(self, broker)
+
+        self.add_queue(queue, options)
+
+    def add_queue(self, queue, options=options):
+        try:
+            receiver = self.session.receiver(self.address(queue, options))
+
+            # Need capacity >=1 for 'self.session.next_receiver' to function across multiple queues
+            receiver.capacity = 1 #32
+        except qpid.messaging.MessagingError, m:
+            raise BusException(m)
+
+    def get(self, timeout=None):
+        msg = None
+
+        try:
+            receiver = self.session.next_receiver(timeout)
+            if receiver != None: msg = receiver.fetch() # receiver.get() is better, but requires qpid 0.31+
+        except qpid.messaging.exceptions.Empty, e:
+            return None
+
+        if msg is None:
+          return None
+        else:
+          return message.Message(qpidMsg=msg)
+
+    def ack(self, msg):
+        self.session.acknowledge(msg.qpidMsg)
+
diff --git a/LCS/MessageBus/src/protocols/CMakeLists.txt b/LCS/MessageBus/src/protocols/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ee3c47119038645b810a0c166a29b07b37cb376d
--- /dev/null
+++ b/LCS/MessageBus/src/protocols/CMakeLists.txt
@@ -0,0 +1,10 @@
+# $Id$
+
+include(PythonInstall)
+
+python_install(
+  __init__.py
+  taskfeedbackdataproducts.py
+  taskfeedbackprocessing.py
+  taskfeedbackstate.py
+  DESTINATION lofar/messagebus/protocols)
diff --git a/LCS/MessageBus/src/protocols/__init__.py b/LCS/MessageBus/src/protocols/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..779271f4bae8ff25f9c6e5fd683317634f899945
--- /dev/null
+++ b/LCS/MessageBus/src/protocols/__init__.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id$
diff --git a/LCS/MessageBus/src/protocols/taskfeedbackdataproducts.py b/LCS/MessageBus/src/protocols/taskfeedbackdataproducts.py
new file mode 100644
index 0000000000000000000000000000000000000000..da9e06a1eee0b03d77de1a9440533e10378a88fa
--- /dev/null
+++ b/LCS/MessageBus/src/protocols/taskfeedbackdataproducts.py
@@ -0,0 +1,33 @@
+
+#!/usr/bin/python
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+import lofar.messagebus.message
+
+class TaskFeedbackDataproducts(lofar.messagebus.message.Message):
+  def __init__(self, from_, forUser, summary, momID, sasID, feedback):
+    super(TaskFeedbackDataproducts, self).__init__(
+      from_,
+      forUser,
+      summary,
+      "task.feedback.dataproducts",
+      "1.0.0",
+      momID,
+      sasID)
+
+    self.payload = str(feedback)
diff --git a/LCS/MessageBus/src/protocols/taskfeedbackprocessing.py b/LCS/MessageBus/src/protocols/taskfeedbackprocessing.py
new file mode 100644
index 0000000000000000000000000000000000000000..bacd6a7491e2c185a37a4414204cbb6ce3c1a72e
--- /dev/null
+++ b/LCS/MessageBus/src/protocols/taskfeedbackprocessing.py
@@ -0,0 +1,33 @@
+
+#!/usr/bin/python
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+import lofar.messagebus.message
+
+class TaskFeedbackProcessing(lofar.messagebus.message.Message):
+  def __init__(self, from_, forUser, summary, momID, sasID, feedback):
+    super(TaskFeedbackProcessing, self).__init__(
+      from_,
+      forUser,
+      summary,
+      "task.feedback.processing",
+      "1.0.0",
+      momID,
+      sasID)
+
+    self.payload = str(feedback)
diff --git a/LCS/MessageBus/src/protocols/taskfeedbackstate.py b/LCS/MessageBus/src/protocols/taskfeedbackstate.py
new file mode 100644
index 0000000000000000000000000000000000000000..c9d3c766ac2b830096998a8e8411772d4a407037
--- /dev/null
+++ b/LCS/MessageBus/src/protocols/taskfeedbackstate.py
@@ -0,0 +1,64 @@
+
+#!/usr/bin/python
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+#import lofar.messagebus.Message
+import lofar.messagebus.message
+import xml.dom.minidom as xml
+
+LOFAR_STATUS_MSG_TEMPLATE = """
+<task>
+  <type/>
+  <state/>
+</task>"""
+
+class TaskFeedbackState(lofar.messagebus.message.Message):
+  def __init__(self, from_, forUser, summary, momID, sasID, status):
+    super(TaskFeedbackState, self).__init__(
+      from_,
+      forUser,
+      summary,
+      "task.feedback.state",
+      "1.0.0",
+      momID,
+      sasID)
+
+    payload_document = xml.parseString(LOFAR_STATUS_MSG_TEMPLATE)
+
+    self._getXMLnode("message.payload").appendChild(payload_document.firstChild)
+
+    self.type_ = "pipeline"
+    if status:
+      self.state = "finished"
+    else:
+      self.state = "aborted"
+
+  def _property_list(self):
+     properties = super(TaskFeedbackState, self)._property_list()
+     
+     properties.update( {
+       "type_": "message.payload.task.type",
+       "state": "message.payload.task.state",
+     } )
+
+     return properties
+
+if __name__ == "__main__":
+    msg = TaskFeedbackState("FROM", "FORUSER", "SUMMARY", "11111", "22222", True)
+    print msg.document.toxml()
+
diff --git a/LCS/MessageBus/test/CMakeLists.txt b/LCS/MessageBus/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0f8f56a78780c14db8f6efddfbe82d300753b60c
--- /dev/null
+++ b/LCS/MessageBus/test/CMakeLists.txt
@@ -0,0 +1,10 @@
+# $Id$
+
+include(LofarCTest)
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/MessageFuncs.sh.in
+  ${CMAKE_BINARY_DIR}/bin/MessageFuncs.sh @ONLY)
+
+lofar_add_test(tMsgBus tMsgBus.cc)
+lofar_add_test(tMessage tMessage.cc)
diff --git a/LCS/MessageBus/test/MessageFuncs.sh.in b/LCS/MessageBus/test/MessageFuncs.sh.in
new file mode 100644
index 0000000000000000000000000000000000000000..79a521e8f5089f78fc36fda73e987d40947b5be9
--- /dev/null
+++ b/LCS/MessageBus/test/MessageFuncs.sh.in
@@ -0,0 +1,182 @@
+#!/bin/bash
+#
+# Usage: source MessageFuncs.sh
+#
+
+function _on_exit() {
+  # Calls $1 on exit, while preserving existing EXIT traps
+
+  # Get existing EXIT traps
+  TRAPLINE=`trap -p EXIT`
+  ONEXITS=`echo $TRAPLINE | perl -ne 'print "$1\n" if /trap -- .(.*). EXIT/;'`
+
+  # Expand traps
+  trap -- "$1;$ONEXITS" EXIT
+}
+
+function _generate_prefix() {
+  # Generate a unique prefix for this test
+  NOW=`date +"%FT%T.%N"`
+
+  echo test-$NOW.
+}
+
+# Generate an unique prefix for all queues in this test
+export QUEUE_PREFIX=`_generate_prefix`
+echo "MessageBus: QUEUE_PREFIX=$QUEUE_PREFIX"
+
+function have_qpid() {
+  [ "@HAVE_QPID@" == "TRUE" ]
+}
+
+# A list of all queues we created
+CREATED_QUEUES=""
+
+function _get_host() {
+  #  input = host:queue -> output = host
+  #  input = queue      -> output = ''
+  HOSTQUEUE="$1"
+
+  echo "$HOSTQUEUE" | perl -ne 'print $1 if /(.*):/;'
+}
+function _get_queue() {
+  #  input = host:queue -> output = queue
+  #  input = queue      -> output = queue
+  HOSTQUEUE="$1"
+
+  echo "$HOSTQUEUE" | perl -ne 'print "$1$2" if /:(.*)|^([^:\n]*)$/;'
+}
+
+function _qpid_receive() {
+  HOSTQUEUE="$1"
+  OPTIONS="$2"
+  shift 2
+
+  QUEUE="`_get_queue "$HOSTQUEUE"`"
+  HOST="`_get_host "$HOSTQUEUE"`"
+
+  if [ "$HOST" == "" ]; then
+    HOST=127.0.0.1
+  fi
+
+  if have_qpid; then
+    @QPID_RECEIVE_EXECUTABLE@ \
+        -b "$HOST" \
+        -a "$QUEUE_PREFIX$QUEUE$OPTIONS" "$@"
+  fi
+}
+
+function _qpid_send() {
+  HOSTQUEUE="$1"
+  OPTIONS="$2"
+  shift 2
+
+  QUEUE="`_get_queue "$HOSTQUEUE"`"
+  HOST="`_get_host "$HOSTQUEUE"`"
+
+  if [ "$HOST" == "" ]; then
+    HOST=127.0.0.1
+  fi
+
+  if have_qpid; then
+    @QPID_SEND_EXECUTABLE@ \
+        -b "$HOST" \
+        -a "$QUEUE_PREFIX$QUEUE$OPTIONS" "$@"
+  fi
+}
+
+
+function create_queue() {
+  # Creates an empty queue
+  #
+  # Usage:
+  #   create_queue [host:]queue
+  HOSTQUEUE="$1"
+
+  echo "MessageBus: Creating queue $HOSTQUEUE"
+
+  _qpid_receive "$HOSTQUEUE" "; { create: always }" --print-content no --ignore-reply-to
+
+  # Update the list of queues we created
+  CREATED_QUEUES="$CREATED_QUEUES $HOSTQUEUE"
+}
+
+function delete_queue() {
+  # Empties and deletes a queue
+  #
+  # Usage:
+  #   delete_queue [host:]queue
+  #
+  # Will not remove used queues
+  HOSTQUEUE="$1"
+
+  echo "MessageBus: Deleting queue $HOSTQUEUE"
+
+  _qpid_receive "$HOSTQUEUE" "; { delete: always }" --print-content no --ignore-reply-to
+}
+
+function delete_all_queues() {
+  # Empties and deletes all queues created by create_queue
+  #
+  # Usage:
+  #   delete_all_queues
+
+  for QUEUE_NAME in $CREATED_QUEUES; do
+    delete_queue "$QUEUE_NAME"
+  done
+}
+
+# Automatically delete all unused queues (created by create_queue) on EXIT
+_on_exit delete_all_queues
+
+function recv_msg() {
+  # Retrieves one message from a queue
+  #
+  # Usage:
+  #   recv_msg [host:]queue > message
+  #
+  # Returns an empty message if none was available
+  HOSTQUEUE="$1"
+
+  _qpid_receive "$HOSTQUEUE" "" --ignore-reply-to -m 1
+}
+
+function recv_all_msgs() {
+  # Retrieves all messages from a queue
+  #
+  # Usage:
+  #   recv_all_msgs [host:]queue > messages
+  #
+  # Returns an empty message if none was available
+  HOSTQUEUE="$1"
+
+  _qpid_receive "$HOSTQUEUE" "" --ignore-reply-to -m 0
+}
+
+function send_msg() {
+  # Send one message to a queue
+  #
+  # Usage:
+  #   send_msg [host:]queue message
+  HOSTQUEUE="$1"
+  MESSAGE="$2"
+
+  _qpid_send "$HOSTQUEUE" "" --content-string "$MESSAGE"
+}
+
+function compare_msg() {
+  # Compare two messages, ignoring uncontrollable fields (UUID, timestamp).
+  # Both messages are expected to be in files (or filedescriptors).
+  #
+  # Usage:
+  #   compare_msg reference_message.txt generated_message.txt
+  REFERENCE="$1"
+  GENERATED="$2"
+
+  function compare_msg_filter() {
+    fgrep -v '<uuid>' | fgrep -v '<timestamp>'
+  }
+
+  diff -w <(<"$REFERENCE" compare_msg_filter) <(<"$GENERATED" compare_msg_filter)
+}
+
diff --git a/LCS/MessageBus/test/tMessage.cc b/LCS/MessageBus/test/tMessage.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cd0c4a8e49da767afa1262c6b7662d1dc2960acb
--- /dev/null
+++ b/LCS/MessageBus/test/tMessage.cc
@@ -0,0 +1,85 @@
+//#  Copyright (C) 2015
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: $
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <MessageBus/Message.h>
+
+//using namespace qpid::messaging;
+using namespace LOFAR;
+
+#if 0
+void showMessage(Message&	msg)
+{
+	cout << "Message ID    : " << msg.getMessageId() << endl;
+	cout << "User ID       : " << msg.getUserId() << endl;
+	cout << "Correlation ID: " << msg.getCorrelationId() << endl;
+	cout << "Subject       : " << msg.getSubject() << endl;
+	cout << "Reply to      : " << msg.getReplyTo() << endl;
+	cout << "Content type  : " << msg.getContentType() << endl;
+	cout << "Priority      : " << msg.getPriority() << endl;
+//	cout << "TTL           : " << msg.getTtl() << endl;
+	cout << "Durable       : " << (msg.getDurable() ? "Yes" : "No") << endl;
+	cout << "Redelivered   : " << (msg.getRedelivered() ? "Yes" : "No")  << endl;
+	cout << "Properties    : " << msg.getProperties() << endl;
+	cout << "Content size  : " << msg.getContentSize() << endl;
+	cout << "Content       : " << msg.getContent() << endl;
+}
+
+void compareMessages(Message&	lhm, Message& rhm)
+{
+	ASSERTSTR(lhm.getMessageId()     == rhm.getMessageId(),     "messageIDs differ");
+	ASSERTSTR(lhm.getUserId()        == rhm.getUserId(),        "UserIDs differ");
+	ASSERTSTR(lhm.getCorrelationId() == rhm.getCorrelationId(), "CorrelationIDs differ");
+	ASSERTSTR(lhm.getSubject()       == rhm.getSubject(),       "Subjects differ");
+	ASSERTSTR(lhm.getReplyTo()       == rhm.getReplyTo(),       "ReplyTos differ");
+	ASSERTSTR(lhm.getContentType()   == rhm.getContentType(),   "ContentTypes differ");
+	ASSERTSTR(lhm.getPriority()      == rhm.getPriority(),      "Priorities differ");
+	ASSERTSTR(lhm.getTtl()           == rhm.getTtl(),           "TTLs differ");
+	ASSERTSTR(lhm.getDurable()       == rhm.getDurable(),       "Durability differs");
+	ASSERTSTR(lhm.getRedelivered()   == rhm.getRedelivered(),   "Redelivered differs");
+//	ASSERTSTR(lhm.getProperties()    == rhm.getProperties(),    "Properties differ");
+	ASSERTSTR(lhm.getContentSize()   == rhm.getContentSize(),   "ContentSize differs");
+	ASSERTSTR(lhm.getContent()       == rhm.getContent(),       "Content differs");
+}
+#endif
+
+int main(int argc, char* argv[]) {
+	if (argc != 1) {
+		cout << "Syntax: " << argv[0] << endl;
+		return (1);
+	}
+
+	Message	msg1("mySubSystem", "user", "some test message", "lofar.observation.start", "1.0", "12345", "54321");
+
+	qpid::messaging::Message	qpMsg("Qpid message");
+	Message		msg2(qpMsg);
+	
+	string	KVmapje("abc=[aap,noot,mies]\nmyInteger=5\nmyDouble=3.14");
+	msg1.setTXTPayload(KVmapje);
+
+	cout << msg1;
+
+	return (0);
+}
+
diff --git a/LCS/MessageBus/test/tMsgBus.cc b/LCS/MessageBus/test/tMsgBus.cc
new file mode 100644
index 0000000000000000000000000000000000000000..14688926fa777573978e0b36f474feaab3270829
--- /dev/null
+++ b/LCS/MessageBus/test/tMsgBus.cc
@@ -0,0 +1,117 @@
+//#  Copyright (C) 2015
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: $
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <MessageBus/MsgBus.h>
+
+using namespace qpid::messaging;
+using namespace LOFAR;
+
+
+void showMessage(qpid::messaging::Message&	msg)
+{
+	cout << "Message ID    : " << msg.getMessageId() << endl;
+	cout << "User ID       : " << msg.getUserId() << endl;
+	cout << "Correlation ID: " << msg.getCorrelationId() << endl;
+	cout << "Subject       : " << msg.getSubject() << endl;
+	cout << "Reply to      : " << msg.getReplyTo() << endl;
+	cout << "Content type  : " << msg.getContentType() << endl;
+	cout << "Priority      : " << msg.getPriority() << endl;
+//	cout << "TTL           : " << msg.getTtl() << endl;
+	cout << "Durable       : " << (msg.getDurable() ? "Yes" : "No") << endl;
+	cout << "Redelivered   : " << (msg.getRedelivered() ? "Yes" : "No")  << endl;
+	cout << "Properties    : " << msg.getProperties() << endl;
+	cout << "Content size  : " << msg.getContentSize() << endl;
+	cout << "Content       : " << msg.getContent() << endl;
+}
+
+void compareMessages(qpid::messaging::Message&	lhm, qpid::messaging::Message& rhm)
+{
+	ASSERTSTR(lhm.getMessageId()     == rhm.getMessageId(),     "messageIDs differ");
+	ASSERTSTR(lhm.getUserId()        == rhm.getUserId(),        "UserIDs differ");
+	ASSERTSTR(lhm.getCorrelationId() == rhm.getCorrelationId(), "CorrelationIDs differ");
+	ASSERTSTR(lhm.getSubject()       == rhm.getSubject(),       "Subjects differ");
+	ASSERTSTR(lhm.getReplyTo()       == rhm.getReplyTo(),       "ReplyTos differ");
+	ASSERTSTR(lhm.getContentType()   == rhm.getContentType(),   "ContentTypes differ");
+	ASSERTSTR(lhm.getPriority()      == rhm.getPriority(),      "Priorities differ");
+	ASSERTSTR(lhm.getTtl()           == rhm.getTtl(),           "TTLs differ");
+	ASSERTSTR(lhm.getDurable()       == rhm.getDurable(),       "Durability differs");
+	ASSERTSTR(lhm.getRedelivered()   == rhm.getRedelivered(),   "Redelivered differs");
+//	ASSERTSTR(lhm.getProperties()    == rhm.getProperties(),    "Properties differ");
+	ASSERTSTR(lhm.getContentSize()   == rhm.getContentSize(),   "ContentSize differs");
+	ASSERTSTR(lhm.getContent()       == rhm.getContent(),       "Content differs");
+}
+
+
+int main(int argc, char* argv[]) {
+  INIT_LOGGER("tMsgBus");
+
+  MessageBus::init();
+
+  std::string queue(argc == 2 ? argv[1] : "tMsgBus");
+
+  cout << "Using queue " << queue << " (Syntax: " << argv[0] << " messagebus)" << endl;
+
+	cout << "--- Drain the queue ---" << endl;
+	FromBus	fb(queue);
+	LOFAR::Message	receivedMsg;
+	while (fb.getMessage(receivedMsg, 0.01)) {
+		fb.ack(receivedMsg);
+	}
+
+	cout << "--- TEST 1: create a message from a string, send it, receive it, print it. --- " << endl;
+	ToBus	tb(queue);
+	string	someText("An example message constructed from text");
+	tb.send(someText);
+	fb.getMessage(receivedMsg);
+	fb.ack(receivedMsg);
+	showMessage(receivedMsg.qpidMsg());
+
+	cout << "--- TEST 2: create a message by hand, send it, receive it, print it, compare them. --- " << endl;
+	LOFAR::Message		msg2Send;
+	msg2Send.setTXTPayload("Manually constructed message");
+	tb.send(msg2Send);
+	fb.getMessage(receivedMsg);
+	fb.ack(receivedMsg);
+	showMessage(receivedMsg.qpidMsg());
+	compareMessages(msg2Send.qpidMsg(), receivedMsg.qpidMsg());
+
+	cout << "--- TEST 3: add an extra queue, send messages to both queues, receive them. --- " << endl;
+	ToBus	tbExtra("tMsgBus-extraTestQ");
+	tbExtra.send("Message send to extra queue");
+	tb.send("Message send to original queue");
+
+	fb.addQueue("tMsgBus-extraTestQ");
+	fb.getMessage(receivedMsg);
+    fb.ack(receivedMsg);
+    showMessage(receivedMsg.qpidMsg());
+    fb.getMessage(receivedMsg);
+    fb.ack(receivedMsg);
+    showMessage(receivedMsg.qpidMsg());
+
+	cout << "--- All test successful! ---" << endl;
+
+	return (0);
+}
+
diff --git a/LCS/MessageBus/test/tMsgBus.run b/LCS/MessageBus/test/tMsgBus.run
new file mode 100755
index 0000000000000000000000000000000000000000..52872de3543ef87e064670700f9bcd882843fb17
--- /dev/null
+++ b/LCS/MessageBus/test/tMsgBus.run
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+source MessageFuncs.sh
+
+create_queue tMsgBus
+create_queue tMsgBus-extraTestQ
+
+./tMsgBus
diff --git a/LCS/MessageBus/test/tMsgBus.sh b/LCS/MessageBus/test/tMsgBus.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5dbd572389fbed059f2b93fe10ca70f52458f7f5
--- /dev/null
+++ b/LCS/MessageBus/test/tMsgBus.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+./runctest.sh tMsgBus
diff --git a/LCS/MessageDaemons/CMakeLists.txt b/LCS/MessageDaemons/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e7f292a5c6dff46d05688ea7b0f53f7874483476
--- /dev/null
+++ b/LCS/MessageDaemons/CMakeLists.txt
@@ -0,0 +1,5 @@
+# $Id$
+
+lofar_package(MessageDaemons 1.0 DEPENDS MessageBus)
+
+add_subdirectory(src)
diff --git a/LCS/MessageDaemons/src/CMakeLists.txt b/LCS/MessageDaemons/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..89821db1ee3b2a69c5c724524c9ea48865fec2db
--- /dev/null
+++ b/LCS/MessageDaemons/src/CMakeLists.txt
@@ -0,0 +1,20 @@
+# $Id$
+
+include(LofarPackageVersion)
+
+set(messagedaemons_LIB_SRCS
+  Package__Version.cc)
+
+lofar_add_library(messagedaemons ${messagedaemons_LIB_SRCS})
+
+install(FILES
+  MessageRouter
+  DESTINATION bin)
+
+file(GLOB MessageRouterConfs
+  MessageRouter.conf*
+  )
+
+install(FILES
+  ${MessageRouterConfs}
+  DESTINATION etc)
diff --git a/LCS/MessageDaemons/src/MessageRouter b/LCS/MessageDaemons/src/MessageRouter
new file mode 100644
index 0000000000000000000000000000000000000000..873663507e07f35050cffa6ff2fa0279aac8fdb7
--- /dev/null
+++ b/LCS/MessageDaemons/src/MessageRouter
@@ -0,0 +1,146 @@
+#!/usr/bin/python
+# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# id.. TDB
+"""Very basic messagebus router that routs the messages according to the settings in Router.conf
+"""
+
+import lofar.messagebus.basemsgbus as msgbus
+#import lofar.messagebus.message as message
+
+import threading
+from ConfigParser import SafeConfigParser
+import os.path
+from datetime import datetime
+
+def log(level, msg):
+  print "%s %-5s %s" % (datetime.now(), level, msg)
+
+class BusMulticast(threading.Thread):
+  """
+  Sets up the router from one inbus to several outbusses
+  """
+  def __init__(self, source, destlist):
+    threading.Thread.__init__(self)
+    self.source   = source
+    self.destlist = destlist
+
+  def run(self):
+    inbus = msgbus.FromBus(self.source)
+    outbusses = [msgbus.ToBus(dest) for dest in self.destlist]
+
+    log("INFO","Forwarding %s -> %s" % (self.source,self.destlist))
+
+    while True:
+      # TODO: Use a transaction (not supported yet in qpid 0.30)
+
+      msg = inbus.get()
+      if msg is None:
+        log("ERROR","Received 'None' message from %s" % (self.source,))
+        continue
+
+      log("INFO","Msg received from %s" % (self.source))
+
+      for outbus in outbusses:
+        outbus.send(msg)
+      inbus.ack(msg)
+
+      log("INFO","Forwarded %s -> %s" % (self.source,self.destlist))
+
+class RouterConfig(SafeConfigParser):
+  """
+    Router configuration. Example:
+
+    [multicast]
+    source-queue-1: dest-queue-1, dest-queue2
+    source-queue-2: dest-queue-3
+
+  """
+  def __init__(self, filename=None):
+    SafeConfigParser.__init__(self)
+
+    # set defaults
+    self.add_section('multicast')
+
+    # read configuration
+    if filename is not None:
+      self.read(filename)
+
+  def read(self, filename):
+    log("INFO","[RouterConfig] Considering reading %s" % (filename,))
+    if not os.path.isfile(filename):
+      return False
+
+    log("INFO","[RouterConfig] Reading %s" % (filename,))
+    SafeConfigParser.read(self, filename)
+    return True
+
+  def sources(self):
+    return self.options('multicast')
+
+  def destinations(self, source):
+    return [field.strip() for field in self.get('multicast', source).split(',')]
+
+if __name__ == "__main__":
+  """
+    Apply the routing specified in router.conf and router.conf.`hostname`;
+    both configration files are found in $LOFARROOT/etc, or . if $LOFARROOT is
+    not set.
+
+    Application runs forever, regardless of the number of routes. Also runs
+    forever if no routing is required, to keep behaviour consistent across
+    nodes.
+  """
+  import os
+  import platform
+  import time
+
+  if "LOFARROOT" in os.environ:
+    path = os.path.expandvars("$LOFARROOT/etc")
+  else:
+    path = "."
+
+  # read default config file
+  config = RouterConfig('%s/MessageRouter.conf' % path)
+
+  # read host-specific config file
+  my_configfile = '%s/MessageRouter.conf.%s' % (path, platform.node().lower()) # = hostname
+  config.read(my_configfile)
+
+  threadlist = []
+
+  # set up router
+  for source in config.sources():
+    destlist = config.destinations(source)
+
+    t = BusMulticast(source, destlist)
+    t.start()
+    threadlist.append(t)
+
+  log("INFO","[main] Running %s threads" % (len(threadlist),))
+
+  if not threadlist:
+    # stall forever (future: allow rereading config from config file? command queue?)
+    log("INFO","[main] Nothing to do. Sleeping forever.");
+    while True:
+      time.sleep(60)
+  else:
+    # wait for join (forever)
+    for t in threadlist:
+      t.join()
+
diff --git a/LCS/MessageDaemons/src/MessageRouter.conf.ccu001 b/LCS/MessageDaemons/src/MessageRouter.conf.ccu001
new file mode 120000
index 0000000000000000000000000000000000000000..e63542263b7d53a99b30f12d189c9e516bcfebf4
--- /dev/null
+++ b/LCS/MessageDaemons/src/MessageRouter.conf.ccu001
@@ -0,0 +1 @@
+MessageRouter.conf.ccu099
\ No newline at end of file
diff --git a/LCS/MessageDaemons/src/MessageRouter.conf.ccu099 b/LCS/MessageDaemons/src/MessageRouter.conf.ccu099
new file mode 100644
index 0000000000000000000000000000000000000000..c5249afdb23e4b517cfdf3f7ff242af74ddfb8f9
--- /dev/null
+++ b/LCS/MessageDaemons/src/MessageRouter.conf.ccu099
@@ -0,0 +1,10 @@
+[multicast]
+#
+# Routing tables
+#
+# source                             destinations
+lofar.task.feedback.dataproducts:  otdb.task.feedback.dataproducts, local.copy.dataproducts
+lofar.task.feedback.processing:    otdb.task.feedback.processing, local.copy.processing
+lofar.task.feedback.state:         mac.task.feedback.state, local.copy.state
+lofar.task.specification.system:   local.copy.specification.system
+
diff --git a/LCS/pyparameterset/src/pyparameterset.cc b/LCS/pyparameterset/src/pyparameterset.cc
index 20aad23021b650694a8d5a656f5b99d2911aec58..22a54009774401654e555cf47617ef26cf45918a 100644
--- a/LCS/pyparameterset/src/pyparameterset.cc
+++ b/LCS/pyparameterset/src/pyparameterset.cc
@@ -87,6 +87,15 @@ namespace LOFAR {
     void adoptCollection (const PyParameterSet& parset, const string& prefix)
       { return ParameterSet::adoptCollection (parset, prefix); }
 
+    string __str__() const
+      { string buffer; writeBuffer(buffer); return buffer; }
+
+    string __getstate__() const
+      { return __str__(); }
+
+    void __setstate__(const string& state)
+      { adoptBuffer(state); }
+
     PyParameterValue get (const string& key) const
       { return ParameterSet::get (key); }
 
@@ -174,6 +183,58 @@ namespace LOFAR {
   vector<string> (ParameterSet::*fgetvecstring2)(const string&, const vector<string>&, bool) const =
     &ParameterSet::getStringVector;
 
+  // Define pickling/unpickling information
+  struct pyparameterset_pickle_suite : boost::python::pickle_suite
+  {
+    /*
+    static
+    boost::python::tuple
+    gtinitargs(const world& w)
+    {
+        return boost::python::make_tuple(w.get_country());
+    }
+    */
+
+    static
+    boost::python::tuple
+    getstate(boost::python::object obj)
+    {
+        PyParameterSet const& ps = boost::python::extract<PyParameterSet const&>(obj)();
+
+        return boost::python::make_tuple(
+            obj.attr("__dict__"),
+            ps.__str__());
+    }
+
+    static
+    void
+    setstate(boost::python::object obj, boost::python::tuple state)
+    {
+        using namespace boost::python;
+        PyParameterSet& ps = extract<PyParameterSet&>(obj)();
+
+        if (len(state) != 2)
+        {
+          PyErr_SetObject(PyExc_ValueError,
+                          ("expected 2-item tuple in call to __setstate__; got %s"
+                           % state).ptr()
+              );
+          throw_error_already_set();
+        }
+
+        // restore the object's __dict__
+        dict d = extract<dict>(obj.attr("__dict__"))();
+        d.update(state[0]);
+
+        // restore the internal state of the C++ object
+        string parsetStr = extract<string>(state[1]);
+        ps.adoptBuffer(parsetStr);
+    }
+
+    static bool getstate_manages_dict() { return true; }
+  };
+
+
 
   // Define the python interface to ParameterValue.
   void pyparametervalue()
@@ -226,6 +287,7 @@ namespace LOFAR {
       .def (init<PyParameterSet>())
       .def (init<bool, int, int>())
       .def (init<std::string, bool>())
+      .def_pickle(pyparameterset_pickle_suite())
       .def ("version", &PyParameterSet::version,
             (boost::python::arg("type")="other"),
             "Get the software version.")
@@ -252,6 +314,8 @@ namespace LOFAR {
  	    (boost::python::arg("filename"),
              boost::python::arg("append")=false),
             "Write the parameterset into a parset file with the given name.")
+      .def ("__str__", &PyParameterSet::__str__,
+            "Return the full parset as a string")
       .def ("add", fadd,
  	    (boost::python::arg("key"),
              boost::python::arg("value")),
diff --git a/LCS/pyparameterset/test/tpyparameterset.py b/LCS/pyparameterset/test/tpyparameterset.py
index be0dd2cd79b183950a98d4add4bb4b9c1bea2f22..272d166282c85d056e6886cec71f34d5b7d6eff6 100644
--- a/LCS/pyparameterset/test/tpyparameterset.py
+++ b/LCS/pyparameterset/test/tpyparameterset.py
@@ -67,7 +67,7 @@ print ps.version("top")
 print ps.version()
 print "<<<"
 ps.add ("a.b", "7")
-ps.add ("a.b.lange_naam", "dit is nu een andere naam geworden met extra spaties aan het einde  ")
+ps.add ("a.b.lange_naam", "dit is nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen")
 ps.add ("a.b.c", "5")
 ps.add ("a.b.double", "3.1415926")
 ps.add ("a.b.bool", "true")
@@ -88,3 +88,12 @@ print pss.makeSubset('b.', 'aa.bb.').keys()
 print pss.makeSubset('b.').size()
 print pss.makeSubset('cc').keys()    # should be empty
 print len(pss.makeSubset('cc'))
+
+# Check str()
+print str(ps)
+
+# Check picking/unpickling
+import cPickle as pickle
+s = pickle.dumps(ps)
+ps2 = pickle.loads(s)
+assert str(ps) == str(ps2)
diff --git a/LCS/pyparameterset/test/tpyparameterset.stdout b/LCS/pyparameterset/test/tpyparameterset.stdout
index d11dc795152badf639efae6bf85e38e2a36b202b..287a9a8ebc8cd221ce48bf3b902f9b97dd3b6275 100644
--- a/LCS/pyparameterset/test/tpyparameterset.stdout
+++ b/LCS/pyparameterset/test/tpyparameterset.stdout
@@ -38,6 +38,50 @@ True
 [1, 2, 3, 10, 10, 10, 10, 10]
 [5, 6, 7, 8, 9, 10]
 
+>>>
+parameterset: version = LOFAR-Task7336 (in CMakeLists.txt: 1.0)
+ overall revision  = 30929
+ package revision  = 30927 (last change in package)
+ built on cbt009 by mol at Feb 10 2015 11:04:26
+  2 files were different from the repository
+ tree of packages used: 
+  pyparameterset-LOFAR-Task7336 (rev.30929)
+   pytools-LOFAR-Task7336 (rev.30929)
+    Common-LOFAR-Task7336 (rev.30929)
+
+parameterset: version = LOFAR-Task7336 (in CMakeLists.txt: 1.0)
+ overall revision  = 30929
+ package revision  = 30927 (last change in package)
+ built on cbt009 by mol at Feb 10 2015 11:04:26
+  2 files were different from the repository
+ packages used: 
+
+  pytools: version = LOFAR-Task7336 (in CMakeLists.txt: 1.0)
+   overall revision  = 30929
+   package revision  = 30536 (last change in package)
+   built on cbt009 by mol at Feb 10 2015 10:37:11
+
+  Common: version = LOFAR-Task7336 (in CMakeLists.txt: 3.3)
+   overall revision  = 30929
+   package revision  = 30651 (last change in package)
+   built on cbt009 by mol at Feb 10 2015 10:37:07
+
+parameterset: version = LOFAR-Task7336 (in CMakeLists.txt: 1.0)
+ overall revision  = 30929
+ package revision  = 30927 (last change in package)
+ built on cbt009 by mol at Feb 10 2015 11:04:26
+  2 files were different from the repository
+
+parameterset: version = LOFAR-Task7336 (in CMakeLists.txt: 1.0)
+ overall revision  = 30929
+ package revision  = 30927 (last change in package)
+ built on cbt009 by mol at Feb 10 2015 11:04:26
+  2 files were different from the repository
+ packages used: 
+  pytools-LOFAR-Task7336 (rev.30929)
+  Common-LOFAR-Task7336 (rev.30929)
+
+<<<
 ['a.b', 'a.b.bool', 'a.b.c', 'a.b.double', 'a.b.lange_naam', 'e.g', 'egg', 'vec', 'vecbool', 'vecexp', 'vecnest']
 False
 True
@@ -45,7 +89,7 @@ True
 7
 7
 aa
-dit is nu een andere naam geworden met extra spaties aan het einde  
+dit is nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen
 True
 True
 False
@@ -84,3 +128,15 @@ b.c = 5
 4
 []
 0
+a.b=7
+a.b.bool=true
+a.b.c=5
+a.b.double=3.1415926
+a.b.lange_naam=dit is nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen
+e.g=een voorbeeld
+egg=een ei
+vec=[1,2,3]
+vecbool=[true,false,true]
+vecexp=[1..3,5..10]
+vecnest=[[1..3,5*10],[5..10]]
+
diff --git a/MAC/APL/APLCommon/src/swlevel b/MAC/APL/APLCommon/src/swlevel
index 7d02ef091231df0f81f5b2855be015ba05ee7ca3..fd40de6370890cad8883f05be135e2116a1e4ef9 100644
--- a/MAC/APL/APLCommon/src/swlevel
+++ b/MAC/APL/APLCommon/src/swlevel
@@ -175,7 +175,7 @@ start_prog()
 	fi
 
 	# Check if program is already running
-	/sbin/pidof ${prog} 1>/dev/null 2>&1
+	/sbin/pidof -x ${prog} 1>/dev/null 2>&1
 	if [ $? -ne 0 ]; then
 		curdate=`date +%Y%m%dT%H%M%S`
 		# PVSS needs special treatment
@@ -248,7 +248,7 @@ stop_prog()
 	fi
 
 	# get processlist
-	/sbin/pidof ${prog} 1>/dev/null 2>&1
+	/sbin/pidof -x ${prog} 1>/dev/null 2>&1
 	if [ $? -ne 0 ]; then
 		return
 	fi
@@ -267,7 +267,7 @@ stop_prog()
 	fi
 
 	# first try normal kill
-	for pid in `/sbin/pidof ${prog}`
+	for pid in `/sbin/pidof -x ${prog}`
 	do 
 		echo "Softly killing ${prog}(${pid})"
 		$asroot kill $pid 1>/dev/null 2>&1
@@ -275,7 +275,7 @@ stop_prog()
 	done
 
 	# when normal kill did not work, kill is with -9
-	for pid in `/sbin/pidof ${prog}`
+	for pid in `/sbin/pidof -x ${prog}`
 	do 
 		echo "Hard killing ${prog}(${pid})"
 		$asroot kill -9 $pid 1>/dev/null 2>&1
@@ -283,7 +283,7 @@ stop_prog()
 	done
         # if user0 or lofarsys, try normal kill as root 	 
 	
-	for pid in `/sbin/pidof ${prog}` 	 
+	for pid in `/sbin/pidof -x ${prog}` 	 
 	do 	 
 	    if [ "$user" == "user0" -o "$user" == "lofarsys" ]; then 	 
 	      sudo kill $pid 1>/dev/null 2>&1 	 
@@ -292,7 +292,7 @@ stop_prog()
 	done 	 
 	  	 
 	# if user0 or lofarsys, try hard kill as root 	 
-	for pid in `/sbin/pidof ${prog}` 	 
+	for pid in `/sbin/pidof -x ${prog}` 	 
 	do 	 
 	    if [ "$user" == "user0" -o "$user" == "lofarsys" ]; then 	 
 		sudo kill -9 $pid 1>/dev/null 2>&1 	 
@@ -301,7 +301,7 @@ stop_prog()
 	done 	 
 	  	 
 	# if still alive, write a message 	 
-	for pid in `/sbin/pidof ${prog}` 	 
+	for pid in `/sbin/pidof -x ${prog}` 	 
 	do 	 
 	  echo -n "Could not kill ${prog}(${pid}); " 	 
 	  if [ "$user" == "user0" -o "$user" == "lofarsys" ]; then 	 
@@ -350,9 +350,9 @@ status_prog()
 		# find out the processID of the possibly (running) process
 		obsid=()
 		pid_user=()
-		/sbin/pidof ${prog} 1>/dev/null 2>&1
+		/sbin/pidof -x ${prog} 1>/dev/null 2>&1
 		if [ $? -eq 0 ]; then
-			pid=( `/sbin/pidof ${prog}` )
+			pid=( `/sbin/pidof -x ${prog}` )
 			i=0
 			for apid in ${pid[@]}
 			do
diff --git a/MAC/APL/APLCommon/src/swlevel.conf b/MAC/APL/APLCommon/src/swlevel.conf
index 6abc540fac70337cac2e0b516d55819dde4d5d63..b9e9922bc3e9c9f8c98324c6576b1c8a59d9cf75 100644
--- a/MAC/APL/APLCommon/src/swlevel.conf
+++ b/MAC/APL/APLCommon/src/swlevel.conf
@@ -4,6 +4,7 @@
 # Table to manage the progrma that should be started and stopped
 # level : up : down : root : mpi : program
 #
+1:u:d:::MessageRouter
 1:u:d:::PVSS00pmon
 1:u:d:::SoftwareMonitor
 1:u:d:::LogProcessor
@@ -11,6 +12,7 @@
 1:u:d:::ServiceBroker
 1:u:d:::SASGateway
 1:u:d:::PVSSGateway
+1:u:d:::FeedbackService
 #
 2:u:d:r::_EPAStub
 2:u:d:r::RSPDriver
diff --git a/MAC/APL/CEPCU/CMakeLists.txt b/MAC/APL/CEPCU/CMakeLists.txt
index f7b97cd31136c339dbcd2294693f547b144465fd..8013b1c814bc7c99ebd974c861b1539933205631 100644
--- a/MAC/APL/CEPCU/CMakeLists.txt
+++ b/MAC/APL/CEPCU/CMakeLists.txt
@@ -1,7 +1,7 @@
 # $Id$
 
 # Do not split the following line, otherwise makeversion will fail!
-lofar_package(CEPCU 1.0 DEPENDS Common ApplCommon MACIO GCFTM GCFRTDB APLCommon RTDBCommon OTDB Stream)
+lofar_package(CEPCU 1.0 DEPENDS Common ApplCommon MACIO GCFTM GCFRTDB APLCommon RTDBCommon OTDB Stream MessageBus)
 
 include(LofarFindPackage)
 lofar_find_package(Boost REQUIRED COMPONENTS date_time)
diff --git a/MAC/APL/CEPCU/src/OnlineControl/CMakeLists.txt b/MAC/APL/CEPCU/src/OnlineControl/CMakeLists.txt
index 04c131069de8e6f5572de6bf0185a3c8d60aacdc..753e334b009b96c1ba092e218d5ccf65202568dd 100644
--- a/MAC/APL/CEPCU/src/OnlineControl/CMakeLists.txt
+++ b/MAC/APL/CEPCU/src/OnlineControl/CMakeLists.txt
@@ -12,3 +12,7 @@ lofar_add_bin_program(OnlineControl
   forkexec.cc)
 
 lofar_add_executable(tPVSSMapping tPVSSMapping.cc)
+
+install(FILES
+  OnlineControl.conf
+  DESTINATION etc)
diff --git a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.cc b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.cc
index 8fd5d8e1b2fa0a6d5803ac070aeeac8a68bcaeb2..6afb4bb872440cdccfe704581360c215772750f7 100644
--- a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.cc
+++ b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.cc
@@ -31,6 +31,7 @@
 #include <Common/Exceptions.h>
 #include <Common/SystemUtil.h>
 #include <Common/hexdump.h>
+#include <MessageBus/Message.h>
 #include <ApplCommon/StationInfo.h>
 #include <ApplCommon/Observation.h>
 #include <ApplCommon/LofarDirs.h>
@@ -65,6 +66,8 @@ namespace LOFAR {
 // static pointer to this object for signal handler
 static OnlineControl*	thisOnlineControl = 0;
 
+const double QUEUE_POLL_TIMEOUT = 1.0;
+
 //
 // OnlineControl()
 //
@@ -80,9 +83,9 @@ OnlineControl::OnlineControl(const string&	cntlrName) :
 	itsForcedQuitTimer	(0),
 	itsLogControlPort	(0),
 	itsState			(CTState::NOSTATE),
-	itsFeedbackListener	(0),					// QUICK FIX #4022
-	itsFeedbackPort		(0),					// QUICK FIX #4022
-	itsFeedbackResult	(CT_RESULT_NO_ERROR),	// QUICK FIX #4022
+	itsMsgQueue			(0),
+	itsQueueTimer		(0),
+	itsFeedbackResult	(CT_RESULT_NO_ERROR),
 	itsTreePrefix       (""),
 	itsInstanceNr       (0),
 	itsStartTime        (),
@@ -110,14 +113,13 @@ OnlineControl::OnlineControl(const string&	cntlrName) :
 	// need port for timers.
 	itsTimerPort = new GCFTimerPort(*this, "TimerPort");
 	ASSERTSTR(itsTimerPort, "Can't allocate the timer!");
+    itsQueueTimer = new GCFTimerPort(*this, "MsgQTimer");
+    ASSERTSTR(itsQueueTimer, "Cannot allocate queue timer");
 
 	// Controlport to logprocessor
 	itsLogControlPort = new GCFTCPPort(*this, MAC_SVCMASK_CEPLOGCONTROL, GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
 	ASSERTSTR(itsLogControlPort, "Can't allocate the logControlPort");
 
-	// QUICK FIX #4022
-	itsFeedbackListener = new GCFTCPPort (*this, "Feedbacklistener", GCFPortInterface::MSPP, CONTROLLER_PROTOCOL);
-	ASSERTSTR(itsFeedbackListener, "Cannot allocate TCP port for feedback");
 	itsForcedQuitTimer = new GCFTimerPort(*this, "EmergencyTimer");
 	ASSERTSTR(itsForcedQuitTimer, "Can't allocate the emergency timer!");
 	itsForceTimeout = globalParameterSet()->getTime("emergencyTimeout", 3600);
@@ -141,14 +143,9 @@ OnlineControl::~OnlineControl()
 		delete itsLogControlPort;
 	}
 
-	if (itsTimerPort) {
-		delete itsTimerPort;
-	}
-
-	if (itsFeedbackListener) {
-		itsFeedbackListener->close();
-		delete itsFeedbackListener;
-	}
+	delete itsTimerPort;
+	delete itsQueueTimer;
+	delete itsMsgQueue;
 }
 
 //
@@ -268,11 +265,12 @@ GCFEvent::TResult OnlineControl::initial_state(GCFEvent& event, GCFPortInterface
 		itsParentPort = itsParentControl->registerTask(this);
 		// results in CONTROL_CONNECT
 
-		// QUICK FIX #4022
-		uint32	obsID = globalParameterSet()->getUint32("Observation.ObsID");
-		LOG_INFO_STR("Openening feedback port for OLAP: " << MAC_ONLINE_FEEDBACK_QF + obsID%1000);
-		itsFeedbackListener->setPortNumber(MAC_ONLINE_FEEDBACK_QF + obsID%1000);
-		itsFeedbackListener->open();	// will result in F_CONN
+		// open connection with messagebus
+		if (!itsMsgQueue) {
+			string	queueName = globalParameterSet()->getString("TaskStateQueue");
+			itsMsgQueue = new FromBus(queueName);
+			LOG_INFO_STR("Starting to listen on " << queueName);
+		}
 
 		LOG_DEBUG ("Going to operational state");
 		TRAN(OnlineControl::active_state);				// go to next state.
@@ -310,11 +308,7 @@ GCFEvent::TResult OnlineControl::active_state(GCFEvent& event, GCFPortInterface&
 		// update PVSS
 		itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString("active"));
 		itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString(""));
-	} break;
-
-	// QUICKFIX #4022
-	case F_ACCEPT_REQ: {
-		_handleAcceptRequest(port);
+		itsQueueTimer->setTimer(QUEUE_POLL_TIMEOUT);
 	} break;
 
 	case F_CONNECTED: {
@@ -326,18 +320,35 @@ GCFEvent::TResult OnlineControl::active_state(GCFEvent& event, GCFPortInterface&
 		_handleDisconnect(port);
 	} break;
 
-	// QUICKFIX #4022
-	case F_DATAIN: {
-		_handleDataIn(port);
-	} break;
-
 	case DP_CHANGED:
 		_databaseEventHandler(event);
 		break;
 
 	case F_TIMER:  {
 		GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
-		if (timerEvent.id == itsStopTimerID) {
+		if (&port == itsQueueTimer) {
+			Message	msg;
+			if (itsMsgQueue->getMessage(msg, 0.1)) {
+				string	obsIDstr = msg.getXMLvalue("message.header.ids.sasid");
+				LOG_INFO_STR("Received message from task " << obsIDstr);
+				if (atoi(obsIDstr.c_str()) == itsObsID) {
+					string	result = msg.getXMLvalue("message.payload.task.state");
+					if (result == "aborted") {
+						itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
+					}
+					else if (result != "finished") {
+						LOG_FATAL_STR("Unknown result received from correlator: " << result << " assuming failure!");
+						itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
+					}
+					LOG_INFO_STR("Received '" << result << "' on the messagebus");
+					itsMsgQueue->ack(msg);
+					TRAN(OnlineControl::finishing_state);
+					break;
+				} // my obsid
+			} // getMsg
+			itsQueueTimer->setTimer(QUEUE_POLL_TIMEOUT);
+		}
+		else if (timerEvent.id == itsStopTimerID) {
 			LOG_DEBUG("StopTimer expired, starting QUIT sequence");
 			itsStopTimerID = 0;
 			_setState(CTState::QUIT);
@@ -360,9 +371,10 @@ GCFEvent::TResult OnlineControl::active_state(GCFEvent& event, GCFPortInterface&
 		CONTROLConnectEvent		msg(event);
 		LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")");
 		itsMyName = msg.cntlrName;
+		itsObsID  = getObservationNr(msg.cntlrName);
 		// first inform CEPlogProcessor
 		CONTROLAnnounceEvent		announce;
-		announce.observationID = toString(getObservationNr(msg.cntlrName));
+		announce.observationID = toString(itsObsID);
 		itsLogControlPort->send(announce);
 		// execute this state
 		_setState(CTState::CONNECT);
@@ -442,45 +454,6 @@ GCFEvent::TResult OnlineControl::active_state(GCFEvent& event, GCFPortInterface&
 	return (status);
 }
 
-//
-// completing_state(event, port)
-//
-//
-GCFEvent::TResult OnlineControl::completing_state(GCFEvent& event, GCFPortInterface& port)
-{
-	LOG_INFO_STR ("completing:" << eventName(event) << "@" << port.getName());
-
-	switch (event.signal) {
-	case F_ENTRY: {
-		// update PVSS
-		itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString("completing"));
-		itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString(""));
-		itsInFinishState = true;
-
-		_passMetadatToOTDB();
-
-		TRAN(OnlineControl::finishing_state);
-	} break;
-
-	case F_TIMER:
-		break;
-
-	case F_DISCONNECTED:
-		_handleDisconnect(port);
-		break;
-
-	case F_DATAIN:
-		_handleDataIn(port);
-		break;
-
-	default:
-		LOG_DEBUG("completing state default");
-		return (GCFEvent::NOT_HANDLED);
-	}
-
-	return (GCFEvent::HANDLED);
-}
-
 //
 // finishing_state(event, port)
 //
@@ -511,10 +484,6 @@ GCFEvent::TResult OnlineControl::finishing_state(GCFEvent& event, GCFPortInterfa
 		_handleDisconnect(port);
 		break;
 
-	case F_DATAIN:
-		_handleDataIn(port);
-		break;
-
 	default:
 		LOG_DEBUG("finishing_state default");
 		return (GCFEvent::NOT_HANDLED);
@@ -798,91 +767,6 @@ void OnlineControl::_clearCobaltDatapoints()
 	delete myDPservice;
 }
 
-//
-// _passMetadatToOTDB();
-// THIS ROUTINE IS A MODIFIED COPY FROM PYTHONCONTROL.CC
-//
-void OnlineControl::_passMetadatToOTDB()
-{
-	// No name specified?
-	bool	metadataFileAvailable (true);
-	uint32	obsID(globalParameterSet()->getUint32("Observation.ObsID", 0));
-	string  feedbackFile = observationParset(obsID)+"_feedback";
-	LOG_INFO_STR ("Expecting metadata to be in file " << feedbackFile);
-	if (feedbackFile.empty()) {
-		metadataFileAvailable = false;
-	}
-
-	// read parameterset
-	// Try to setup the connection with the database
-	string	confFile = globalParameterSet()->getString("OTDBconfFile", "SASGateway.conf");
-	ConfigLocator	CL;
-	string	filename = CL.locate(confFile);
-	LOG_INFO_STR("Trying to read database information from file " << filename);
-	ParameterSet	otdbconf;
-	otdbconf.adoptFile(filename);
-	string database = otdbconf.getString("SASGateway.OTDBdatabase");
-	string dbhost   = otdbconf.getString("SASGateway.OTDBhostname");
-	OTDBconnection  conn("paulus", "boskabouter", database, dbhost);
-	if (!conn.connect()) {
-		LOG_FATAL_STR("Cannot connect to database " << database << " on machine " << dbhost);
-		// WE DO HAVE A PROBLEM HERE BECAUSE THIS PIPELINE CANNOT BE SET TO FINISHED IN SAS.
-		return;
-	}
-	LOG_INFO_STR("Connected to database " << database << " on machine " << dbhost);
-
-	if (metadataFileAvailable) {
-		try {
-			TreeValue   tv(&conn, getObservationNr(getName()));
-			ParameterSet	metadata;
-			metadata.adoptFile(feedbackFile);
-			// Loop over the parameterset and send the information to the KVTlogger.
-			// During the transition phase from parameter-based to record-based storage in OTDB the
-			// nodenames ending in '_' are implemented both as parameter and as record.
-			ParameterSet::iterator		iter = metadata.begin();
-			ParameterSet::iterator		end  = metadata.end();
-			while (iter != end) {
-				string	key(iter->first);	// make destoyable copy
-				rtrim(key, "[]0123456789");
-		//		bool	doubleStorage(key[key.size()-1] == '_');
-				bool	isRecord(iter->second.isRecord());
-				//   isRecord  doubleStorage
-				// --------------------------------------------------------------
-				//      Y          Y           store as record and as parameters
-				//      Y          N           store as parameters
-				//      N          *           store parameter
-				if (!isRecord) {
-					LOG_DEBUG_STR("BASIC: " << iter->first << " = " << iter->second);
-					tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
-				}
-				else {
-		//			if (doubleStorage) {
-		//				LOG_DEBUG_STR("RECORD: " << iter->first << " = " << iter->second);
-		//				tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
-		//			}
-					// to store is a node/param values the last _ should be stipped of
-					key = iter->first;		// destroyable copy
-		//			string::size_type pos = key.find_last_of('_');
-		//			key.erase(pos,1);
-					ParameterRecord	pr(iter->second.getRecord());
-					ParameterRecord::const_iterator	prIter = pr.begin();
-					ParameterRecord::const_iterator	prEnd  = pr.end();
-					while (prIter != prEnd) {
-						LOG_DEBUG_STR("ELEMENT: " << key+"."+prIter->first << " = " << prIter->second);
-						tv.addKVT(key+"."+prIter->first, prIter->second, ptime(microsec_clock::local_time()));
-						prIter++;
-					}
-				}
-				iter++;
-			}
-			LOG_INFO_STR(metadata.size() << " metadata values send to SAS");
-		}
-		catch (APSException &e) {
-			// Parameterfile not found
-			LOG_FATAL(e.text());
-		}
-	}
-}
 // -------------------- Application-order administration --------------------
 
 //
@@ -891,55 +775,6 @@ void OnlineControl::_passMetadatToOTDB()
 void OnlineControl::_handleDisconnect(GCFPortInterface& port)
 {
 	port.close();
-	// QUICKFIX #4022
-	if (&port == itsFeedbackPort) {
-		LOG_INFO_STR("Lost connection with Feedback of OLAP.");
-		delete itsFeedbackPort;
-		itsFeedbackPort = 0;
-	}
-}
-
-//
-// _handleAcceptRequest(port)
-//
-void OnlineControl::_handleAcceptRequest(GCFPortInterface& port)
-{
-	ASSERTSTR(&port == itsFeedbackListener, "Incoming connection on main listener iso feedbackListener");
-	itsFeedbackPort = new GCFTCPPort();
-	itsFeedbackPort->init(*this, "feedback", GCFPortInterface::SPP, 0, true);   // raw port
-	if (!itsFeedbackListener->accept(*itsFeedbackPort)) {
-		delete itsFeedbackPort;
-		itsFeedbackPort = 0;
-		LOG_ERROR("Connection with Python feedback FAILED");
-	}
-	else {
-		LOG_INFO("Connection made on feedback port, accepting commands");
-	}
-}
-
-//
-// _handleDataIn(port)
-//
-void OnlineControl::_handleDataIn(GCFPortInterface& port)
-{
-	ASSERTSTR(&port == itsFeedbackPort, "Didn't expect raw data on port " << port.getName());
-	char    buf[1024];
-	ssize_t btsRead = port.recv((void*)&buf[0], 1023);
-	buf[btsRead] = '\0';
-	string  s;
-	hexdump(s, buf, btsRead);
-	LOG_INFO_STR("Received command on feedback port: " << s);
-
-	if (!strcmp(buf, "ABORT")) {
-		itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
-		TRAN(OnlineControl::completing_state);	// pass metadata
-	}
-	else if (!strcmp(buf, "FINISHED")) {
-		TRAN(OnlineControl::completing_state);
-	}
-	else {
-		LOG_FATAL_STR("Received command on feedback port unrecognized");
-	}
 }
 
 }; // CEPCU
diff --git a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.conf b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.conf
index 628c55fa5cf86fa0ba6c8a83c675aadf9c7c06d4..c0c088bf99f5a4a1f058c99265d2713b63ed7249 100644
--- a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.conf
+++ b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.conf
@@ -5,5 +5,8 @@
 # Host on which the KVTLogger runs (normally localhost)
 OTDBconfFile		= SASGateway.conf
 
+# Queue to listen at.
+TaskStateQueue	= mac.task.feedback.state
+
 # Max time to wait for response from Python Framework when quiting
 emergencyTimeout	= 1h
diff --git a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.h b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.h
index a3fe3a4fc85b6f86a9dbab5d1b33ff89e580557c..d6daf80a70afdcf578ef0293ade9c40a139757e5 100644
--- a/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.h
+++ b/MAC/APL/CEPCU/src/OnlineControl/OnlineControl.h
@@ -27,10 +27,11 @@
 #include <Common/lofar_string.h>
 #include <Common/lofar_vector.h>
 #include <Common/LofarLogger.h>
-
-//# ACC Includes
 #include <Common/ParameterSet.h>
 
+//# MsgBus Includes
+#include <MessageBus/MsgBus.h>
+
 //# GCF Includes
 #include <GCF/TM/GCF_Control.h>
 #include <GCF/PVSS/PVSSservice.h>
@@ -90,15 +91,13 @@ private:
 	void	_stopApplications();
 	void   	_finishController	 (uint16_t 				result);
    	void	_handleDisconnect	 (GCFPortInterface& 	port);
-   	void	_handleAcceptRequest (GCFPortInterface& 	port);
-   	void	_handleDataIn		 (GCFPortInterface& 	port);
 	void	_setState	  		 (CTState::CTstateNr	newState);
 	void	_databaseEventHandler(GCFEvent&				event);
-	void	_passMetadatToOTDB   ();
 	void	_clearCobaltDatapoints();
 
 	// ----- datamembers -----
 	string						itsMyName;
+	int							itsObsID;
    	RTDBPropertySet*           	itsPropertySet;
 	bool					  	itsPropertySetInitialized;
 	PVSSservice*				itsPVSSService;
@@ -115,9 +114,8 @@ private:
 
 	CTState::CTstateNr		itsState;
 
-	// QUICK FIX #4022
-	GCFTCPPort*				itsFeedbackListener;
-	GCFTCPPort*				itsFeedbackPort;
+	FromBus*				itsMsgQueue;
+	GCFTimerPort*			itsQueueTimer;
 	int						itsFeedbackResult;
 
 	// ParameterSet variables
diff --git a/MAC/APL/CEPCU/src/OnlineControl/OnlineControlMain.cc b/MAC/APL/CEPCU/src/OnlineControl/OnlineControlMain.cc
index e3356ed014303d8897d4e7eb7954bbd60a614e93..9963bec3477a7bdec1d347369d15d89a7cfc0c5c 100644
--- a/MAC/APL/CEPCU/src/OnlineControl/OnlineControlMain.cc
+++ b/MAC/APL/CEPCU/src/OnlineControl/OnlineControlMain.cc
@@ -23,6 +23,7 @@
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
 #include <Common/Exception.h>
+#include <MessageBus/MsgBus.h>
 
 #include "OnlineControl.h"
 
@@ -44,6 +45,8 @@ int main(int argc, char* argv[])
 
 	GCFScheduler::instance()->init(argc, argv, argv[1]);
 
+  MessageBus::init();
+
 	ParentControl*	pc = ParentControl::instance();
 	pc->start();	// make initial transition
 
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc b/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
index 3bd66084edb679c58e5ab8bda4ac3ed4f94fa646..f6e1d880f10618d39615a14a1683a4943186bba7 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControl.cc
@@ -50,6 +50,7 @@
 
 using namespace std;
 using namespace boost::posix_time;
+using qpid::messaging::Message;
 
 namespace LOFAR {
 	using namespace APLCommon;
@@ -62,6 +63,7 @@ namespace LOFAR {
 // static pointer to this object for signal handler
 static PythonControl*	thisPythonControl = 0;
 
+const double QUEUE_POLL_TIMEOUT = 1.0;
 //
 // PythonControl()
 //
@@ -72,14 +74,13 @@ PythonControl::PythonControl(const string&	cntlrName) :
 	itsParentControl	(0),
 	itsParentPort		(0),
 	itsTimerPort		(0),
+	itsQueueTimer		(0),
 	itsForcedQuitTimer  (0),
 	itsListener			(0),
-	itsFeedbackListener	(0),					// QUICK FIX #3633
-	itsFeedbackPort		(0),					// QUICK FIX #3633
-	itsFeedbackResult	(CT_RESULT_NO_ERROR),	// QUICK FIX #3633
+	itsMsgQueue			(0),
+	itsFeedbackResult	(CT_RESULT_NO_ERROR),
 	itsPythonPort		(0),
 	itsState			(CTState::NOSTATE),
-	itsFeedbackFile     (""),
 	itsForceTimeout		(3600.0)
 {
 	LOG_TRACE_OBJ_STR (cntlrName << " construction");
@@ -97,9 +98,6 @@ PythonControl::PythonControl(const string&	cntlrName) :
 	itsListener = new GCFTCPPort (*this, "listener", GCFPortInterface::MSPP, CONTROLLER_PROTOCOL);
 	ASSERTSTR(itsListener, "Cannot allocate TCP port for server port");
 
-	// QUICK FIX #3633
-	itsFeedbackListener = new GCFTCPPort (*this, "Feedbacklistener", GCFPortInterface::MSPP, CONTROLLER_PROTOCOL);
-	ASSERTSTR(itsFeedbackListener, "Cannot allocate TCP port for feedback");
 	itsForcedQuitTimer = new GCFTimerPort(*this, "ForcedQuitTimer");
 	ASSERTSTR(itsForcedQuitTimer, "Cannot allocate emergency quit timer");
 	itsForceTimeout = globalParameterSet()->getTime("emergencyTimeout", 3600);
@@ -107,6 +105,8 @@ PythonControl::PythonControl(const string&	cntlrName) :
 	// need port for timers.
 	itsTimerPort = new GCFTimerPort(*this, "TimerPort");
 	ASSERTSTR(itsTimerPort, "Cannot allocate the timer");
+	itsQueueTimer = new GCFTimerPort(*this, "MsgQTimer");
+	ASSERTSTR(itsQueueTimer, "Cannot allocate queue timer");
 
 	// for debugging purposes
 	registerProtocol (CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_STRINGS);
@@ -125,10 +125,9 @@ PythonControl::~PythonControl()
 		delete itsListener; 
 	}
 
-	if (itsFeedbackListener) { 	// QUICK FIX #3633
-		itsFeedbackListener->close(); 
-		delete itsFeedbackListener; 
-	}
+	delete itsTimerPort;
+	delete itsQueueTimer;
+	delete itsMsgQueue;
 }
 
 //
@@ -203,9 +202,6 @@ bool PythonControl::_startPython(const string&	pythonProg,
 		}
 	}
 
-	// Readin parameters from the obsercationfile.
-	itsFeedbackFile = observationParset(obsID)+"_feedback";
-	LOG_INFO_STR ("Expect metadata to be in file " << itsFeedbackFile);
 
 	// construct system command
 	string	startCmd;
@@ -307,11 +303,6 @@ GCFEvent::TResult PythonControl::initial_state(GCFEvent& event, GCFPortInterface
 	switch (event.signal) {
 	case F_ENTRY: {
 		itsListener->open();	// will result in F_CONN
-		// QUICK FIX #3633
-     unsigned portNr = MAC_PYTHON_FEEDBACK_QF + getObservationNr(getName()) % 7000;
-		LOG_INFO_STR("Listening for feedback on port " << portNr);
-		itsFeedbackListener->setPortNumber(portNr);
-		itsFeedbackListener->open();	// will result in F_CONN
     }
   	break;
 
@@ -353,6 +344,7 @@ GCFEvent::TResult PythonControl::initial_state(GCFEvent& event, GCFPortInterface
 	case CONTROL_CONNECT: {
 		CONTROLConnectEvent		msg(event);
 		itsMyName  = msg.cntlrName;
+		itsObsID   = getObservationNr(getName());
 
 		// request from parent task to start up the child side.
 		ParameterSet*   thePS  = globalParameterSet();      // shortcut to global PS.
@@ -361,9 +353,8 @@ GCFEvent::TResult PythonControl::initial_state(GCFEvent& event, GCFPortInterface
 		string	pythonHost      (thePS->getString(myPrefix+"pythonHost",     "@pythonHost@"));
 		itsChildCanCommunicate = thePS->getBool  (myPrefix+"canCommunicate", true);
 		// START PYTHON
-		// QUICK FIX #3633: if-else nesting was different
 		if (itsChildCanCommunicate) {
-			bool startOK = _startPython(pythonProg, getObservationNr(getName()), realHostname(pythonHost), 
+			bool startOK = _startPython(pythonProg, itsObsID, realHostname(pythonHost), 
 										itsListener->makeServiceName());
 			if (!startOK) {
 				LOG_ERROR("Failed to start the Python environment.");
@@ -421,12 +412,18 @@ GCFEvent::TResult PythonControl::waitForConnection_state(GCFEvent& event, GCFPor
 		break;
 
 	case F_TIMER: {
-		LOG_FATAL("Python environment does not respond! QUITING!");
-		CONTROLConnectedEvent	answer;
-		answer.cntlrName = itsMyName;
-		answer.result    = CONTROL_LOST_CONN_ERR;
-		itsParentPort->send(answer);
-		finish(CT_RESULT_PIPELINE_FAILED);
+		if (&port == itsForcedQuitTimer) {
+			LOG_WARN("Aborting program on emergency timer!");
+			finish(CT_RESULT_EMERGENCY_TIMEOUT);
+		}
+		if (&port == itsTimerPort) {
+			LOG_FATAL("Python environment does not respond! QUITING!");
+			CONTROLConnectedEvent	answer;
+			answer.cntlrName = itsMyName;
+			answer.result    = CONTROL_LOST_CONN_ERR;
+			itsParentPort->send(answer);
+			finish(CT_RESULT_PIPELINE_FAILED);
+		}
 	} break;
 
 	case F_EXIT:
@@ -504,22 +501,12 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 		itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString("active"));
 		itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString(""));
 #endif
-	}
-	break;
-
-	// QUICK FIX #3633
-	case F_ACCEPT_REQ: {
-		ASSERTSTR(&port == itsFeedbackListener, "Incoming connection on main listener iso feedbackListener");
-		itsFeedbackPort = new GCFTCPPort();
-		itsFeedbackPort->init(*this, "feedback", GCFPortInterface::SPP, 0, true);	// raw port
-		if (!itsFeedbackListener->accept(*itsFeedbackPort)) {
-			delete itsFeedbackPort;
-			itsFeedbackPort = 0;
-			LOG_ERROR("Connection with Python feedback FAILED");
-		}
-		else {
-			LOG_INFO("Connection made on feedback port, accepting commands");
+		if (!itsMsgQueue) {
+			string	queueName = globalParameterSet()->getString("TaskStateQueue");
+			itsMsgQueue = new FromBus(queueName);
+			LOG_INFO_STR("Starting to listen on " << queueName);
 		}
+		itsQueueTimer->setTimer(QUEUE_POLL_TIMEOUT);
 	} break;
 
 	case F_DISCONNECTED: {
@@ -528,33 +515,37 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 			LOG_FATAL_STR("Lost connection with Python, going to wait for a new connection");
 			TRAN(PythonControl::waitForConnection_state);
 		}
-		// QUICK FIX #3633
-		if (&port == itsFeedbackPort) {
-			LOG_FATAL_STR("Lost connection with Feedback of PythonFramework.");
-			delete itsFeedbackPort;
-			itsFeedbackPort = 0;
+		else {
+			LOG_FATAL_STR("Lost connection with unknown port! (" << port.getName() << ")");
 		}
 	} break;
 	
-	// QUICK FIX #3633
-	case F_DATAIN: {
-		ASSERTSTR(&port == itsFeedbackPort, "Didn't expect raw data on port " << port.getName());
-		char	buf[1024];
-		ssize_t	btsRead = port.recv((void*)&buf[0], 1023);
-		buf[btsRead] = '\0';
-		string	s;
-		hexdump(s, buf, btsRead);
-		LOG_INFO_STR("Received command on feedback port: " << s);
-
-		if (!strcmp(buf, "ABORT")) {
-			itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
-			TRAN(PythonControl::completing_state);
-		}
-		else if (!strcmp(buf, "FINISHED")) {
-			TRAN(PythonControl::completing_state);
+	case F_TIMER: {
+		if (&port == itsForcedQuitTimer) {
+			LOG_WARN("Aborting program on emergency timer!");
+			finish(CT_RESULT_EMERGENCY_TIMEOUT);
 		}
-		else {
-			LOG_ERROR_STR("Received command on feedback port unrecognized");
+		if (&port == itsQueueTimer) {
+			Message		msg;
+			if (itsMsgQueue->getMessage(msg, 0.1)) {
+				string	obsIDstr = msg.getXMLvalue("message.header.ids.sasid");
+				LOG_INFO_STR("Received message from task " << obsIDstr);
+				if (atoi(obsIDstr.c_str()) == itsObsID) {
+					string	result = msg.getXMLvalue("message.payload.task.state");
+					if (result == "aborted") {
+						itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
+					}
+					else if (result != "finished") {
+						LOG_FATAL_STR("Unknown result received from pipeline: " << result << " assuming failure!");
+						itsFeedbackResult = CT_RESULT_PIPELINE_FAILED;
+					}
+					LOG_INFO_STR("Received '" << result << "' on the messagebus");
+					itsMsgQueue->ack(msg);
+					TRAN(PythonControl::finishing_state);
+					break;
+				} // ID matches?
+			} // getMsg
+			itsQueueTimer->setTimer(QUEUE_POLL_TIMEOUT);
 		}
 	} break;
 
@@ -562,13 +553,6 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 		_databaseEventHandler(event);
 		break;
 
-	case F_TIMER:  {
-		if (&port == itsForcedQuitTimer) {
-			LOG_WARN("Aborting program on emergency timer!");
-			finish(CT_RESULT_EMERGENCY_TIMEOUT);
-		}
-	} break;
-
 	// -------------------- EVENTS RECEIVED FROM PARENT CONTROL --------------------
 	case CONTROL_CONNECT: {
 		CONTROLConnectEvent		msg(event);
@@ -616,13 +600,12 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 			itsPythonPort->send(msg);
 		}
 		else {
-			// QUICK FIX #3633
 			LOG_INFO("Trying to start the Python environment");
 			ParameterSet*   thePS  = globalParameterSet();      // shortcut to global PS.
 			string  myPrefix        (thePS->locateModule("PythonControl")+"PythonControl.");
 			string	pythonProg      (thePS->getString(myPrefix+"pythonProgram",  "@pythonProgram@"));
 			string	pythonHost      (thePS->getString(myPrefix+"pythonHost",     "@pythonHost@"));
-			bool startOK = _startPython(pythonProg, getObservationNr(getName()), realHostname(pythonHost), 
+			bool startOK = _startPython(pythonProg, itsObsID, realHostname(pythonHost), 
 										itsListener->makeServiceName());
 			if (!startOK) {
 				LOG_ERROR("Failed to start the Python environment, ABORTING.");
@@ -633,7 +616,6 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 				finish(CT_RESULT_PIPELINE_FAILED);
 				break;
 			}
-			// QUICK FIX #3633 END
 			LOG_WARN("Start of Python environment looks OK, sending FAKE Resume response");
 			sendControlResult(*itsParentPort, event.signal, itsMyName, CT_RESULT_NO_ERROR);
 		}
@@ -678,7 +660,7 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 			ParameterSet*   thePS  = globalParameterSet();      // shortcut to global PS.
 			string  myPrefix  (thePS->locateModule("PythonControl")+"PythonControl.");
 			string	pythonHost(thePS->getString(myPrefix+"pythonHost","@pythonHost@"));
-			bool stopOK = _stopPython(getObservationNr(getName()), realHostname(pythonHost));
+			bool stopOK = _stopPython(itsObsID, realHostname(pythonHost));
 			if (!stopOK) {
 				LOG_ERROR("Failed to stop the Python environment.");
 				finish(CT_RESULT_PIPELINE_FAILED);
@@ -742,7 +724,7 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 //		msg.result = CT_RESULT_NO_ERROR;
 //		itsParentPort->send(msg);
 		LOG_INFO("Python environment has quited, quiting too.");
-		TRAN(PythonControl::completing_state);
+		TRAN(PythonControl::finishing_state);
 		break;
 	}
 
@@ -755,39 +737,6 @@ GCFEvent::TResult PythonControl::operational_state(GCFEvent& event, GCFPortInter
 	return (status);
 }
 
-//
-// completing_state(event, port)
-//
-// Pickup Metadata feedbackfile is any and pass it to SAS
-//
-GCFEvent::TResult PythonControl::completing_state(GCFEvent& event, GCFPortInterface& port)
-{
-	LOG_DEBUG_STR ("completing:" << eventName(event) << "@" << port.getName());
-
-	switch (event.signal) {
-	case F_ENTRY: {
-		// update PVSS
-#ifdef USE_PVSS_DATABASE
-		itsPropertySet->setValue(PN_FSM_CURRENT_ACTION, GCFPVString("completing"));
-		itsPropertySet->setValue(PN_FSM_ERROR, GCFPVString(""));
-#endif
-		_passMetadatToOTDB();
-
-		TRAN(PythonControl::finishing_state);
-	} break;
-
-	case F_DISCONNECTED:
-		port.close();
-		break;
-	
-	default:
-		LOG_DEBUG("completing_state, default");
-		return (GCFEvent::NOT_HANDLED);
-	}
-
-	return (GCFEvent::HANDLED);
-}
-
 //
 // finishing_state(event, port)
 //
@@ -809,6 +758,8 @@ GCFEvent::TResult PythonControl::finishing_state(GCFEvent& event, GCFPortInterfa
 		msg.cntlrName = itsMyName;
 		msg.result    = itsFeedbackResult;
 		itsParentPort->send(msg);
+		itsQueueTimer->cancelAllTimers();
+		itsForcedQuitTimer->cancelAllTimers();
 		itsTimerPort->cancelAllTimers();
 		itsTimerPort->setTimer(1.0);	// give parent task time to process the message
 	} break;
@@ -829,100 +780,5 @@ GCFEvent::TResult PythonControl::finishing_state(GCFEvent& event, GCFPortInterfa
 	return (GCFEvent::HANDLED);
 }
 
-//
-//	_passMetadatToOTDB();
-//
-void PythonControl::_passMetadatToOTDB()
-{
-	bool	metadataFileAvailable (true);
-
-	// No name specified?
-	if (itsFeedbackFile.empty()) {
-		metadataFileAvailable = false;
-	}
-	else {
-		// Copy file from remote system to localsystem
-		ParameterSet*   thePS  = globalParameterSet();      // shortcut to global PS.
-		string  myPrefix  (thePS->locateModule("PythonControl")+"PythonControl.");
-		string	pythonHost(thePS->getString(myPrefix+"pythonHost","@pythonHost@"));
-		try {
-			if (copyFromRemote(realHostname(pythonHost), itsFeedbackFile, itsFeedbackFile) != 0) {
-				LOG_ERROR_STR("Failed to copy metadatafile " << itsFeedbackFile << " from host " << realHostname(pythonHost));
-				metadataFileAvailable = false;
-			}
-		}
-		catch (...) { 
-			metadataFileAvailable = false;
-		}
-	}
-
-	// Try to setup the connection with the database
-	string	confFile = globalParameterSet()->getString("OTDBconfFile", "SASGateway.conf");
-	ConfigLocator	CL;
-	string	filename = CL.locate(confFile);
-	LOG_DEBUG_STR("Trying to read database information from file " << filename);
-	ParameterSet	otdbconf;
-	otdbconf.adoptFile(filename);
-	string database = otdbconf.getString("SASGateway.OTDBdatabase");
-	string dbhost   = otdbconf.getString("SASGateway.OTDBhostname");
-	OTDBconnection  conn("paulus", "boskabouter", database, dbhost);
-	if (!conn.connect()) {
-		LOG_FATAL_STR("Cannot connect to database " << database << " on machine " << dbhost);
-		// WE DO HAVE A PROBLEM HERE BECAUSE THIS PIPELINE CANNOT BE SET TO FINISHED IN SAS.
-		return;
-	}
-	LOG_INFO_STR("Connected to database " << database << " on machine " << dbhost);
-
-	int			obsID(getObservationNr(getName()));
-	TreeValue   tv(&conn, obsID);
-
-	if (metadataFileAvailable) {
-		// read parameterset
-		ParameterSet	metadata;
-		metadata.adoptFile(itsFeedbackFile);
-
-		// Loop over the parameterset and send the information to the SAS database
-		// During the transition phase from parameter-based to record-based storage in OTDB the
-		// nodenames ending in '_' are implemented both as parameter and as record.
-		ParameterSet::iterator		iter = metadata.begin();
-		ParameterSet::iterator		end  = metadata.end();
-		while (iter != end) {
-			string	key(iter->first);	// make destoyable copy
-			rtrim(key, "[]0123456789");
-	//		bool	doubleStorage(key[key.size()-1] == '_');
-			bool	isRecord(iter->second.isRecord());
-			//   isRecord  doubleStorage
-			// --------------------------------------------------------------
-			//      Y          Y           store as record and as parameters
-			//      Y          N           store as parameters
-			//      N          *           store parameter
-			if (!isRecord) {
-				LOG_DEBUG_STR("BASIC: " << iter->first << " = " << iter->second);
-				tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
-			}
-			else {
-	//			if (doubleStorage) {
-	//				LOG_DEBUG_STR("RECORD: " << iter->first << " = " << iter->second);
-	//				tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
-	//			}
-				// to store is a node/param values the last _ should be stipped of
-				key = iter->first;		// destroyable copy
-	//			string::size_type pos = key.find_last_of('_');
-	//			key.erase(pos,1);
-				ParameterRecord	pr(iter->second.getRecord());
-				ParameterRecord::const_iterator	prIter = pr.begin();
-				ParameterRecord::const_iterator	prEnd  = pr.end();
-				while (prIter != prEnd) {
-					LOG_DEBUG_STR("ELEMENT: " << key+"."+prIter->first << " = " << prIter->second);
-					tv.addKVT(key+"."+prIter->first, prIter->second, ptime(microsec_clock::local_time()));
-					prIter++;
-				}
-			}
-			iter++;
-		}
-		LOG_INFO_STR(metadata.size() << " metadata values send to SAS");
-	}
-}
-
 }; // CEPCU
 }; // LOFAR
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControl.conf b/MAC/APL/CEPCU/src/PythonControl/PythonControl.conf
index 0cffc595c807e87cc5ce4e4c3f7d20268bd3a0d4..674e9fc88ab3e58d75bb4fa78b32b8b3dc28ea40 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControl.conf
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControl.conf
@@ -2,8 +2,8 @@
 # PythonControl.conf
 #
 
-# Host on which the KVTLogger runs (normally localhost)
-OTDBconfFile		= SASGateway.conf
+# Queue to listen at.
+TaskStateQueue	= mac.task.feedback.state
 
 # Max time to wait for response from Python Framework when quiting
 emergencyTimeout	= 1h
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControl.h b/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
index 7d3460d2382608e9e4086b39824c4af9bf0591a5..25f277d81a85c81a90729c95b9be9e3b4d2c8790 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControl.h
@@ -27,10 +27,11 @@
 #include <Common/lofar_string.h>
 #include <Common/lofar_vector.h>
 #include <Common/LofarLogger.h>
-
-//# ACC Includes
 #include <Common/ParameterSet.h>
 
+//# MsgBus Includes
+#include <MessageBus/MsgBus.h>
+
 //# GCF Includes
 #include <GCF/TM/GCF_Control.h>
 #include <GCF/RTDB/RTDB_PropertySet.h>
@@ -67,8 +68,6 @@ public:
    	GCFEvent::TResult waitForConnection_state(GCFEvent& event, GCFPortInterface& port);
 	// Normal control mode. 
 	GCFEvent::TResult operational_state		 (GCFEvent& event, GCFPortInterface& port);
-	// Completing mode. 
-	GCFEvent::TResult completing_state		 (GCFEvent& event, GCFPortInterface& port);
 	// Finishing mode. 
 	GCFEvent::TResult finishing_state		 (GCFEvent& event, GCFPortInterface& port);
 	
@@ -89,26 +88,25 @@ private:
 	bool 	_stopPython  ( int			obsID,
 						  const string&	pythonHost);
 	void	_databaseEventHandler(GCFEvent&				event);
-	void	_passMetadatToOTDB();
 
 	// ----- datamembers -----
    	RTDBPropertySet*           	itsPropertySet;
 	bool					  	itsPropertySetInitialized;
 
 	string					itsMyName;
+	int						itsObsID;
 
 	// pointer to parent control task
 	ParentControl*			itsParentControl;
 	GCFITCPort*				itsParentPort;
 
 	GCFTimerPort*			itsTimerPort;
+	GCFTimerPort*			itsQueueTimer;
 	GCFTimerPort*			itsForcedQuitTimer;
 
 	GCFTCPPort*				itsListener;
 
-	// QUICK FIX #3633
-	GCFTCPPort*				itsFeedbackListener;
-	GCFTCPPort*				itsFeedbackPort;
+	FromBus*				itsMsgQueue;
 	int						itsFeedbackResult;
 
 	GCFTCPPort*				itsPythonPort;
@@ -119,7 +117,6 @@ private:
 	CTState::CTstateNr		itsState;
 
 	// conf-file variables
-	string					itsFeedbackFile;
 	double					itsForceTimeout;
 };
 
diff --git a/MAC/APL/CEPCU/src/PythonControl/PythonControlMain.cc b/MAC/APL/CEPCU/src/PythonControl/PythonControlMain.cc
index 565ab9bd97fac9b5cd81cc3ef5c4d7e8cc7f5505..6c05cfd3e151cf4423595bf0836e48e11478a19c 100644
--- a/MAC/APL/CEPCU/src/PythonControl/PythonControlMain.cc
+++ b/MAC/APL/CEPCU/src/PythonControl/PythonControlMain.cc
@@ -31,7 +31,7 @@ using namespace LOFAR::CEPCU;
 using namespace LOFAR;
 
 // Use a terminate handler that can produce a backtrace.
-Exception::TerminateHandler t(Exception::terminate);
+LOFAR::Exception::TerminateHandler t(Exception::terminate);
 
 int main(int argc, char* argv[])
 {
@@ -57,7 +57,7 @@ int main(int argc, char* argv[])
 		pc->quit();		// let tasks quit nicely.
 		pyc.quit();
 		GCFScheduler::instance()->run(0.3); // let tasks die.
-	} catch( Exception &ex ) {
+	} catch( LOFAR::Exception &ex ) {
 		LOG_FATAL_STR("Caught exception: " << ex);
 		return 1;
 	}
diff --git a/MAC/APL/CUDaemons/CT_StartDaemon/CTStartDaemon.cc b/MAC/APL/CUDaemons/CT_StartDaemon/CTStartDaemon.cc
index b1103e70473e52d9348b813a1b2dbaf44e219264..9ef212f531f1db668a36e2f97f90e461ad0e9c4f 100644
--- a/MAC/APL/CUDaemons/CT_StartDaemon/CTStartDaemon.cc
+++ b/MAC/APL/CUDaemons/CT_StartDaemon/CTStartDaemon.cc
@@ -264,10 +264,10 @@ int32 CTStartDaemon::startController(uint16			cntlrType,
 									parentService.c_str());
 	LOG_INFO_STR("About to start: " << startCmd);
 
-	int32	result = system (startCmd.c_str());
+	int	result = system (startCmd.c_str());
 	LOG_INFO_STR ("Result of start = " << result);
 
-	if (result == -1) {
+	if (result != 0) {
 		return (SD_RESULT_START_FAILED);
 	}
 	
diff --git a/MAC/APL/MainCU/CMakeLists.txt b/MAC/APL/MainCU/CMakeLists.txt
index 8ee48d7734a84388d07d04cb40dc07b5f029d7c4..772dc46fbda9608ed28b552f5863e09857fe02b7 100644
--- a/MAC/APL/MainCU/CMakeLists.txt
+++ b/MAC/APL/MainCU/CMakeLists.txt
@@ -1,7 +1,7 @@
 # $Id$
 
 # Do not split the following line, otherwise makeversion will fail!
-lofar_package(MainCU 1.0 DEPENDS Common OTDB MACIO GCFTM GCFPVSS GCFRTDB APLCommon RTDBCommon ApplCommon CR_Protocol)
+lofar_package(MainCU 1.0 DEPENDS Common MessageBus OTDB MACIO GCFTM GCFPVSS GCFRTDB APLCommon RTDBCommon ApplCommon CR_Protocol)
 
 include(LofarFindPackage)
 lofar_find_package(Boost REQUIRED COMPONENTS date_time)
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
index a812099ed1b3ea17ae8aa17f1716282cbf22ba3e..5464388d30bb33ac1d421301d7fe5b8765d52124 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
@@ -28,6 +28,8 @@
 #include <Common/ParameterSet.h>
 #include <GCF/TM/GCF_Protocols.h>
 #include <MACIO/MACServiceInfo.h>
+#include <MessageBus/MsgBus.h>
+#include <MessageBus/Protocols/TaskSpecificationSystem.h>
 #include <GCF/PVSS/GCF_PVTypes.h>
 #include <APL/APLCommon/APL_Defines.h>
 #include <APL/APLCommon/ControllerDefines.h>
@@ -47,6 +49,7 @@ using namespace LOFAR::GCF::PVSS;
 using namespace LOFAR::GCF::TM;
 using namespace LOFAR::GCF::RTDB;
 using namespace LOFAR::OTDB;
+using namespace LOFAR::Protocols;
 using namespace boost::posix_time;
 using namespace std;
 
@@ -77,7 +80,8 @@ MACScheduler::MACScheduler() :
 	itsNextFinishedTime	(0),
 	itsNrPlanned		(0),
 	itsNrActive			(0),
-	itsOTDBconnection	(0)
+	itsOTDBconnection	(0),
+	itsMsgQueue			(0)
 {
 	LOG_TRACE_OBJ ("MACscheduler construction");
 
@@ -93,7 +97,8 @@ MACScheduler::MACScheduler() :
 	itsMaxPlanned    = globalParameterSet()->getTime("maxPlannedList",  30);
 	itsMaxFinished   = globalParameterSet()->getTime("maxFinishedList", 40);
 
-	ASSERTSTR(itsMaxPlanned + itsMaxFinished < MAX_CONCURRENT_OBSERVATIONS, "maxPlannedList + maxFinishedList should be less than " << MAX_CONCURRENT_OBSERVATIONS);
+	ASSERTSTR(itsMaxPlanned + itsMaxFinished < MAX_CONCURRENT_OBSERVATIONS, 
+				"maxPlannedList + maxFinishedList should be less than " << MAX_CONCURRENT_OBSERVATIONS);
 
 	// Read the schedule periods for starting observations.
 	itsQueuePeriod 		= globalParameterSet()->getTime("QueuePeriod");
@@ -101,20 +106,23 @@ MACScheduler::MACScheduler() :
 
 	// attach to child control task
 	itsChildControl = ChildControl::instance();
-	itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", 
-									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
 	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol");
 	itsChildPort->open();		// will result in F_CONNECTED
 
 	// create an PVSSprepare Task
 	itsClaimerTask = new ObsClaimer(this);
 	ASSERTSTR(itsClaimerTask, "Cannot construct a ObsClaimerTask");
-	itsClaimerPort = new GCFITCPort (*this, *itsClaimerTask, "ObsClaimerPort",
-									GCFPortInterface::SAP, CM_PROTOCOL);
+	itsClaimerPort = new GCFITCPort (*this, *itsClaimerTask, "ObsClaimerPort", GCFPortInterface::SAP, CM_PROTOCOL);
 
 	// need port for timers
 	itsTimerPort = new GCFTimerPort(*this, "Timerport");
 
+	// setup MsgQueue
+	string queueName = globalParameterSet()->getString("ParsetQueuename");
+	ASSERTSTR(!queueName.empty(), "Queuename for distributing parameterSets not specified");
+	itsMsgQueue = new ToBus(queueName);
+
 	registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_STRINGS);
 	registerProtocol(DP_PROTOCOL, 		  DP_PROTOCOL_STRINGS);
 }
@@ -134,6 +142,10 @@ MACScheduler::~MACScheduler()
 	if (itsOTDBconnection) {
 		delete itsOTDBconnection;
 	}
+
+	if (itsMsgQueue) {
+		delete itsMsgQueue;
+	}
 }
 
 //
@@ -696,6 +708,10 @@ void MACScheduler::_updatePlannedList()
 					// add controller to our 'monitor' administration
 					itsControllerMap[cntlrName] =  obsID;
 					LOG_DEBUG_STR("itsControllerMap[" << cntlrName << "]=" <<  obsID);
+					if (!itsPreparedObs[obsID].parsetDistributed) {
+						_setParsetOnMsgBus(observationParset(obsID));
+						itsPreparedObs[obsID].parsetDistributed = true;
+					}
 				}
 				else {
 					LOG_DEBUG_STR("Observation " << obsID << " is already (being) started");
@@ -809,6 +825,29 @@ void MACScheduler::_updateFinishedList()
 	}
 }
 
+//
+// _setParsetOnMsgBus(parsetFile)
+//
+void MACScheduler::_setParsetOnMsgBus(const string&	filename) const
+{
+	// open file
+	ParameterSet	obsSpecs(filename);
+	string			obsPrefix = obsSpecs.fullModuleName("Observation");
+	string			momID = obsSpecs.getString(obsPrefix + ".momID");
+	string			sasID = obsSpecs.getString(obsPrefix + ".otdbID");
+
+    //                      from, forUser, summary, protocol, protocolVersion, momID, sasID
+#if 1	
+	TaskSpecificationSystem	outMsg("LOFAR.MACScheduler", "", "", momID, sasID, obsSpecs);
+#else
+	Message			outMsg("LOFAR.MACScheduler", "", "", "task.specification.system", "1.0", momID, sasID);
+	stringstream	ss;
+	obsSpecs.writeStream(ss);
+	outMsg.setTXTPayload(ss.str());
+#endif
+	cout << outMsg << endl;
+	itsMsgQueue->send(outMsg);
+}
 
 //
 // _connectedHandler(port)
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
index e4ac723afce39d2d10bc94678d610d2ca78644cd..911f75463162324556fcb8d03141d9aece3381b6 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
@@ -29,3 +29,4 @@ maxFinishedList	= 40	# Never show more finished observations
 #ChildControl.StartupRetryInterval = 10s
 #ChildControl.MaxStartupRetry	   = 5
 
+ParsetQueuename = lofar.task.specification.system
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
index 65f6f754792c1f0dd0583284090f913c96528fdb..83b8069877267ab001b02fe9002c2544c9a7b9cc 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
@@ -39,6 +39,7 @@
 #include <Common/lofar_vector.h>
 #include <Common/LofarLogger.h>
 #include <ApplCommon/Observation.h>
+#include <MessageBus/MsgBus.h>
 
 //# ACC Includes
 #include <OTDB/OTDBconnection.h>
@@ -107,6 +108,7 @@ private:
 	void _updatePlannedList();
 	void _updateActiveList();
 	void _updateFinishedList();
+	void _setParsetOnMsgBus(const string&	filename) const;
 
 	// ----- DATA MEMBERS -----
 	// Our own propertySet in PVSS to inform the operator
@@ -130,8 +132,9 @@ private:
 	public:
 		ptime	modTime;
 		bool	prepReady;
-		schedInfo(ptime t, bool p) : modTime(t), prepReady(p) {};
-		schedInfo() : modTime(min_date_time), prepReady(false) {};
+		bool	parsetDistributed;
+		schedInfo(ptime t, bool p) : modTime(t), prepReady(p), parsetDistributed(false) {};
+		schedInfo() : modTime(min_date_time), prepReady(false), parsetDistributed(false) {};
 	};
 	typedef map<int /*obsID*/, schedInfo /*prepReady*/>	ObsList;
 	typedef map<int ,schedInfo>::iterator				OLiter;
@@ -163,8 +166,10 @@ private:
 	uint32				itsQueuePeriod;			// period between queueing and start
       
 	// OTDB related variables.
-   	OTDB::OTDBconnection*	itsOTDBconnection;		// connection to the database
+   	OTDB::OTDBconnection*	itsOTDBconnection;	// connection to the database
 
+	// Messagebus related variables
+	ToBus*					itsMsgQueue;		// Bus used for sending
 };
 
   };//MainCU
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
index 14e7f54e380a8abd101892423c5a971882119276..2b472d7c01a3741d039d35a98eca861b32520e1f 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
@@ -23,6 +23,7 @@
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
 #include <Common/Exception.h>
+#include <MessageBus/MsgBus.h>
 
 #include "MACScheduler.h"
 
@@ -38,6 +39,8 @@ int main(int argc, char* argv[])
 {
 	GCFScheduler::instance()->init(argc, argv, "MACScheduler");
 
+  MessageBus::init();
+
 	ChildControl*	cc = ChildControl::instance();
 	cc->start();	// make initial transition
 
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
index ac46c6ce423a37b285c7216194d532b9186d7474..62a099b482fd5716d5919cdd7d252c23b250c01c 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.cc
@@ -107,10 +107,11 @@ ObservationControl::ObservationControl(const string&	cntlrName) :
 	itsProcessType   = globalParameterSet()->getString("Observation.processType", "Observation");
 
 	// Values from my conf file
-	itsLateLimit     = globalParameterSet()->getTime  ("ObservationControl.lateLimit", 15);
-	itsFailedLimit   = globalParameterSet()->getTime  ("ObservationControl.failedLimit", 30);
-	itsHeartBeatItv	 = globalParameterSet()->getTime  ("ObservationControl.heartbeatInterval", 10);
-	string reportType= globalParameterSet()->getString("ObservationControl.reportType", "Full");
+	itsLateLimit       = globalParameterSet()->getTime  ("ObservationControl.lateLimit", 15);
+	itsFailedLimit     = globalParameterSet()->getTime  ("ObservationControl.failedLimit", 30);
+	itsHeartBeatItv	   = globalParameterSet()->getTime  ("ObservationControl.heartbeatInterval", 10);
+	itsFinalStateDelay = globalParameterSet()->getTime  ("ObservationControl.finalStateDelay", 10);
+	string reportType  = globalParameterSet()->getString("ObservationControl.reportType", "Full");
 	if 		(reportType == "Full")		itsFullReport = true;
 	else if (reportType == "Changes")	itsChangeReport = true;
 
@@ -655,6 +656,8 @@ GCFEvent::TResult ObservationControl::finishing_state(GCFEvent& 		event,
 		setState(CTState::QUITED);
 
 		// inform MACScheduler we are going down
+		LOG_INFO_STR("Waiting " << itsFinalStateDelay << " seconds before reporting final state...");
+		sleep (itsFinalStateDelay);
 		CONTROLQuitedEvent	msg;
 		msg.cntlrName = getName();
 		msg.result 	  = itsQuitReason;
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
index 2a43f6f73b9846150e972423742cf3e3c7ffbeab..554b7fa92589e077632e060b9b6eb0d1160d5f47 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.conf.in
@@ -28,3 +28,7 @@ ObservationControl.reportType = Full
 #
 ObservationControl.emergencyTimeout = 1h
 
+#
+# Delay before reporting FINAL state to MACScheduler
+#
+ObservationControl.finalStateDelay = 10s
diff --git a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
index 79dd634ae6c1cd85caa43315580881f0a9ccf5b9..cb8f86738577f6faf9241566ce5ff77ac4cc677b 100644
--- a/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
+++ b/MAC/APL/MainCU/src/ObservationControl/ObservationControl.h
@@ -171,6 +171,7 @@ private:
 	uint32					itsTreeID;
 	uint32					itsHeartBeatItv;
 	uint32					itsForcedQuitDelay;
+	uint32					itsFinalStateDelay;
 	uint32					itsClaimPeriod;
 	uint32					itsPreparePeriod;
 	int32					itsLateLimit;		// after how many seconds a requested state should have been reached.
diff --git a/RTCP/Cobalt/CoInterface/src/LTAFeedback.cc b/RTCP/Cobalt/CoInterface/src/LTAFeedback.cc
index 8928df3d4e4e513b45f52b5e072bf82107ff95da..7396924d513ac9e7122b7269aaa00f3f6103e251 100644
--- a/RTCP/Cobalt/CoInterface/src/LTAFeedback.cc
+++ b/RTCP/Cobalt/CoInterface/src/LTAFeedback.cc
@@ -192,7 +192,7 @@ namespace LOFAR
     }
 
 
-    ParameterSet LTAFeedback::allFeedback() const
+    ParameterSet LTAFeedback::processingFeedback() const
     {
       ParameterSet ps;
 
@@ -209,11 +209,6 @@ namespace LOFAR
                str(format("%u") % settings.correlator.nrChannels));
         ps.add("Observation.Correlator.channelWidth",
                str(format("%.16g") % (settings.subbandWidth() / settings.correlator.nrChannels)));
-
-        // add the feedback for the individual files
-        for (size_t i = 0; i < settings.correlator.files.size(); ++i) {
-          ps.adoptCollection(correlatedFeedback(i));
-        }
       }
 
       ps.add("Observation.DataProducts.nrOfOutput_Beamformed_", 
@@ -314,9 +309,25 @@ namespace LOFAR
         ps.add("Observation.IncoherentStokes.stationList",
                settings.rawStationList);
       }
+
+      return ps;
+    }
+
+
+    ParameterSet LTAFeedback::allFeedback() const
+    {
+      ParameterSet ps;
+
+      ps.adoptCollection(processingFeedback());
+
+      // add the feedback for the individual files
+      if (settings.correlator.enabled) {
+        for (size_t i = 0; i < settings.correlator.files.size(); ++i) {
+          ps.adoptCollection(correlatedFeedback(i));
+        }
+      }
       
       if (settings.beamFormer.enabled) {
-        // add the feedback for the individual files
         for (size_t i = 0; i < settings.beamFormer.files.size(); ++i) {
           ps.adoptCollection(beamFormedFeedback(i));
         }
diff --git a/RTCP/Cobalt/CoInterface/src/LTAFeedback.h b/RTCP/Cobalt/CoInterface/src/LTAFeedback.h
index 3fbe662591407bc996a41a0bea3f388f58bc1a80..e8be4dd8d389581c12d45bc4eb991ddd247f6ab6 100644
--- a/RTCP/Cobalt/CoInterface/src/LTAFeedback.h
+++ b/RTCP/Cobalt/CoInterface/src/LTAFeedback.h
@@ -45,6 +45,14 @@ namespace LOFAR
       ParameterSet                correlatedFeedback(size_t fileno) const;
       ParameterSet                beamFormedFeedback(size_t fileno) const;
 
+      // Return the generic processing LTA feedback parameters.
+      // (Non data-product specific).
+      // \note Details about the meaning of the different meta-data parameters
+      // can be found in the XSD that describes the Submission Information
+      // Package (sip) for the LTA.
+      // \see http://proposal.astron.nl/schemas/LTA-SIP.xsd
+      ParameterSet                processingFeedback() const;
+
       // Return the LTA feedback parameters.
       // \note Details about the meaning of the different meta-data parameters
       // can be found in the XSD that describes the Submission Information
diff --git a/RTCP/Cobalt/CoInterface/src/OMPThread.h b/RTCP/Cobalt/CoInterface/src/OMPThread.h
index 6d83f05a6438a47a07bf2bd6811f785a27a71c30..2914a0fe5bfc9d0162077558c5ea379c57e5a2c1 100644
--- a/RTCP/Cobalt/CoInterface/src/OMPThread.h
+++ b/RTCP/Cobalt/CoInterface/src/OMPThread.h
@@ -162,6 +162,8 @@ namespace LOFAR
 
         if ((retval = pthread_setname_np(pthread_self(), name.substr(0,15).c_str())) != 0)
           throw SystemCallException("pthread_setname_np", retval, THROW_ARGS);
+#else
+        (void)name;
 #endif
       }
 
diff --git a/RTCP/Cobalt/CoInterface/src/Parset.cc b/RTCP/Cobalt/CoInterface/src/Parset.cc
index 911a06981a7e495902a0bc0f3ae980d34156ae1d..316a4a32e0db490331c4e8746cde53c264ae6f66 100644
--- a/RTCP/Cobalt/CoInterface/src/Parset.cc
+++ b/RTCP/Cobalt/CoInterface/src/Parset.cc
@@ -321,6 +321,7 @@ namespace LOFAR
       // Generic information
       settings.realTime = getBool("Cobalt.realTime", false);
       settings.observationID = getUint32("Observation.ObsID", 0);
+      settings.momID         = getUint32("Observation.momID", 0);
       settings.commandStream = getString("Cobalt.commandStream", "null:");
       settings.startTime = getTime("Observation.startTime", "2013-01-01 00:00:00");
       settings.stopTime  = getTime("Observation.stopTime",  "2013-01-01 00:01:00");
diff --git a/RTCP/Cobalt/CoInterface/src/Parset.h b/RTCP/Cobalt/CoInterface/src/Parset.h
index 8c9361fdbab97aa3692fa2c82e8080210ef0c854..5c99148bee65924870d3fdfcb6fe06eca3264f00 100644
--- a/RTCP/Cobalt/CoInterface/src/Parset.h
+++ b/RTCP/Cobalt/CoInterface/src/Parset.h
@@ -70,6 +70,11 @@ namespace LOFAR
       // key: Observation.ObsID
       unsigned observationID;
 
+      // The MoM observation number
+      //
+      // key: Observation.momID
+      unsigned momID;
+
       // Command stream, or null: if not used
       //
       // key: Cobalt.commandStream
diff --git a/RTCP/Cobalt/CoInterface/test/tParset.cc b/RTCP/Cobalt/CoInterface/test/tParset.cc
index 1b80fa02e6c2c7783b2268aa9bdde8f97a0203c1..a07e2c33f430ea9da88058e8c0b71e9dc8849b78 100644
--- a/RTCP/Cobalt/CoInterface/test/tParset.cc
+++ b/RTCP/Cobalt/CoInterface/test/tParset.cc
@@ -96,6 +96,12 @@ TEST(observationID) {
   CHECK_EQUAL(12345U, ps.settings.observationID);
 }
 
+TEST(momID) {
+  Parset ps = makeDefaultTestParset("Observation.momID", "12345");
+
+  CHECK_EQUAL(12345U, ps.settings.momID);
+}
+
 TEST(startTime) {
   Parset ps = makeDefaultTestParset("Observation.startTime", "2013-03-17 10:55:08");
 
diff --git a/RTCP/Cobalt/GPUProc/CMakeLists.txt b/RTCP/Cobalt/GPUProc/CMakeLists.txt
index 6b420ab50d288c5be17f15fd2a571887f6e4e4a1..3a8a7c8ad69c4f4ce5cf3b79a5c3502cdaccdadb 100644
--- a/RTCP/Cobalt/GPUProc/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/CMakeLists.txt
@@ -2,7 +2,7 @@
 
 # Handle options USE_CUDA and USE_OPENCL.
 if(USE_CUDA AND NOT USE_OPENCL)
-  set(_gpuproc_deps Common Stream ApplCommon CoInterface InputProc MACIO BrokenAntennaInfo)
+  set(_gpuproc_deps Common Stream ApplCommon CoInterface InputProc MACIO BrokenAntennaInfo MessageBus)
   lofar_find_package(CUDA 4.1 REQUIRED)
   lofar_find_package(CUDADriver REQUIRED)
 
@@ -34,7 +34,7 @@ if(USE_CUDA AND NOT USE_OPENCL)
   endif()
 
 elseif(USE_OPENCL AND NOT USE_CUDA)
-  set(_gpuproc_deps Common Stream ApplCommon CoInterface InputProc MACIO BrokenAntennaInfo OpenCL_FFT)
+  set(_gpuproc_deps Common Stream ApplCommon CoInterface InputProc MACIO BrokenAntennaInfo OpenCL_FFT MessageBus)
   lofar_find_package(OpenCL REQUIRED)
   add_definitions(-DUSE_OPENCL)
 else()
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset
deleted file mode 100644
index 14e6a2cedc84950869b3e4829e7c993c85a2e2c9..0000000000000000000000000000000000000000
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset
+++ /dev/null
@@ -1,15 +0,0 @@
-# $Id$
-
-# The host that is running OnlineControl
-# The feedback port is derived through
-#   21000 + (Observation.ObsID % 1000)
-Cobalt.Feedback.host = ccu001
-
-# The remote directory in which the LTA feedback needs to be stored
-Cobalt.Feedback.remotePath = /opt/lofar/var/run
-
-# The host that is running PVSSGateway.
-# If empty, data points are never sent.
-# One can also start a PVSSGateway_Stub
-#   on localhost, which writes to a file.
-Cobalt.PVSSGateway.host = ccu001
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/PVSS-feedback.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/PVSS-feedback.parset
new file mode 100644
index 0000000000000000000000000000000000000000..4e062233e380cd0bc57b388f0ecec42bf1ccfe33
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/PVSS-feedback.parset
@@ -0,0 +1,7 @@
+# $Id: MAC-feedback.parset 30525 2014-11-28 12:21:15Z mol $
+
+# The host that is running PVSSGateway.
+# If empty, data points are never sent.
+# One can also start a PVSSGateway_Stub
+#   on localhost, which writes to a file.
+Cobalt.PVSSGateway.host = ccu001
diff --git a/RTCP/Cobalt/GPUProc/src/CMakeLists.txt b/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
index b511d42b9b92e42c54929bff6b07a00bb52308a6..da6eeee66c2931fee22f2d14c7bb88f4fbeb8a60 100644
--- a/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
@@ -119,6 +119,7 @@ endif()
 
 lofar_add_bin_program(mpi_node_list Station/mpi_node_list.cc)
 lofar_add_bin_program(station_stream Station/station_stream.cc)
+lofar_add_bin_program(send_state send_state.cc)
 
 # install scripts used to run an observation under bin
 install(PROGRAMS
diff --git a/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc b/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
index 929197ed7a0f925bb1c02e723676c0872e7dfcc0..2a12316f9fe2d18c02d3bbf0d77de5ec4b21b98b 100644
--- a/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
+++ b/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
@@ -558,12 +558,16 @@ namespace LOFAR {
           if (ps.settings.realTime) {
             #pragma omp parallel for num_threads(nrBoards)
             for(size_t board = 0; board < nrBoards; board++) {
-              OMPThreadSet::ScopedRun sr(packetReaderThreads);
-              OMPThread::ScopedName sn(str(format("%s rd %u") % ps.settings.antennaFields.at(stationIdx).name % board));
+              try {
+                OMPThreadSet::ScopedRun sr(packetReaderThreads);
+                OMPThread::ScopedName sn(str(format("%s rd %u") % ps.settings.antennaFields.at(stationIdx).name % board));
 
-              Thread::ScopedPriority sp(SCHED_FIFO, 10);
+                Thread::ScopedPriority sp(SCHED_FIFO, 10);
 
-              readRSPRealTime(board, mdLogger, mdKeyPrefix);
+                readRSPRealTime(board, mdLogger, mdKeyPrefix);
+              } catch(OMPThreadSet::CannotStartException &ex) {
+                LOG_INFO_STR( logPrefix << "Stopped");
+              }
             }
           } else {
             readRSPNonRealTime(mdLogger, mdKeyPrefix);
diff --git a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.cc b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.cc
index 5b602f491460b70ca486630f8d6e87c5529bb75d..d381e8075c34e47c397f4bb190f002f26eb30185 100644
--- a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.cc
+++ b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.cc
@@ -28,8 +28,11 @@
 
 #include <Common/LofarLogger.h>
 #include <Common/Thread/Thread.h>
+#include <MessageBus/MsgBus.h>
+#include <MessageBus/Protocols/TaskFeedbackDataproducts.h>
 #include <Stream/PortBroker.h>
 #include <CoInterface/Stream.h>
+#include <CoInterface/LTAFeedback.h>
 
 namespace LOFAR
 {
@@ -45,7 +48,9 @@ namespace LOFAR
       itsParset(parset),
       itsLogPrefix(str(boost::format("%s [StorageWriter rank %2d host %s] ") % logPrefix % rank % hostname)),
       itsRank(rank),
-      itsHostname(hostname)
+      itsHostname(hostname),
+      itsSentFeedback(false),
+      itsSuccessful(false)
     {
     }
 
@@ -57,6 +62,46 @@ namespace LOFAR
       // stop immediately
       struct timespec immediately = { 0, 0 };
       stop(immediately);
+
+      if (!itsSentFeedback) {
+        // send default LTA feedback for this host
+        ToBus bus("lofar.task.feedback.dataproducts");
+
+        const std::string myName = "Cobalt/GPUProc/Storage/StorageProcess";
+
+        LTAFeedback feedback(itsParset.settings);
+
+        if (itsParset.settings.correlator.enabled)
+          for (size_t i = 0; i < itsParset.settings.correlator.files.size(); ++i) {
+            LOG_INFO_STR(itsParset.settings.correlator.files[i].location.host << " == " << itsHostname);
+
+            if (itsParset.settings.correlator.files[i].location.host == itsHostname) {
+              Protocols::TaskFeedbackDataproducts msg(
+                myName,
+                "",
+                str(boost::format("Feedback for Correlated Data, subband %s") % i),
+                str(format("%s") % itsParset.settings.momID),
+                str(format("%s") % itsParset.settings.observationID),
+                feedback.correlatedFeedback(i));
+
+              bus.send(msg);
+            }
+        }
+
+        if (itsParset.settings.beamFormer.enabled)
+          for (size_t i = 0; i < itsParset.settings.beamFormer.files.size(); ++i)
+            if (itsParset.settings.beamFormer.files[i].location.host == itsHostname) {
+              Protocols::TaskFeedbackDataproducts msg(
+                myName,
+                "",
+                str(boost::format("Feedback for Beamformed Data, file nr %s") % i),
+                str(format("%s") % itsParset.settings.momID),
+                str(format("%s") % itsParset.settings.observationID),
+                feedback.beamFormedFeedback(i));
+
+              bus.send(msg);
+            }
+      }
     }
 
 
@@ -82,6 +127,12 @@ namespace LOFAR
     }
 
 
+    bool StorageProcess::isSuccesful() const
+    {
+      return itsSuccessful;
+    }
+
+
     bool StorageProcess::isDone() const
     {
       return itsThread->isDone();
@@ -95,15 +146,6 @@ namespace LOFAR
     }
 
 
-    ParameterSet StorageProcess::feedbackLTA() const
-    {
-      // Prevent read/write conflicts
-      ASSERT(isDone());
-
-      return itsFeedbackLTA;
-    }
-
-
     void StorageProcess::controlThread()
     {
       // Connect control stream
@@ -123,12 +165,11 @@ namespace LOFAR
       itsFinalMetaData.write(stream);
       LOG_DEBUG_STR(itsLogPrefix << "[ControlThread] sent final meta data");
 
-      // Wait for LTA feedback
-      LOG_DEBUG_STR(itsLogPrefix << "[ControlThread] reading LTA feedback");
-      ParameterSet feedbackLTA;
-      readParameterSet(stream, feedbackLTA);
-      itsFeedbackLTA.adoptCollection(feedbackLTA);
-      LOG_DEBUG_STR(itsLogPrefix << "[ControlThread] read LTA feedback");
+      // Wait for OutputProc to finish
+      LOG_DEBUG_STR(itsLogPrefix << "[ControlThread] waiting to finish");
+      stream.read(&itsSentFeedback, sizeof itsSentFeedback);
+      stream.read(&itsSuccessful, sizeof itsSuccessful);
+      LOG_DEBUG_STR(itsLogPrefix << "[ControlThread] finished");
     }
 
   }
diff --git a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.h b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.h
index f982196a70cd7b318984aac26cc08f2ebe6c3b89..a6e49c8429a9e9d48739861f26eab0b678568c0f 100644
--- a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.h
+++ b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcess.h
@@ -67,11 +67,9 @@ namespace LOFAR
 
       void start();
       void stop( struct timespec deadline );
-      bool isDone() const;
 
-      // Returns feedback for the LTA -- only access this once the
-      // StorageProcess has finished!
-      ParameterSet feedbackLTA() const;
+      bool isSuccesful() const; // return whether communication with OutputProc went perfect
+      bool isDone() const;
 
       void setFinalMetaData( const FinalMetaData &finalMetaData );
 
@@ -84,11 +82,12 @@ namespace LOFAR
       const int itsRank;
       const std::string itsHostname;
 
+      bool                               itsSentFeedback;
+      bool                               itsSuccessful;
+
       FinalMetaData                      itsFinalMetaData;
       Semaphore                          itsFinalMetaDataAvailable;
 
-      ParameterSet                       itsFeedbackLTA;
-
       SmartPtr<Thread> itsThread;
     };
 
diff --git a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
index 402e43a5b95babbe6cb4323121fbbff80d8357b0..148c18dc8cf6bac77f56f03d69811122da6fed1b 100644
--- a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
+++ b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
@@ -58,12 +58,6 @@ namespace LOFAR
     }
 
 
-    ParameterSet StorageProcesses::feedbackLTA() const
-    {
-      return itsFeedbackLTA;
-    }
-
-
     void StorageProcesses::start()
     {
       const vector<string> &hostnames = itsParset.settings.outputProcHosts;
@@ -91,9 +85,6 @@ namespace LOFAR
         // stop storage process
         itsStorageProcesses[rank]->stop(deadline_ts);
 
-        // obtain feedback for LTA
-        itsFeedbackLTA.adoptCollection(itsStorageProcesses[rank]->feedbackLTA());
-
         // free the StorageProcess object
         itsStorageProcesses[rank] = 0;
       }
diff --git a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.h b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.h
index 04151848e90d6697d6297fb44e06c1136cf15f63..2e59471ed5cbec36b60917a4f8ef265dc33a7fde 100644
--- a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.h
+++ b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.h
@@ -80,17 +80,12 @@ namespace LOFAR
       // stop the processes and control threads, given an absolute time out.
       void stop( time_t deadline );
 
-      ParameterSet feedbackLTA() const;
-
     private:
       const Parset                         &itsParset;
       const std::string itsLogPrefix;
 
       std::vector<SmartPtr<StorageProcess> > itsStorageProcesses;
 
-      // All feedback for the LTA obtained by the storage processes
-      ParameterSet itsFeedbackLTA;
-
       // start the processes and control threads
       void start();
 
diff --git a/RTCP/Cobalt/GPUProc/src/rtcp.cc b/RTCP/Cobalt/GPUProc/src/rtcp.cc
index ee93600810e45156acec705f623fa00114cc9f95..544e829e0d20c256ba92abe6e8a6a3960c429641 100644
--- a/RTCP/Cobalt/GPUProc/src/rtcp.cc
+++ b/RTCP/Cobalt/GPUProc/src/rtcp.cc
@@ -52,6 +52,8 @@
 #include <Common/SystemUtil.h>
 #include <Common/StringUtil.h>
 #include <Common/Thread/Trigger.h>
+#include <MessageBus/MsgBus.h>
+#include <MessageBus/Protocols/TaskFeedbackProcessing.h>
 #include <ApplCommon/PVSSDatapointDefs.h>
 #include <ApplCommon/StationInfo.h>
 #include <MACIO/RTmetadata.h>
@@ -168,6 +170,10 @@ int main(int argc, char **argv)
 
   LOG_INFO("===== INIT =====");
 
+  // Initialise message bus
+  LOG_INFO("----- Initialising MessageBus");
+  MessageBus::init();
+
   // Create a parameters set object based on the inputs
   LOG_INFO("----- Reading Parset");
   Parset ps(argv[optind]);
@@ -593,31 +599,20 @@ int main(int argc, char **argv)
     // graceful exit
     storageProcesses->stop(time(0) + outputProcTimeout);
 
-    LOG_INFO("Writing LTA feedback to disk");
+    // send processing feedback
+    ToBus bus("lofar.task.feedback.processing");
 
-    // obtain LTA feedback
     LTAFeedback fb(ps.settings);
-    Parset feedbackLTA;
-
-    // augment LTA feedback with global information
-    feedbackLTA.adoptCollection(fb.allFeedback());
-
-    // process updates from outputProc
-    feedbackLTA.adoptCollection(storageProcesses->feedbackLTA());
 
-    // write LTA feedback to disk
-    const char *LOFARROOT = getenv("LOFARROOT");
-    if (LOFARROOT != NULL) {
-      string feedbackFilename = str(format("%s/var/run/Observation%s_feedback") % LOFARROOT % ps.settings.observationID);
+    Protocols::TaskFeedbackProcessing msg(
+      "Cobalt/GPUProc/rtcp",
+      "",
+      "Processing feedback",
+      str(format("%s") % ps.settings.momID),
+      str(format("%s") % ps.settings.observationID),
+      fb.processingFeedback());
 
-      try {
-        feedbackLTA.writeFile(feedbackFilename, false);
-      } catch (APSException &ex) {
-        LOG_ERROR_STR("Could not write feedback file " << feedbackFilename << ": " << ex);
-      }
-    } else {
-      LOG_WARN("Could not write feedback file: $LOFARROOT not set.");
-    }
+    bus.send(msg);
 
     // final cleanup
     storageProcesses = 0;
diff --git a/RTCP/Cobalt/GPUProc/src/scripts/CobaltVersions.sh b/RTCP/Cobalt/GPUProc/src/scripts/CobaltVersions.sh
index 6465f07bc5ffd29dc8571e24c726a202b04f2be3..55b901be83712424a910de98a09e3353711698dc 100755
--- a/RTCP/Cobalt/GPUProc/src/scripts/CobaltVersions.sh
+++ b/RTCP/Cobalt/GPUProc/src/scripts/CobaltVersions.sh
@@ -13,8 +13,8 @@ function error() {
 if [ -z "$HOSTS" ]; then
   case `hostname` in
     cbt001|cbt002|cbt003|cbt004|cbt005|cbt006|cbt007|cbt008)
-      # Production system
-      HOSTS="cbm001 cbm002 cbm003 cbm004 cbm005 cbm006 cbm007 cbm008"
+      # Production system -- switch test system as well, in case we use cbm009/cbm010!
+      HOSTS="cbm001 cbm002 cbm003 cbm004 cbm005 cbm006 cbm007 cbm008 cbm009 cbm010"
       ;;
 
     cbt009|cbt010)
diff --git a/RTCP/Cobalt/GPUProc/src/scripts/Cobalt_install.sh b/RTCP/Cobalt/GPUProc/src/scripts/Cobalt_install.sh
index 6b7dbad8514539717f6fa452c3947531636f7d44..0e594f82c00c88b753c045fda6688d15d3b56443 100755
--- a/RTCP/Cobalt/GPUProc/src/scripts/Cobalt_install.sh
+++ b/RTCP/Cobalt/GPUProc/src/scripts/Cobalt_install.sh
@@ -19,7 +19,7 @@ if [ "${RELEASE_NAME}" = "" ]; then
   exit 1
 fi
 
-for HOST in ${HOSTS:-cbm001 cbm002 cbm003 cbm004 cbm005 cbm006 cbm007 cbm008 cbm009}; do
+for HOST in ${HOSTS:-cbm001 cbm002 cbm003 cbm004 cbm005 cbm006 cbm007 cbm008 cbm009 cbm010}; do
   echo "ssh-ing to node $HOST"
 
   # Escape double quotes below the following line!
diff --git a/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh b/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
index d903cebebd7e4095958fa25e1d7f6baff2536ab1..fde6a641e02af789f2dfbee3b1189cfcd92089a1 100755
--- a/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
+++ b/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
@@ -12,7 +12,7 @@
 
 function error {
   echo -e "$@" >&2
-  sendback_status 1
+  sendback_state 1
   exit 1
 }
 
@@ -51,7 +51,7 @@ function usage {
     "\n    -B: do NOT add broken antenna information"\
     "\n    -C: run with check tool specified in environment variable"\
     "LOFAR_CHECKTOOL"\
-    "\n    -F: do NOT send feedback to OnlineControl and do NOT send data points to a PVSS gateway"\
+    "\n    -F: do NOT send data points to a PVSS gateway"\
     "\n    -P: create PID file"\
     "\n    -l: run solely on localhost using 'nprocs' MPI processes (isolated test)"\
     "\n    -p: enable profiling" \
@@ -85,66 +85,26 @@ function command_retry {
   done
 }
 
-# Send the result status back to OnlineControl.
+# Send the result state back to LOFAR (MAC, MoM)
 #
 # to report success:
 #   sendback_status 0
 # to report failure:
 #   sendback_status 1
-function sendback_status {
+function sendback_state {
   OBSRESULT="$1"
 
-  if [ -z "$PARSET" ]
+  if [ $OBSRESULT -eq 0 ]
   then
-    echo "Not communicating back to OnlineControl (no parset)"
-    return 0
-  fi
-
-  if [ "$ONLINECONTROL_FEEDBACK" -eq "0" ]
-  then
-    echo "Not communicating back to OnlineControl (disabled on command line)"
-    return 0
-  fi
-
-  if [ "$ONLINECONTROL_FEEDBACK" -eq "1" ]
-  then
-    ONLINECONTROL_USER=`getkey Cobalt.Feedback.userName $USER`
-    ONLINECONTROL_HOST=`getkey Cobalt.Feedback.host`
-
-    if [ $OBSRESULT -eq 0 ]
-    then
-      # ***** Observation ran successfully
-
-      # Copy LTA feedback file to ccu001
-      FEEDBACK_DEST="$ONLINECONTROL_USER@$ONLINECONTROL_HOST:`getkey Cobalt.Feedback.remotePath`"
-
-      echo "Copying feedback to $FEEDBACK_DEST"
-      timeout $KILLOPT 30s scp "$FEEDBACK_FILE" "$FEEDBACK_DEST"
-      FEEDBACK_RESULT=$?
-      if [ $FEEDBACK_RESULT -ne 0 ]
-      then
-        echo "Failed to copy file $FEEDBACK_FILE to $FEEDBACK_DEST (status: $FEEDBACK_RESULT)"
-        OBSRESULT=$FEEDBACK_RESULT
-      fi
-    fi
-
-    # Communicate result back to OnlineControl
-    ONLINECONTROL_RESULT_PORT=$((21000 + $OBSID % 1000))
-
-    if [ $OBSRESULT -eq 0 ]
-    then
-      # Signal success to OnlineControl
-      echo "Signalling success to $ONLINECONTROL_HOST"
-      echo -n "FINISHED" > /dev/tcp/$ONLINECONTROL_HOST/$ONLINECONTROL_RESULT_PORT
-    else
-      # ***** Observation or sending feedback failed for some reason
-      # Signal failure to OnlineControl
-      echo "Signalling failure to $ONLINECONTROL_HOST"
-      echo -n "ABORT" > /dev/tcp/$ONLINECONTROL_HOST/$ONLINECONTROL_RESULT_PORT
-    fi
+    echo "Signalling success"
+    SUCCESS=1
+  else
+    # ***** Observation or sending feedback failed for some reason
+    echo "Signalling failure"
+    SUCCESS=0
   fi
 
-  return 1
+  send_state "$PARSET" $SUCCESS
 }
 
 #############################
@@ -155,8 +115,8 @@ echo "Called as: $0 $@"
 # Set default options
 # ******************************
 
-# Provide feedback to OnlineControl and data points to PVSS?
-ONLINECONTROL_FEEDBACK=1
+# Provide data points to PVSS?
+STATUS_FEEDBACK=1
 
 # Augment the parset with etc/parset-additions.d/* ?
 AUGMENT_PARSET=1
@@ -192,7 +152,7 @@ while getopts ":ABCFP:l:o:p" opt; do
           ;;
       C)  CHECK_TOOL="$LOFAR_CHECKTOOL"
           ;;
-      F)  ONLINECONTROL_FEEDBACK=0
+      F)  STATUS_FEEDBACK=0
           ;;
       P)  PIDFILE="$OPTARG"
           ;;
@@ -295,8 +255,6 @@ then
     setkey Cobalt.OutputProc.executable               "$LOFARROOT/bin/outputProc"
     setkey Cobalt.OutputProc.StaticMetaDataDirectory  "$LOFARROOT/etc"
     setkey Cobalt.FinalMetaDataGatherer.database.host localhost
-    setkey Cobalt.Feedback.host                       localhost
-    setkey Cobalt.Feedback.remotePath                 "$LOFARROOT/var/run"
     setkey Cobalt.PVSSGateway.host                    ""
 
     # Redirect UDP/TCP input streams to any interface on the local machine
@@ -309,7 +267,7 @@ then
     setkey Cobalt.FinalMetaDataGatherer.enabled       false
   fi
 
-  if [ "$ONLINECONTROL_FEEDBACK" -eq "0" ]
+  if [ "$STATUS_FEEDBACK" -eq "0" ]
   then
     setkey Cobalt.PVSSGateway.host                    ""
   fi
@@ -418,11 +376,13 @@ touch $PID_LIST_FILE
 
 LIST_OF_HOSTS=$(getOutputProcHosts $PARSET)
 RANK=0
+VARS="QUEUE_PREFIX=$QUEUE_PREFIX" # Variables to forward to outputProc
 for HOST in $LIST_OF_HOSTS
 do
-  COMMAND="ssh -tt -l $SSH_USER_NAME $KEY_STRING $SSH_USER_NAME@$HOST $OUTPUT_PROC_EXECUTABLE $OBSERVATIONID $RANK"
+  COMMAND="ssh -tt -l $SSH_USER_NAME $KEY_STRING $SSH_USER_NAME@$HOST $VARS $OUTPUT_PROC_EXECUTABLE $OBSERVATIONID $RANK"
+  echo "Starting $COMMAND"
   # keep a counter to allow determination of the rank (needed for binding to rtcp)
-  RANK=$(($RANK + 1))   
+  RANK=$(($RANK + 1))
   
   command_retry "$COMMAND" &  # Start retrying function in the background
   PID=$!                      # get the pid 
@@ -437,8 +397,10 @@ done
 # Run in the background to allow signals to propagate
 #
 # -x LOFARROOT    Propagate $LOFARROOT for rtcp to find GPU kernels, config files, etc.
+# -x QUEUE_PREFIX Propagate $QUEUE_PREFIX for test-specific interaction over the message bus
 # -H              The host list to run on, derived earlier.
 mpirun.sh -x LOFARROOT="$LOFARROOT" \
+          -x QUEUE_PREFIX="$QUEUE_PREFIX" \
           -H "$HOSTS" \
           $MPIRUN_PARAMS \
           $CHECK_TOOL \
@@ -480,7 +442,7 @@ fi
 # Post-process the observation
 # ******************************
 
-sendback_status "$OBSRESULT"
+sendback_state "$OBSRESULT"
 
 # clean up outputProc children
 echo "Allowing 120 second for normal end of outputProc"
diff --git a/RTCP/Cobalt/GPUProc/src/send_state.cc b/RTCP/Cobalt/GPUProc/src/send_state.cc
new file mode 100644
index 0000000000000000000000000000000000000000..777838919f6234c90f29b68e54e3021c4d87e439
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/src/send_state.cc
@@ -0,0 +1,91 @@
+//# send_state.cc: Send lofar.task.feedback.status information
+//# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite is distributed in the hope that it will be useful,
+//# but WITHOUT ANY WARRANTY; without even the implied warranty of
+//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//# GNU General Public License for more details.
+//#
+//# You should have received a copy of the GNU General Public License along
+//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#include <lofar_config.h>
+
+#include <Common/LofarLogger.h>
+#include <CoInterface/Parset.h>
+#include <MessageBus/MsgBus.h>
+#include <MessageBus/Protocols/TaskFeedbackState.h>
+
+#include <boost/format.hpp>
+
+#include <unistd.h>
+
+using namespace LOFAR;
+using namespace LOFAR::Cobalt;
+using namespace std;
+using boost::format;
+
+static void usage(const char *argv0)
+{
+  cerr << "Usage: " << argv0 << " parset success" << endl;
+  cerr << endl;
+  cerr << "  -h: print this message" << endl;
+}
+
+int main(int argc, char **argv)
+{
+  /*
+   * Parse command-line options
+   */
+
+  int opt;
+  while ((opt = getopt(argc, argv, "h")) != -1) {
+    switch (opt) {
+
+    case 'h':
+      usage(argv[0]);
+      return EXIT_SUCCESS;
+
+    default: /* '?' */
+      usage(argv[0]);
+      return EXIT_FAILURE;
+    }
+  }
+
+  // we expect a parset filename and a success indicator as an additional parameter
+  if (optind + 1 >= argc) {
+    usage(argv[0]);
+    return EXIT_FAILURE;
+  }
+
+  INIT_LOGGER("send_status");
+  MessageBus::init();
+
+  Parset parset(argv[optind]);
+  int success = atoi(argv[optind+1]);
+
+  // send status feedback
+  ToBus bus("lofar.task.feedback.state");
+
+  Protocols::TaskFeedbackState msg(
+    "Cobalt/GPUProc/send_state",
+    "",
+    "State feedback",
+    str(format("%s") % parset.settings.momID),
+    str(format("%s") % parset.settings.observationID),
+    success);
+
+  bus.send(msg);
+
+  return 0;
+}
+
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/CMakeLists.txt b/RTCP/Cobalt/GPUProc/test/Storage/CMakeLists.txt
index d27b53f7a22f1cf7738edb2441c6762c2de6dd1a..a01cc37bebb1f2974e6ef4e4341bd022715b6708 100644
--- a/RTCP/Cobalt/GPUProc/test/Storage/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/test/Storage/CMakeLists.txt
@@ -2,6 +2,10 @@
 
 include(LofarCTest)
 
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/tStorageProcesses.run2.in
+  ${CMAKE_CURRENT_BINARY_DIR}/tStorageProcesses.run2 @ONLY)
+
 # DummyStorage is started by tStorageProcesses to emulate an OutputProc process
 lofar_add_executable(DummyStorage DummyStorage.cc)
 lofar_add_test(tStorageProcesses tStorageProcesses.cc DEPENDS DummyStorage)
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/DummyStorage.cc b/RTCP/Cobalt/GPUProc/test/Storage/DummyStorage.cc
index 7a8a1307b47f9050ce5b7fd59cf93dc17f3d8072..b246f19a15b8d111155473f90823f2637b97119d 100644
--- a/RTCP/Cobalt/GPUProc/test/Storage/DummyStorage.cc
+++ b/RTCP/Cobalt/GPUProc/test/Storage/DummyStorage.cc
@@ -43,10 +43,6 @@ unsigned rank;
 
 Exception::TerminateHandler th(Exception::terminate);
 
-FinalMetaData origFinalMetaData;
-
-Mutex logMutex;
-
 void emulateStorage()
 {
   // establish control connection
@@ -55,52 +51,22 @@ void emulateStorage()
 
   // read and print parset
   Parset parset(&stream);
-  {
-    ScopedLock sl(logMutex);
-    cout << "Storage: Parset received." << endl;
-  }
+  cout << "Storage: Parset received." << endl;
 
   // read and print meta data
   FinalMetaData finalMetaData;
   finalMetaData.read(stream);
-  {
-    ScopedLock sl(logMutex);
-
-    ASSERT(finalMetaData.brokenRCUsAtBegin == origFinalMetaData.brokenRCUsAtBegin);
-    ASSERT(finalMetaData.brokenRCUsDuring  == origFinalMetaData.brokenRCUsDuring);
-
-    cout << "Storage: FinalMetaData received and matches." << endl;
-  }
-
-  // write LTA feedback
-  Parset feedbackLTA;
-  feedbackLTA.add("foo", "bar");
-  feedbackLTA.write(&stream);
-}
 
-void emulateFinalMetaDataGatherer()
-{
-  // establish control connection
-  string resource = getStorageControlDescription(observationID, -1);
-  PortBroker::ServerStream stream(resource);
-
-  // read and print parset
-  Parset parset(&stream);
-  {
-    ScopedLock sl(logMutex);
-    cout << "FinalMetaDataGatherer: Parset received." << endl;
-  }
+  //ASSERT(finalMetaData.brokenRCUsAtBegin == origFinalMetaData.brokenRCUsAtBegin);
+  //ASSERT(finalMetaData.brokenRCUsDuring  == origFinalMetaData.brokenRCUsDuring);
 
-  // set and write meta data
-  origFinalMetaData.brokenRCUsAtBegin.push_back( FinalMetaData::BrokenRCU("CS001", "LBA", 2, "2012-01-01 12:34") );
-  origFinalMetaData.brokenRCUsAtBegin.push_back( FinalMetaData::BrokenRCU("RS205", "HBA", 1, "2012-01-01 12:34") );
-  origFinalMetaData.brokenRCUsDuring.push_back( FinalMetaData::BrokenRCU("DE601", "RCU", 3, "2012-01-01 12:34") );
-  origFinalMetaData.write(stream);
+  cout << "Storage: FinalMetaData received and matches." << endl;
 
-  {
-    ScopedLock sl(logMutex);
-    cout << "FinalMetaDataGatherer: FinalMetaData sent." << endl;
-  }
+  // write completion signal
+  bool sentFeedback = false;
+  stream.write(&sentFeedback, sizeof sentFeedback);
+  bool success = true;
+  stream.write(&success, sizeof success);
 }
 
 int main(int argc, char **argv)
@@ -118,7 +84,7 @@ int main(int argc, char **argv)
 
   // Make sure DummyStorage always dies, even if the test
   // malfunctions.
-  alarm(10);
+  alarm(20);
 
   observationID = boost::lexical_cast<int>(argv[1]);
   rank = boost::lexical_cast<unsigned>(argv[2]);
@@ -126,21 +92,10 @@ int main(int argc, char **argv)
   // set up broker server
   PortBroker::createInstance(storageBrokerPort(observationID));
 
-#pragma omp parallel sections
-  {
-#   pragma omp section
-    try {
-      emulateStorage();
-    } catch (Exception &ex) {
-      cout << "Storage caught exception: " << ex << endl;
-    }
-
-#   pragma omp section
-    try {
-      emulateFinalMetaDataGatherer();
-    } catch (Exception &ex) {
-      cout << "FinalMetaDataGatherer caught exception: " << ex << endl;
-    }
+  try {
+    emulateStorage();
+  } catch (Exception &ex) {
+    cout << "Storage caught exception: " << ex << endl;
   }
 }
 
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.cc b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.cc
index 306ba933a95bcfead49498c0f89b84f422931259..0c1d9870b511cfd5362238f80f8969a07d620f3c 100644
--- a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.cc
+++ b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.cc
@@ -56,6 +56,8 @@ void test_protocol()
     THROW_SYSCALL("getcwd");
 
   p.add("Observation.ObsID",                 "12345");
+  p.add("Observation.startTime",             "2015-01-01 00:00:00");
+  p.add("Observation.stopTime",              "2015-01-01 00:01:00");
   p.add("Cobalt.OutputProc.userName",        USER);
   p.add("Cobalt.OutputProc.sshPublicKey",    pubkey);
   p.add("Cobalt.OutputProc.sshPrivateKey",   privkey);
@@ -90,11 +92,6 @@ void test_protocol()
 	
 	    // Give 10 seconds to wrap up
 	    sp.stop(time(0) + 10);
-	
-	    // Obtain LTA feedback
-	    ParameterSet feedbackLTA(sp.feedbackLTA());
-	
-	    ASSERT(feedbackLTA.getString("foo","") == "bar");
   }
 }
 
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.queue b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.queue
new file mode 100644
index 0000000000000000000000000000000000000000..4ec0ed39e87645060dab7300cda59f0907848b20
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.queue
@@ -0,0 +1,38 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.feedback.dataproducts</name>
+         <version>1.0.0</version>
+      </protocol>
+      <source>
+         <name>Cobalt/GPUProc/Storage/StorageProcess</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>Feedback for Correlated Data, subband 0</summary>
+      </source>
+      <ids>
+         <momid>0</momid>
+         <sasid>12345</sasid>
+      </ids>
+   </header>
+   <payload>
+Observation.DataProducts.Output_Correlated_[0].SAP=0
+Observation.DataProducts.Output_Correlated_[0].centralFrequency=0.000000
+Observation.DataProducts.Output_Correlated_[0].channelWidth=3051.757812
+Observation.DataProducts.Output_Correlated_[0].channelsPerSubband=64
+Observation.DataProducts.Output_Correlated_[0].duration=0
+Observation.DataProducts.Output_Correlated_[0].fileFormat=AIPS++/CASA
+Observation.DataProducts.Output_Correlated_[0].filename=SB0.MS
+Observation.DataProducts.Output_Correlated_[0].integrationInterval=1.006633
+Observation.DataProducts.Output_Correlated_[0].location=localhost:.
+Observation.DataProducts.Output_Correlated_[0].percentageWritten=0
+Observation.DataProducts.Output_Correlated_[0].size=0
+Observation.DataProducts.Output_Correlated_[0].startTime=2015-01-01 00:00:00
+Observation.DataProducts.Output_Correlated_[0].stationSubband=0
+Observation.DataProducts.Output_Correlated_[0].subband=0
+
+   </payload>
+</message>
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run
index 474574333959f95d9e89aaee548627a21e85faea..855a8c12020b14cd2cc2c5e717edbf8c240ffe1b 100755
--- a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run
+++ b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run
@@ -1,8 +1,4 @@
 #!/bin/bash
-#
-DummyStorage 12345 0&                  # Run the command
-PID_ID=$!                              # get the PID
 
-tStorageProcesses || exit 1
-wait $PID_ID
-exit 0  # do not exit with DymmyStorage exit. If we are waiting the test should succeed
+# Defer to the .run2, which is constructed by CMake but won't be cleaned up by assay
+bash ./tStorageProcesses.run2
diff --git a/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run2.in b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run2.in
new file mode 100755
index 0000000000000000000000000000000000000000..4491adeaa30cc3022f0e8a033cfc3fa41f621c29
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/test/Storage/tStorageProcesses.run2.in
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+
+# Run a program to talk to
+DummyStorage 12345 0&                  # Run the command
+PID_ID=$!                              # get the PID
+
+source MessageFuncs.sh
+
+# Empty queues (if any)
+create_queue lofar.task.feedback.dataproducts
+
+# Start the test
+tStorageProcesses || exit 1
+wait $PID_ID
+
+# Validate queues
+if have_qpid; then
+  recv_msg lofar.task.feedback.dataproducts > tStorageProcesses.queue
+
+  compare_msg $srcdir/tStorageProcesses.queue tStorageProcesses.queue || exit 1
+fi
+
+# Signal success to parent
+exit 0
+
diff --git a/RTCP/Cobalt/OutputProc/CMakeLists.txt b/RTCP/Cobalt/OutputProc/CMakeLists.txt
index 2aed652557937b472bcd4b9640f6ccb4b1a73650..d12b4addfe84de38b51621ed4e1b1c37c73bf75e 100644
--- a/RTCP/Cobalt/OutputProc/CMakeLists.txt
+++ b/RTCP/Cobalt/OutputProc/CMakeLists.txt
@@ -1,6 +1,6 @@
 # $Id$
 
-lofar_package(OutputProc 1.0 DEPENDS Common Stream CoInterface MSLofar LofarStMan MACIO)
+lofar_package(OutputProc 1.0 DEPENDS Common Stream CoInterface MSLofar LofarStMan MACIO MessageBus)
 
 include(LofarFindPackage)
 lofar_find_package(Casacore COMPONENTS casa ms tables REQUIRED)
diff --git a/RTCP/Cobalt/OutputProc/src/GPUProcIO.cc b/RTCP/Cobalt/OutputProc/src/GPUProcIO.cc
index d3c6720f26bb3c7d86b60c91a81f411f88608ffc..fffaff1bdfbb114bd984ce757e4f7f4b5e3a9f0e 100644
--- a/RTCP/Cobalt/OutputProc/src/GPUProcIO.cc
+++ b/RTCP/Cobalt/OutputProc/src/GPUProcIO.cc
@@ -32,6 +32,8 @@
 #include <Common/LofarLogger.h>
 #include <Common/StringUtil.h>
 #include <Common/Exceptions.h>
+#include <MessageBus/MsgBus.h>
+#include <MessageBus/Protocols/TaskFeedbackDataproducts.h>
 #include <Stream/PortBroker.h>
 #include <ApplCommon/PVSSDatapointDefs.h>
 #include <ApplCommon/StationInfo.h>
@@ -249,22 +251,45 @@ bool process(Stream &controlStream, unsigned myRank)
      * LTA FEEDBACK
      */
 
-    LOG_DEBUG_STR("Retrieving LTA feedback");
-    Parset feedbackLTA;
+    LOG_DEBUG_STR("Forwarding LTA feedback");
 
-    for (size_t i = 0; i < subbandWriters.size(); ++i)
-      feedbackLTA.adoptCollection(subbandWriters[i]->feedbackLTA());
-    for (size_t i = 0; i < tabWriters.size(); ++i)
-      feedbackLTA.adoptCollection(tabWriters[i]->feedbackLTA());
+    ToBus bus("lofar.task.feedback.dataproducts");
 
-    LOG_DEBUG_STR("Forwarding LTA feedback");
-    try {
-      feedbackLTA.write(&controlStream);
-    } catch (LOFAR::Exception &err) {
-      success = false;
-      LOG_ERROR_STR("Failed to forward LTA feedback information: " << err);
+    const std::string myName = str(boost::format("Cobalt/OutputProc on %s") % myHostName);
+
+    for (size_t i = 0; i < subbandWriters.size(); ++i) {
+      Protocols::TaskFeedbackDataproducts msg(
+        myName,
+        "",
+        str(boost::format("Feedback for Correlated Data, subband %s") % subbandWriters[i]->streamNr()),
+        str(format("%s") % parset.settings.momID),
+        str(format("%s") % parset.settings.observationID),
+        subbandWriters[i]->feedbackLTA());
+
+      bus.send(msg);
+    }
+
+    for (size_t i = 0; i < tabWriters.size(); ++i) {
+      Protocols::TaskFeedbackDataproducts msg(
+        myName,
+        "",
+        str(boost::format("Feedback for Beamformed Data, file nr %s") % tabWriters[i]->streamNr()),
+        str(format("%s") % parset.settings.momID),
+        str(format("%s") % parset.settings.observationID),
+        tabWriters[i]->feedbackLTA());
+
+      bus.send(msg);
     }
 
+    /*
+     * SIGN OFF
+     */
+
+    bool sentFeedback = true;
+
+    controlStream.write(&sentFeedback, sizeof sentFeedback);
+    controlStream.write(&success, sizeof success);
+
     return success;
   }
 }
diff --git a/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc b/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
index 3914faeab3bc726991a6dc53df982b559a2c746f..711bc2f0a9c1f4c888367bfd19047641400a066b 100644
--- a/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
+++ b/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
@@ -30,6 +30,7 @@
 #include <Common/SystemUtil.h>
 #include <MSLofar/FailedTileInfo.h>
 #include <CoInterface/CorrelatedData.h>
+#include <CoInterface/LTAFeedback.h>
 
 #include <tables/Tables/Table.h>
 #include <casa/Quanta/MVTime.h>
@@ -54,6 +55,10 @@ namespace LOFAR
       itsMSname(msName),
       itsParset(parset)
     {
+      // Add file-specific processing feedback
+      LTAFeedback fb(itsParset.settings);
+      itsConfiguration.adoptCollection(fb.correlatedFeedback(subbandIndex));
+
       if (LofarStManVersion > 1) {
         string seqfilename = str(format("%s/table.f0seqnr") % msName);
 
diff --git a/RTCP/Cobalt/OutputProc/src/MSWriterDAL.cc b/RTCP/Cobalt/OutputProc/src/MSWriterDAL.cc
index 51129879950f6e5bb798047e64e0ab22b33cab8d..260fab955922c19078ce90a3d0ab2eceb3eb0151 100644
--- a/RTCP/Cobalt/OutputProc/src/MSWriterDAL.cc
+++ b/RTCP/Cobalt/OutputProc/src/MSWriterDAL.cc
@@ -40,6 +40,7 @@
 #include <Common/StreamUtil.h>
 #include <Common/Thread/Mutex.h>
 #include <CoInterface/StreamableData.h>
+#include <CoInterface/LTAFeedback.h>
 #include <OutputProc/Package__Version.h>
 
 #include <dal/lofar/BF_File.h>
@@ -110,6 +111,10 @@ namespace LOFAR
       itsNextSeqNr(0),
       itsFileNr(fileno)
     {
+      // Add file-specific processing feedback
+      LTAFeedback fb(itsParset.settings);
+      itsConfiguration.adoptCollection(fb.beamFormedFeedback(itsFileNr));
+
       itsNrExpectedBlocks = itsParset.settings.nrBlocks();
 
       string h5filename = forceextension(string(filename),".h5");
diff --git a/RTCP/Cobalt/OutputProc/src/outputProc.cc b/RTCP/Cobalt/OutputProc/src/outputProc.cc
index 39407435760cceb38492b31110eba99d723617b0..4e469d7fdae0533efa95bb419898ee1e30ae63da 100644
--- a/RTCP/Cobalt/OutputProc/src/outputProc.cc
+++ b/RTCP/Cobalt/OutputProc/src/outputProc.cc
@@ -38,6 +38,7 @@
 #include <CoInterface/Stream.h>
 #include <CoInterface/OMPThread.h>
 #include <OutputProc/Package__Version.h>
+#include <MessageBus/MsgBus.h>
 #include "GPUProcIO.h"
 #include "IOPriority.h"
 
@@ -97,6 +98,8 @@ int main(int argc, char *argv[])
 
   INIT_LOGGER("outputProc"); // also attaches to CasaLogSink
 
+  MessageBus::init();
+
   LOG_DEBUG_STR("Started: " << argv[0] << ' ' << argv[1] << ' ' << argv[2]);
   LOG_INFO_STR("OutputProc version " << OutputProcVersion::getVersion() << " r" << OutputProcVersion::getRevision());
 
diff --git a/SAS/CMakeLists.txt b/SAS/CMakeLists.txt
index 4cfb43c0523cb2092f2408ab783d27ab306d61da..6b44144c0fa6bba0d13ab3189af2fd86edb2c8f4 100644
--- a/SAS/CMakeLists.txt
+++ b/SAS/CMakeLists.txt
@@ -4,3 +4,4 @@ lofar_add_package(OTDB)
 lofar_add_package(OTB)
 lofar_add_package(OTDB_SQL OTDB/sql)
 lofar_add_package(Scheduler)
+lofar_add_package(SAS_Feedback Feedback_Service)
diff --git a/SAS/Feedback_Service/CMakeLists.txt b/SAS/Feedback_Service/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..908452ac68c61484e7003af9453c98db30ba3c38
--- /dev/null
+++ b/SAS/Feedback_Service/CMakeLists.txt
@@ -0,0 +1,11 @@
+# $Id: CMakeLists.txt 23213 2012-12-07 13:00:09Z loose $
+
+lofar_package(SAS_Feedback 1.0 DEPENDS Common MACIO GCFTM OTDB MessageBus)
+
+include(LofarFindPackage)
+lofar_find_package(Boost REQUIRED COMPONENTS date_time)
+lofar_find_package(PQXX REQUIRED)
+
+add_subdirectory(src)
+#add_subdirectory(test)
+
diff --git a/SAS/Feedback_Service/package.dox b/SAS/Feedback_Service/package.dox
new file mode 100644
index 0000000000000000000000000000000000000000..23d33bb5e72cf84e9c9e18c6cb4fa5297406cb69
--- /dev/null
+++ b/SAS/Feedback_Service/package.dox
@@ -0,0 +1,6 @@
+// 
+// \ingroup FeedbackService
+// \defgroup Feedback Service that receives feedback.* messages and updates
+// the database accordingly.
+// 
+
diff --git a/SAS/Feedback_Service/src/CMakeLists.txt b/SAS/Feedback_Service/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..df3ad9e63ae1866a2bcfcdc4ebdcb42e8707e3c8
--- /dev/null
+++ b/SAS/Feedback_Service/src/CMakeLists.txt
@@ -0,0 +1,10 @@
+# $Id: CMakeLists.txt 30676 2015-01-07 14:09:34Z mol $
+
+include(LofarPackageVersion)
+
+lofar_add_library(sas_feedback Package__Version.cc)
+
+lofar_add_bin_program(versionsas_feedback versionsas_feedback.cc)
+lofar_add_bin_program(FeedbackService Feedback.cc FeedbackMain.cc)
+
+install(FILES FeedbackService.conf DESTINATION etc)
diff --git a/SAS/Feedback_Service/src/Feedback.cc b/SAS/Feedback_Service/src/Feedback.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0526a7e1e176801ccf2056e9f1bff3bd87c9faec
--- /dev/null
+++ b/SAS/Feedback_Service/src/Feedback.cc
@@ -0,0 +1,263 @@
+//#  Feedback.cc: one_line_description
+//#
+//#  Copyright (C) 2015
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: $
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+#include <signal.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <Common/LofarLocators.h>
+#include <Common/ParameterSet.h>
+#include <Common/ParameterRecord.h>
+#include <Common/Version.h>
+#include <GCF/TM/GCF_Control.h>
+#include <OTDB/TreeValue.h>
+#include <SAS_Feedback/Package__Version.h>
+#include "Feedback.h"
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+using namespace boost::posix_time;
+
+namespace LOFAR {
+  using namespace OTDB;
+  using namespace GCF::TM;
+  namespace SAS {
+
+static Feedback*	thisFeedback = 0;
+
+//
+// Feedback()
+//
+Feedback::Feedback() :
+	GCFTask		((State)&Feedback::connect2OTDB_state, "FeedbackService"),
+	itsTimer	(0),
+	itsOTDBconn (0),
+	itsMsgQueue (0)
+{
+	// Log who we are.
+	LOG_INFO(Version::getInfo<SAS_FeedbackVersion>("FeedbackService"));
+
+	// attach timer
+	itsTimer = new GCFTimerPort(*this, "TimerPort");
+	ASSERTSTR(itsTimer, "Cannot allocate timer");
+
+	// get the name of the queues to monitor
+	vector<string>	queuenames = globalParameterSet()->getStringVector("FeedbackQueuenames");
+	ASSERTSTR(!queuenames.empty(), "Queuenames not specified in label 'FeedbackQueuenames'");
+
+	// connect to bussystem
+	itsMsgQueue = new FromBus(queuenames[0]);
+	for (size_t i = 1; i < queuenames.size(); ++i) {
+		itsMsgQueue->addQueue(queuenames[i]);
+	}
+
+	// redirect signal handlers
+	thisFeedback = this;
+	signal (SIGINT,  Feedback::sigintHandler);   // ctrl-c
+	signal (SIGTERM, Feedback::sigintHandler);   // kill
+}
+
+//
+// ~Feedback()
+//
+Feedback::~Feedback()
+{
+	delete itsTimer;
+	delete itsMsgQueue;
+	delete itsOTDBconn;
+}
+
+//
+// sigintHandler(signum)
+//
+void Feedback::sigintHandler(int signum)
+{   
+	LOG_INFO (formatString("SIGINT signal detected (%d)",signum));
+    
+	if (thisFeedback) {
+		thisFeedback->finish();
+	}
+}
+
+//
+// finish
+//
+void Feedback::finish()
+{   
+	GCFScheduler::instance()->stop();
+}
+
+
+
+//
+//	connect2OTDB_state(event, port);
+//
+GCFEvent::TResult Feedback::connect2OTDB_state(GCFEvent& event, GCFPortInterface& port)
+{
+	LOG_DEBUG_STR ("connect2OTDB:" << eventName(event) << "@" << port.getName());
+
+	switch (event.signal) {
+	case F_INIT:	break;
+
+	case F_ENTRY: 
+	case F_TIMER: {
+		// Try to setup the connection with the database
+		string	confFile = globalParameterSet()->getString("OTDBconfFile", "SASGateway.conf");
+		ConfigLocator	CL;
+		string	filename = CL.locate(confFile);
+		LOG_DEBUG_STR("Trying to read database information from file " << filename);
+		ParameterSet	otdbconf;
+		otdbconf.adoptFile(filename);
+		string database = otdbconf.getString("SASGateway.OTDBdatabase");
+		string dbhost   = otdbconf.getString("SASGateway.OTDBhostname");
+		itsOTDBconn = new OTDBconnection("paulus", "boskabouter", database, dbhost);
+		if (!itsOTDBconn->connect()) {
+			LOG_FATAL_STR("Cannot connect to database " << database << " on machine " << dbhost << ", retry in 10 seconds");
+			itsTimer->setTimer(10.0);
+			return (GCFEvent::HANDLED);
+		}
+		LOG_INFO_STR("Connected to database " << database << " on machine " << dbhost);
+		TRAN(Feedback::operational_state);
+	} break;
+
+	default:
+		LOG_DEBUG_STR("connect2OTDB: not handled:" << eventName(event));
+		break;
+	} // switch
+	
+	return (GCFEvent::HANDLED);
+}
+
+//
+//	operational_state(event, port);
+//
+GCFEvent::TResult Feedback::operational_state(GCFEvent& event, GCFPortInterface& port)
+{
+	LOG_DEBUG_STR ("operational:" << eventName(event) << "@" << port.getName());
+
+	switch (event.signal) {
+	case F_ENTRY: 
+	case F_TIMER:  {
+		// wait (blocking) for next message
+		Message	msg;
+		if (!itsMsgQueue->getMessage(msg)) {
+			LOG_FATAL_STR("Wow, lost connection with message bus");
+			GCFScheduler::instance()->stop();		// TODO better solution
+		}
+
+		if (!itsOTDBconn->connect()) {
+			LOG_ERROR("Lost connection with OTDB, starting reconnect cycle");
+			delete itsOTDBconn;
+			itsOTDBconn = 0;
+			itsMsgQueue->nack(msg);
+			TRAN (Feedback::connect2OTDB_state);
+			return (GCFEvent::HANDLED);
+		}
+
+		// Yeah, still connected.
+		if (passKVpairsToOTDB(atoi(msg.sasid().c_str()), msg.payload())) {
+			itsMsgQueue->ack(msg);
+			LOG_DEBUG("Message processed successful");
+		}
+		else {
+			itsMsgQueue->reject(msg);
+			LOG_DEBUG("Message rejected");
+		}
+		itsTimer->setTimer(0.0);
+	} break;
+
+	default:
+		LOG_DEBUG_STR("operational: not handled:" << eventName(event));
+		break;
+	} // switch
+
+	return (GCFEvent::HANDLED);
+}
+
+
+//
+// passKVpairsToOTDB()
+//
+// Handler for procssing the messages that are received on the bus.
+//
+bool Feedback::passKVpairsToOTDB(int	obsID, const string&	content)
+{
+	try {
+		TreeValue   tv(itsOTDBconn, obsID);
+
+		// read parameterset
+		ParameterSet	metadata;
+		metadata.adoptBuffer(content);
+
+		// Loop over the parameterset and send the information to the SAS database
+		// During the transition phase from parameter-based to record-based storage in OTDB the
+		// nodenames ending in '_' are implemented both as parameter and as record.
+		ParameterSet::iterator		iter = metadata.begin();
+		ParameterSet::iterator		end  = metadata.end();
+		while (iter != end) {
+			string	key(iter->first);	// make destoyable copy
+			rtrim(key, "[]0123456789");
+	//		bool	doubleStorage(key[key.size()-1] == '_');
+			bool	isRecord(iter->second.isRecord());
+			//   isRecord  doubleStorage
+			// --------------------------------------------------------------
+			//      Y          Y           store as record and as parameters
+			//      Y          N           store as parameters
+			//      N          *           store parameter
+			if (!isRecord) {
+				LOG_DEBUG_STR("BASIC: " << iter->first << " = " << iter->second);
+				tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
+			}
+			else {
+	//			if (doubleStorage) {
+	//				LOG_DEBUG_STR("RECORD: " << iter->first << " = " << iter->second);
+	//				tv.addKVT(iter->first, iter->second, ptime(microsec_clock::local_time()));
+	//			}
+				// to store is a node/param values the last _ should be stipped of
+				key = iter->first;		// destroyable copy
+	//			string::size_type pos = key.find_last_of('_');
+	//			key.erase(pos,1);
+				ParameterRecord	pr(iter->second.getRecord());
+				ParameterRecord::const_iterator	prIter = pr.begin();
+				ParameterRecord::const_iterator	prEnd  = pr.end();
+				while (prIter != prEnd) {
+					LOG_DEBUG_STR("ELEMENT: " << key+"."+prIter->first << " = " << prIter->second);
+					tv.addKVT(key+"."+prIter->first, prIter->second, ptime(microsec_clock::local_time()));
+					prIter++;
+				}
+			}
+			iter++;
+		}
+		LOG_INFO_STR(metadata.size() << " metadata values send to SAS");
+		return (true);
+	}
+	catch (Exception &ex) {
+		LOG_FATAL_STR(ex.what());
+	}
+	return (false);
+}
+
+
+
+  } // namespace SAS
+} // namespace LOFAR
diff --git a/SAS/Feedback_Service/src/Feedback.h b/SAS/Feedback_Service/src/Feedback.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc85c8c0ad11c46d22f4fec63ca8132787dde70a
--- /dev/null
+++ b/SAS/Feedback_Service/src/Feedback.h
@@ -0,0 +1,82 @@
+//#  Feedback.h: Pass key-value pairs to the database.
+//#
+//#  Copyright (C) 2015
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: $
+
+#ifndef FEEDBACK_SERVICE_H_
+#define FEEDBACK_SERVICE_H_
+
+// \file Feedback.h
+// Pass key-value pairs to the database.
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <MACIO/GCF_Event.h>
+#include <GCF/TM/GCF_Control.h>
+#include <OTDB/OTDBconnection.h>
+#include <MessageBus/MsgBus.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  namespace SAS {
+
+using   MACIO::GCFEvent;
+using   GCF::TM::GCFTimerPort;
+using   GCF::TM::GCFPort;
+using   GCF::TM::GCFPortInterface;
+using   GCF::TM::GCFTask;
+using   OTDB::OTDBconnection;
+
+// \addtogroup package
+// @{
+
+
+class Feedback : public GCFTask
+{
+public:
+	Feedback();
+	~Feedback();
+
+	// Interrupthandler for switching to finishingstate when exiting the program.
+	static void sigintHandler (int signum);
+	void finish();
+
+private:
+	GCFEvent::TResult	connect2OTDB_state(GCFEvent& e, GCFPortInterface& p);
+	GCFEvent::TResult	operational_state (GCFEvent& e, GCFPortInterface& p);
+	bool passKVpairsToOTDB(int obsID, const string&	content);
+
+	// Copying is not allowed
+	Feedback(const Feedback&	that);
+	Feedback& operator=(const Feedback& that);
+
+	//# --- Datamembers ---
+	GCFTimerPort*		itsTimer;			// generic timer
+	OTDBconnection*		itsOTDBconn;		// connection with OTDB
+	FromBus*			itsMsgQueue;		// session with Qpid.
+
+};
+
+// @}
+  } // namespace SAS
+} // namespace LOFAR
+
+#endif
diff --git a/SAS/Feedback_Service/src/FeedbackMain.cc b/SAS/Feedback_Service/src/FeedbackMain.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1dffbed678f5f352aa07a2a41e833ba76227c62f
--- /dev/null
+++ b/SAS/Feedback_Service/src/FeedbackMain.cc
@@ -0,0 +1,53 @@
+//#  FeedbackMain.cc: Main entry for the Feedback controller.
+//#
+//#  Copyright (C) 2015
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id: FeedbackMain.cc 23491 2013-01-11 10:07:59Z overeem $
+//#
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/Exception.h>
+#include <GCF/TM/GCF_Control.h>
+
+#include "Feedback.h"
+
+using namespace LOFAR::GCF::TM;
+using namespace LOFAR;
+using namespace LOFAR::SAS;
+
+// Use a terminate handler that can produce a backtrace.
+Exception::TerminateHandler t(Exception::terminate);
+
+int main(int argc, char* argv[])
+{
+	try {
+		GCFScheduler::instance()->init(argc, argv, "FeedbackService");
+
+		Feedback	fbTask;
+		fbTask.start(); 					// make initial transition
+
+		GCFScheduler::instance()->run();	// until stop was called.
+	} catch( Exception &ex ) {
+		LOG_FATAL_STR("Caught exception: " << ex);
+		return 1;
+	}
+
+	return (0);
+}
+
diff --git a/SAS/Feedback_Service/src/FeedbackService.conf b/SAS/Feedback_Service/src/FeedbackService.conf
new file mode 100644
index 0000000000000000000000000000000000000000..64c745844ba358847dc43cc822834cf54423b1b2
--- /dev/null
+++ b/SAS/Feedback_Service/src/FeedbackService.conf
@@ -0,0 +1,7 @@
+#
+# FeedbackService.conf
+#
+# Parameters for FeedbackService to connect to Qpid.
+#
+FeedbackQueuenames = [ "otdb.task.feedback.dataproducts" , "otdb.task.feedback.processing" ]
+
diff --git a/SAS/Feedback_Service/src/fb_data_44883.txt b/SAS/Feedback_Service/src/fb_data_44883.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e6a7627720e1a4fcd441bdf2695137b23c75118f
--- /dev/null
+++ b/SAS/Feedback_Service/src/fb_data_44883.txt
@@ -0,0 +1,40 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>lofar.observation.start</name>
+         <version>1.0</version>
+      </protocol>
+      <source>
+         <name>mySubSystem</name>
+         <user>user</user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>some test message</summary>
+      </source>
+      <ids>
+         <momid>12345</momid>
+         <sasid>44883</sasid>
+      </ids>
+   </header>
+   <payload>
+Observation.Correlator.channelWidth=3051.7578125
+Observation.Correlator.channelsPerSubband=64
+Observation.Correlator.integrationInterval=1.00139008
+Observation.DataProducts.Output_Correlated_[0].SAP=0
+Observation.DataProducts.Output_Correlated_[0].centralFrequency=115039062.500000
+Observation.DataProducts.Output_Correlated_[0].channelWidth=3051.757812
+Observation.DataProducts.Output_Correlated_[0].channelsPerSubband=64
+Observation.DataProducts.Output_Correlated_[0].duration=119.165420
+Observation.DataProducts.Output_Correlated_[0].fileFormat=AIPS++/CASA
+Observation.DataProducts.Output_Correlated_[0].filename=L257915_SAP000_SB000_uv.MS
+Observation.DataProducts.Output_Correlated_[0].integrationInterval=1.001390
+Observation.DataProducts.Output_Correlated_[0].location=locus001:/data/L257915/
+Observation.DataProducts.Output_Correlated_[0].percentageWritten=100
+Observation.DataProducts.Output_Correlated_[0].size=268083200
+Observation.DataProducts.Output_Correlated_[0].startTime=2015-01-15 09:32:09
+Observation.DataProducts.Output_Correlated_[0].stationSubband=77
+Observation.DataProducts.Output_Correlated_[0].subband=0
+   </payload>
+</message>
diff --git a/SAS/OTDB/sql/exportTree_func.sql b/SAS/OTDB/sql/exportTree_func.sql
index 71a729345d6842c9a20f799ecabec303d1bb75c8..0d525c743bdda86d78378d7f0fb6c8f6cc7aab4d 100644
--- a/SAS/OTDB/sql/exportTree_func.sql
+++ b/SAS/OTDB/sql/exportTree_func.sql
@@ -22,6 +22,49 @@
 --  $Id$
 --
 
+-- exportIDs(treeID, prefixLen)
+--
+-- Return all the IDs that are attached to this tree (sas/mom/origin)
+--
+-- Authorisation: none
+--
+-- Tables: 	otdbtree	read
+--
+-- Types:	none
+--
+CREATE OR REPLACE FUNCTION exportIDs(INT4, INT4)
+  RETURNS TEXT AS $$
+    --  $Id$
+	DECLARE
+		vResult			    TEXT := '';
+		vPrefix     		TEXT;
+		vTreeID		 		OTDBtree.treeID%TYPE;
+		vMoMID				OTDBtree.momID%TYPE;
+		vOriginID			OTDBtree.originID%TYPE;
+		aTreeID				ALIAS FOR $1;
+		aPrefixLen			ALIAS FOR $2;
+
+	BEGIN
+		-- get processInfo
+		SELECT	treeid, momid, originid
+		INTO	vTreeID, vMoMID, vOriginID
+		FROM	OTDBtree
+		WHERE	treeID = aTreeID;
+		IF NOT FOUND THEN
+		  RAISE EXCEPTION 'Tree % does not exist', aTreeID;
+		END IF;
+
+		SELECT substr(name, aPrefixLen)
+		INTO   vPrefix
+		FROM   getVHitemList(aTreeID, '%.Observation');
+		vResult := vResult || vPrefix || '.otdbID='    || vTreeID   || chr(10);
+		vResult := vResult || vPrefix || '.momID='     || vMoMID    || chr(10);
+		vResult := vResult || vPrefix || '.originID='  || vOriginID || chr(10);
+
+		RETURN vResult;
+	END;
+$$ LANGUAGE plpgsql;
+
 --
 -- recursive helper function
 -- fullTemplateNodeName (treeID, nodeID, lastPart)
@@ -288,7 +331,7 @@ CREATE OR REPLACE FUNCTION exportTree(INT4, INT4, INT4)
 		  vResult := vResult || exportPICSubTree($2, $3, vPrefixLen+2);
 		ELSE
 		  IF vIsVicTree THEN
-		    vResult := vResult || exportVICSubTree($2, $3, vPrefixLen+2) || exportProcessType($2, vPrefixLen+2) || exportCampaign($2, vPrefixLen+2);
+		    vResult := vResult || exportVICSubTree($2, $3, vPrefixLen+2) || exportProcessType($2, vPrefixLen+2) || exportCampaign($2, vPrefixLen+2) || exportIDs($2, vPrefixLen+2);
 		  ELSE
 			vResult := vResult || exportTemplateSubTree($2, $3, '');
 		  END IF;
diff --git a/SubSystems/CCU_MAC/CMakeLists.txt b/SubSystems/CCU_MAC/CMakeLists.txt
index 3386fbd5067dc0bbe023eeb8a66dd46d6328386f..e8ddd38992d67474da2bcd49cf83d327eed2217e 100644
--- a/SubSystems/CCU_MAC/CMakeLists.txt
+++ b/SubSystems/CCU_MAC/CMakeLists.txt
@@ -1,5 +1,5 @@
 # $Id$
 
 lofar_package(CCU_MAC 
-  DEPENDS CEPCU CUDaemons CURTDBDaemons StaticMetaData)
+  DEPENDS CEPCU CUDaemons CURTDBDaemons StaticMetaData MessageDaemons)
 
diff --git a/SubSystems/MCU_MAC/CMakeLists.txt b/SubSystems/MCU_MAC/CMakeLists.txt
index 4cf6b00c6e7ffb24f136d5eb41ffffa887c9c5b6..b92b378f0fd3d9e00bf620a44cad1038020df66a 100644
--- a/SubSystems/MCU_MAC/CMakeLists.txt
+++ b/SubSystems/MCU_MAC/CMakeLists.txt
@@ -1,4 +1,4 @@
 # $Id$
 
 lofar_package(MCU_MAC 
-  DEPENDS MainCU CUDaemons CURTDBDaemons StaticMetaData)
+  DEPENDS MainCU CUDaemons CURTDBDaemons StaticMetaData SAS_Feedback)
diff --git a/SubSystems/Offline/CMakeLists.txt b/SubSystems/Offline/CMakeLists.txt
index f11dad6519c8ead9b279515f1a33952fb0577b33..f11418570ff5891292fe2deb87bfe63fa7004afe 100644
--- a/SubSystems/Offline/CMakeLists.txt
+++ b/SubSystems/Offline/CMakeLists.txt
@@ -1,4 +1,4 @@
 # $Id$
 
-lofar_package(Offline DEPENDS CEP MSLofar StaticMetaData)
+lofar_package(Offline DEPENDS CEP MSLofar StaticMetaData MessageBus)
 
diff --git a/SubSystems/Online_Cobalt/install/install_qpid.sh b/SubSystems/Online_Cobalt/install/install_qpid.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f77144ac0c639abd23fcaaf38c4c71e35fbf9084
--- /dev/null
+++ b/SubSystems/Online_Cobalt/install/install_qpid.sh
@@ -0,0 +1,90 @@
+#!/bin/bash -eu
+
+# Note: this script is derived from the QPID build procedure
+# described on http://www.lofar.org/wiki/doku.php?id=qpid:build
+
+# We need to be lofarbuild to have the proper writing rights
+[ "`whoami`" == "lofarbuild" ]
+
+# Download location for the latest QPID source
+PROTON_SOURCE="http://svn.apache.org/repos/asf/qpid/proton/branches/0.8"
+QPID_SOURCE="http://svn.apache.org/repos/asf/qpid/branches/0.30/qpid/"
+
+QPID_INSTALLDIR=/localhome/lofar/qpid
+
+# ********************************************
+#  Install latest PROTON & QPID
+#
+#  into $QPID_INSTALLDIR
+# ********************************************
+echo "Configuring PROTON and QPID..."
+mkdir -p $QPID_INSTALLDIR
+
+QPID_BUILDDIR=`mktemp -d`
+pushd $QPID_BUILDDIR >/dev/null
+
+echo "  Downloading PROTON..."
+svn co $PROTON_SOURCE proton >/dev/null
+
+echo "  Configuring PROTON..."
+pushd proton >/dev/null
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=$QPID_INSTALLDIR -DBUILD_PERL=OFF .. > cmake.log
+
+echo "  Building PROTON..."
+make -j 8 > make.log
+
+echo "  Installing PROTON..."
+make -j 8 install > make_install.log
+
+# back to QPID_BUILDDIR
+popd >/dev/null
+
+echo "  Downloading QPID..."
+svn co $QPID_SOURCE qpid >/dev/null
+
+echo "  Configuring QPID C bindings..."
+pushd qpid/cpp >/dev/null
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=$QPID_INSTALLDIR -DProton_DIR=/localhome/lofar/qpid/lib/cmake/Proton -DBUILD_XML=OFF -DBUILD_SSL=OFF -DBUILD_BINDING_RUBY=OFF .. > cmake.log
+
+echo "  Building QPID C bindings..."
+make -j 8 > make.log
+
+echo "  Installing QPID C bindings..."
+make -j 8 install > make_install.log
+
+# back to QPID_BUILDDIR
+popd >/dev/null
+
+echo "  Building and installing QPID Python bindings..."
+pushd qpid/python >/dev/null
+./setup.py build > setup_build.log
+./setup.py install --home=$QPID_INSTALLDIR > setup_install.log
+
+echo "  Building and installing QPID Python QMF..."
+popd >/dev/null
+pushd qpid/extras/qmf >/dev/null
+./setup.py build > setup_build.log
+./setup.py install --home=$QPID_INSTALLDIR > setup_install.log
+
+echo "  Building and installing QPID Python tools..."
+popd >/dev/null
+pushd qpid/tools >/dev/null
+./setup.py build > setup_build.log
+./setup.py install --home=$QPID_INSTALLDIR > setup_install.log
+
+echo "  Creating .profile..."
+PYTHONVERSION=`python -c 'import platform; print "%s.%s" % platform.python_version_tuple()[0:2]'`
+cat > $QPID_INSTALLDIR/.profile << EOF
+export PATH=\$PATH:$QPID_INSTALLDIR/sbin/:$QPID_INSTALLDIR/bin/:$QPID_INSTALLDIR/local/bin/
+export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$QPID_INSTALLDIR/lib:$QPID_INSTALLDIR/local/lib/
+export PYTHONPATH=\$PYTHONPATH:$QPID_INSTALLDIR/lib/python/:$QPID_INSTALLDIR/lib/python$PYTHONVERSION/site-packages/
+EOF
+
+echo "  Cleaning up..."
+popd >/dev/null
+rm -rf "$QPID_BUILDDIR"
+
diff --git a/SubSystems/Online_Cobalt/install/postinstall.sh b/SubSystems/Online_Cobalt/install/postinstall.sh
index a894b5fd5c6366e16c89506afa22d737d93db90c..f84f819ca187c5192751a64c6c35ce8c7999b052 100755
--- a/SubSystems/Online_Cobalt/install/postinstall.sh
+++ b/SubSystems/Online_Cobalt/install/postinstall.sh
@@ -35,6 +35,7 @@ function postinstall_lofarbuild {
   ./install_IERS.sh
   ./install_DAL.sh
   ./install_casacore.sh
+  ./install_qpid.sh
 }
 
 case "`whoami`" in
diff --git a/SubSystems/Online_Cobalt/test/CMakeLists.txt b/SubSystems/Online_Cobalt/test/CMakeLists.txt
index 67349fe148aef60bc99695d5d8e3cb4144023d35..9682fe742845f10afcbcea8ac4c0b8c8964a7754 100644
--- a/SubSystems/Online_Cobalt/test/CMakeLists.txt
+++ b/SubSystems/Online_Cobalt/test/CMakeLists.txt
@@ -2,15 +2,15 @@
 
 include(LofarCTest)
 
-foreach(_file testFuncs runtest)
+foreach(_file testFuncs.sh runtest.sh tStatusFeedback.run2)
   configure_file(
-    ${CMAKE_CURRENT_SOURCE_DIR}/${_file}.sh.in
-    ${CMAKE_CURRENT_BINARY_DIR}/${_file}.sh @ONLY)
+    ${CMAKE_CURRENT_SOURCE_DIR}/${_file}.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${_file} @ONLY)
 endforeach()
 
 set(_tests
   tgenerateStationStreams
-  tMACfeedback
+  tStatusFeedback
   tProductionParsets
   tstartBGL
 )
diff --git a/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.processing b/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.processing
new file mode 100644
index 0000000000000000000000000000000000000000..21dafb3099c1f3dcb20bc810853ade3d8f99cbec
--- /dev/null
+++ b/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.processing
@@ -0,0 +1,30 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.feedback.processing</name>
+         <version>1.0.0</version>
+      </protocol>
+      <source>
+         <name>Cobalt/GPUProc/rtcp</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>Processing feedback</summary>
+      </source>
+      <ids>
+         <momid>0</momid>
+         <sasid>76966</sasid>
+      </ids>
+   </header>
+   <payload>
+Observation.Correlator.channelWidth=12207.03125
+Observation.Correlator.channelsPerSubband=16
+Observation.Correlator.integrationInterval=0.25165824
+Observation.DataProducts.nrOfOutput_Beamformed_=0
+Observation.DataProducts.nrOfOutput_Correlated_=5
+_isCobalt=T
+
+   </payload>
+</message>
diff --git a/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.state b/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.state
new file mode 100644
index 0000000000000000000000000000000000000000..be60b26610df342f9d804c1ee123b3517b503d13
--- /dev/null
+++ b/SubSystems/Online_Cobalt/test/Correlator/tCorrelate_1sec_1st_5sb_noflagging.output/queues/lofar.task.feedback.state
@@ -0,0 +1,27 @@
+<message>
+   <header>
+      <system>LOFAR</system>
+      <version>1.0.0</version>
+      <protocol>
+         <name>task.feedback.state</name>
+         <version>1.0.0</version>
+      </protocol>
+      <source>
+         <name>Cobalt/GPUProc/send_state</name>
+         <user></user>
+         <uuid></uuid>
+         <timestamp></timestamp>
+         <summary>State feedback</summary>
+      </source>
+      <ids>
+         <momid>0</momid>
+         <sasid>76966</sasid>
+      </ids>
+   </header>
+   <payload>
+<task>
+  <type>observation</type>
+  <state>finished</state>
+</task>
+   </payload>
+</message>
diff --git a/SubSystems/Online_Cobalt/test/MockOnlineControl.sh b/SubSystems/Online_Cobalt/test/MockOnlineControl.sh
deleted file mode 100755
index d22f2c3ea63e2c27b6535f33de7d863a9a77aa00..0000000000000000000000000000000000000000
--- a/SubSystems/Online_Cobalt/test/MockOnlineControl.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-
-# A mock OnlineControl to receive the observation status
-# and the LTA feedback.
-
-# 1. Read parset
-PARSET="$1"
-
-function error {
-  echo "$@"
-  exit 1
-}
-
-function getkey {
-  KEY=$1
-  <$PARSET perl -ne '/^'$KEY'\s*=\s*"?(.*?)"?\s*$/ || next; print "$1";' | tail -n 1
-}
-
-[ -n "$PARSET" ] || error "No parset specified"
-[ -r "$PARSET" ] || error "Cannot read parset: $PARSET"
-
-# 2. Open port @ 21000 + 1000 % obsid
-OBSID=`getkey Observation.ObsID`
-RESULT_PORT=$((21000 + $OBSID % 1000))
-
-STATUSSTR=`timeout 120s nc -l $RESULT_PORT`
-
-# 3. Read string: ABORT or FINISHED
-if [ "$STATUSSTR" == "FINISHED" ]
-then
-  echo "Observation reported success"
-
-  # 4. If finished, check for existence of feedback file
-  FEEDBACK_FILE=`getkey Cobalt.Feedback.remotePath`/Observation${OBSID}_feedback
-
-  # Check existence and access rights
-  [ -e $FEEDBACK_FILE ] || error "Feedback file not found: $FEEDBACK_FILE"
-  [ -r $FEEDBACK_FILE ] || error "Feedback file not readable: $FEEDBACK_FILE"
-  [ -f $FEEDBACK_FILE ] || error "Feedback file not a regular file: $FEEDBACK_FILE"
-
-  # Check file size
-  FILESIZE=`stat -c %s $FEEDBACK_FILE`
-  [ $FILESIZE -ne 0 ] || error "Feedback file empty: $FEEDBACK_FILE"
-elif [ "$STATUSSTR" == "ABORT" ]
-then
-  echo "Observation reported failure"
-else
-  error "Invalid status string: '$STATUSSTR'"
-fi
-
-exit 0
-
diff --git a/SubSystems/Online_Cobalt/test/runtest.sh.in b/SubSystems/Online_Cobalt/test/runtest.sh.in
index d3fc83b64248ebdd4151599c9ec71a1fb1a23acb..04e5845e1ae4447d6dc566597ae5dedfda074c17 100755
--- a/SubSystems/Online_Cobalt/test/runtest.sh.in
+++ b/SubSystems/Online_Cobalt/test/runtest.sh.in
@@ -36,7 +36,7 @@ echo "  in directory $(pwd)"
   [ -n "$(echo *.raw)" ]  || error "runObservation.sh produced no output files"
 
   # create script to accept output (ie. copy it to the source dir for check in)
-  echo "#!/bin/sh
+  echo "#!/bin/bash
   cp ${PWD}/*.raw ${REFDIR}" > accept_output
   chmod a+x accept_output
 
@@ -60,5 +60,21 @@ echo "  in directory $(pwd)"
     done
   done
 
+  if have_qpid; then
+    # validate the contents of the queues
+    mkdir "queues" || error "Failed to create temporary directory ${OUTDIR}/queues"
+    echo "[ -d ${PWD}/queues ] && cp -r ${PWD}/queues ${REFDIR}" >> accept_output
+    QUEUES=`cd ${REFDIR}/queues 2>/dev/null && ls`
+    INCORRECT_QUEUES=""
+    for Q in $QUEUES; do
+      echo "Comparing output of queue $Q"
+      recv_all_msgs "$Q" > queues/$Q
+      compare_msg ${REFDIR}/queues/$Q queues/$Q || INCORRECT_QUEUES+="$Q " 
+    done
+
+    if [ "$INCORRECT_QUEUES" != "" ]; then
+      error "Output of queue(s) $INCORRECT_QUEUES do(es) not match"
+    fi
+  fi
 ) || exit 1
 
diff --git a/SubSystems/Online_Cobalt/test/tMACfeedback.run b/SubSystems/Online_Cobalt/test/tMACfeedback.run
deleted file mode 100755
index 620ee8e3575357353286b735a09be3c3984c0dd8..0000000000000000000000000000000000000000
--- a/SubSystems/Online_Cobalt/test/tMACfeedback.run
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-
-. ./testFuncs.sh
-
-function test_parset {
-  PARSET="$1" 
-  EXPECTED_OBSRESULT="$2"
-  EXTRA_PARAMS="$3"
-
-  echo "Testing $PARSET, expecting result $EXPECTED_OBSRESULT"
-
-  # Add the connection information for this test
-  echo "Cobalt.Feedback.host=localhost" >> $PARSET
-  echo "Cobalt.Feedback.remotePath=$LOFARROOT/var/run" >> $PARSET
-  echo "Cobalt.FinalMetaDataGatherer.host=localhost" >> $PARSET
-
-  # Start a mock OnlineControl to verify the communications of runObservation.sh
-  $srcdir/MockOnlineControl.sh $PARSET &
-  ONLINECONTROL_PID=$!
-
-  # Run the observation
-  runObservation.sh -B -C -l 1 $EXTRA_PARAMS $PARSET
-  OBSRESULT=$?
-
-  # Wait for OnlineControl to finish
-  wait $ONLINECONTROL_PID
-  ONLINECONTROLRESULT=$?
-
-  if [ $OBSRESULT -ne $EXPECTED_OBSRESULT ]; then
-    echo "runObservation.sh failed (status: $OBSRESULT)"
-    exit 1
-  fi
-
-  if [ $ONLINECONTROLRESULT -gt 0 ]; then
-    echo "MockOnlineControl.sh failed (status: $ONLINECONTROLRESULT)"
-    exit 1
-  fi
-}
-
-test_parset $PWD/tMACfeedback.in_parset_success_1 0 ""
-test_parset $PWD/tMACfeedback.in_parset_failure_1 1 "-o Cobalt.Nodes=[unreachable]"
-
-# Everything went ok
-exit 0
-
diff --git a/SubSystems/Online_Cobalt/test/tMACfeedback.sh b/SubSystems/Online_Cobalt/test/tMACfeedback.sh
deleted file mode 100755
index 5ea49e61cbf0971b5b46ce0445e5c77bcb98576e..0000000000000000000000000000000000000000
--- a/SubSystems/Online_Cobalt/test/tMACfeedback.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-./runctest.sh tMACfeedback
diff --git a/SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_failure_1 b/SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_failure_1
similarity index 100%
rename from SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_failure_1
rename to SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_failure_1
diff --git a/SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_success_1 b/SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_success_1
similarity index 100%
rename from SubSystems/Online_Cobalt/test/tMACfeedback.in_parset_success_1
rename to SubSystems/Online_Cobalt/test/tStatusFeedback.in_parset_success_1
diff --git a/SubSystems/Online_Cobalt/test/tStatusFeedback.run b/SubSystems/Online_Cobalt/test/tStatusFeedback.run
new file mode 100755
index 0000000000000000000000000000000000000000..a2dbabeefb09e4705a2861fb66940405d0f2fdee
--- /dev/null
+++ b/SubSystems/Online_Cobalt/test/tStatusFeedback.run
@@ -0,0 +1,2 @@
+#!/bin/sh
+./tStatusFeedback.run2
diff --git a/SubSystems/Online_Cobalt/test/tStatusFeedback.run2.in b/SubSystems/Online_Cobalt/test/tStatusFeedback.run2.in
new file mode 100755
index 0000000000000000000000000000000000000000..bca4e8a3a97275c552407909b5c9c5ea9dce8ea5
--- /dev/null
+++ b/SubSystems/Online_Cobalt/test/tStatusFeedback.run2.in
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+. ./testFuncs.sh
+
+function test_parset {
+  PARSET="$1" 
+  EXPECTED_OBSRESULT="$2"
+  EXTRA_PARAMS="$3"
+
+  echo "Testing $PARSET, expecting result $EXPECTED_OBSRESULT"
+
+  # Add the connection information for this test
+  echo "Cobalt.FinalMetaDataGatherer.host=localhost" >> $PARSET
+
+  # Run the observation
+  runObservation.sh -B -C -l 1 $EXTRA_PARAMS $PARSET
+  OBSRESULT=$?
+
+  if [ $OBSRESULT -ne $EXPECTED_OBSRESULT ]; then
+    echo "runObservation.sh failed (status: $OBSRESULT)"
+    exit 1
+  fi
+
+  # Pull the message from the status queue
+  @QPID_RECEIVE_EXECUTABLE@ -b 127.0.0.1 -q lofar.task.feedback.status || error 'Could not pull status message from bus'
+
+  # Check the message against the expected result
+  # <TODO>
+}
+
+test_parset $PWD/tStatusFeedback.in_parset_success_1 0 ""
+test_parset $PWD/tStatusFeedback.in_parset_failure_1 1 "-o Cobalt.Nodes=[unreachable]"
+
+# Everything went ok
+exit 0
diff --git a/SubSystems/Online_Cobalt/test/tStatusFeedback.sh b/SubSystems/Online_Cobalt/test/tStatusFeedback.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6c8d582909b8210b477eaf031e19a21b31797b9e
--- /dev/null
+++ b/SubSystems/Online_Cobalt/test/tStatusFeedback.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+./runctest.sh tStatusFeedback
diff --git a/SubSystems/Online_Cobalt/test/testFuncs.sh.in b/SubSystems/Online_Cobalt/test/testFuncs.sh.in
index 7744152fef5983ed55bba2846b79005e6f27b404..51e146d427b31edcbfa49d1042334e3c5b09872f 100755
--- a/SubSystems/Online_Cobalt/test/testFuncs.sh.in
+++ b/SubSystems/Online_Cobalt/test/testFuncs.sh.in
@@ -13,9 +13,24 @@ error()
 # Set LOFARROOT and other LOFAR env vars into install directory (var is always set).
 . "@CMAKE_INSTALL_PREFIX@/lofarinit.sh" || error "Could not load our lofarinit.sh -- did you run 'make install'?"
 
+# MessageFuncs.sh provides QPID functionality, and is present in the build directory
+. "MessageFuncs.sh" || error "Could not load MessageFuncs.sh"
+
 # Create runtime output directories if not exists.
 # Not done at build, because it is a post-install setting. Different in production.
 mkdir -p "$LOFARROOT/var/log" "$LOFARROOT/var/run" || error "Failed to create runtime output directories"
 
 # Set all locales to "C" to avoid problems with, e.g., perl.
 export LC_ALL="C"
+
+# Clear all used QPID queues to prevent leakage from previous tests
+# (if they exist, so ignore any errors regarding that)
+
+QUEUES="
+  lofar.task.feedback.state
+  lofar.task.feedback.dataproducts
+  lofar.task.feedback.processing"
+for Q in $QUEUES; do
+  create_queue "$Q"
+done
+
diff --git a/SubSystems/Online_Cobalt/test/tstartBGL.run b/SubSystems/Online_Cobalt/test/tstartBGL.run
index 5718de6be95091cf5c0745a5cde2d88036d9d61b..75e8e3ca24ae45148a8de2e20f8c6305334ab0e0 100755
--- a/SubSystems/Online_Cobalt/test/tstartBGL.run
+++ b/SubSystems/Online_Cobalt/test/tstartBGL.run
@@ -59,8 +59,6 @@ echo "Test 5: normal run"
 echo "        (expects success)"
 echo "***************************"
 # Add the connection information for this test
-echo "Cobalt.Feedback.host=localhost" >> tstartBGL.in_parset
-echo "Cobalt.Feedback.remotePath=$LOFARROOT/var/run" >> tstartBGL.in_parset
 echo "Cobalt.FinalMetaDataGatherer.host=localhost" >> tstartBGL.in_parset
 startBGL.sh 1 2 3 tstartBGL.in_parset 1000 || error "startBGL.sh failed"
 
@@ -88,8 +86,6 @@ echo "Test 6: stop a run"
 echo "        (expects success)"
 echo "***************************"
 # Add the connection information for this test
-echo "Cobalt.Feedback.host=localhost" >> tstartBGL.in_parset
-echo "Cobalt.Feedback.remotePath=$LOFARROOT/var/run" >> tstartBGL.in_parset
 echo "Cobalt.FinalMetaDataGatherer.host=localhost" >> tstartBGL.in_parset
 
 # Run forever
diff --git a/lofar_config.h.cmake b/lofar_config.h.cmake
index 4b033b2950ae56dafd2a7cd02d9a00bfe8df0953..0f04b602f1f5b5a1547ab863e58846e1f1b1cbd5 100644
--- a/lofar_config.h.cmake
+++ b/lofar_config.h.cmake
@@ -156,6 +156,9 @@
 /* Define if using Rational Purify */
 #cmakedefine HAVE_PURIFY 1
 
+/* Define if QPID is installed */
+#cmakedefine HAVE_QPID 1
+
 /* Define if readline is installed */
 #cmakedefine HAVE_READLINE 1
 
@@ -165,6 +168,9 @@
 /* Defined if shared memory is used */
 #cmakedefine HAVE_SHMEM 1
 
+/* Defined if uuid is installed */
+#cmakedefine HAVE_UUID 1
+
 /* Define if WCSLIB is installed */
 #cmakedefine HAVE_WCSLIB 1