diff --git a/.gitattributes b/.gitattributes
index d3a3acbe43981842b1c1d42bb9f5b5a54ac32ddb..0371817b1bde5abf367da574dd91698216506184 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1613,6 +1613,7 @@ CEP/Pipeline/recipes/sip/nodes/setupparmdb.py eol=lf
 CEP/Pipeline/recipes/sip/nodes/setupsourcedb.py eol=lf
 CEP/Pipeline/recipes/sip/nodes/vdsmaker.py eol=lf
 CEP/Pipeline/recipes/sip/pipeline.cfg.in eol=lf
+CEP/Pipeline/recipes/sip/pipeline.cfg.thead01.cep4 -text
 CEP/Pipeline/recipes/sip/plugins/PipelineStep_addMapfile.py -text
 CEP/Pipeline/recipes/sip/plugins/PipelineStep_changeMapfile.py -text
 CEP/Pipeline/recipes/sip/plugins/PipelineStep_combineParsets.py -text
@@ -2344,6 +2345,13 @@ CMake/variants/variants.node503 -text
 CMake/variants/variants.node521 -text
 CMake/variants/variants.phi -text
 CMake/variants/variants.sharkbay -text
+Docker/docker-build-all.sh -text
+Docker/lofar-base/Dockerfile.tmpl -text
+Docker/lofar-base/bashrc -text
+Docker/lofar-base/chuser.sh -text
+Docker/lofar-base/subversion_servers -text
+Docker/lofar-outputproc/Dockerfile.tmpl -text
+Docker/lofar-pipeline/Dockerfile.tmpl -text
 JAVA/GUI/Plotter/dist/lib/sgt.jar -text svneol=unset#unset
 JAVA/GUI/Plotter/doc/Plotter.EAP -text
 JAVA/GUI/Plotter/doc/javadoc/resources/inherit.gif -text
diff --git a/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py b/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
index 9bb498e5514559e110c153312b27aaef97677843..82950986177ebb0cf1e16735b99f0861fa2f5ad0 100644
--- a/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
+++ b/CEP/Pipeline/framework/lofarpipe/support/remotecommand.py
@@ -78,6 +78,8 @@ def run_remote_command(config, logger, host, command, env, arguments = None):
     except:
         method = None
 
+    logger.info("********************** Remote method is %s" % method)
+
     if method == "paramiko":
         try:
             key_filename = config.get('remote', 'key_filename')
@@ -94,13 +96,17 @@ def run_remote_command(config, logger, host, command, env, arguments = None):
         return run_via_mpiexec_cep(logger, command, arguments, host)
     elif method == "slurm_srun_cep3":
         return run_via_slurm_srun_cep3(logger, command, arguments, host)
+    elif method == "custom_cmdline":
+        return run_via_custom_cmdline(logger, host, command, env, arguments, config)
     else:
         return run_via_ssh(logger, host, command, env, arguments)
 
 def run_via_slurm_srun_cep3(logger, command, arguments, host):
+    logger.debug("Dispatching command to %s with srun" % host)
     for arg in arguments:
         command = command + " " + str(arg)
     commandstring = ["srun","-N 1","-n 1","-w",host, "/bin/sh", "-c", "hostname && " + command]
+    #commandstring = ["srun","-N 1","--cpu_bind=map_cpu:none","-w",host, "/bin/sh", "-c", "hostname && " + command]
     # we have a bug that crashes jobs when too many get startet at the same time
     # temporary NOT 100% reliable workaround
     #from random import randint
@@ -179,6 +185,53 @@ def run_via_ssh(logger, host, command, environment, arguments):
     process.kill = lambda : os.kill(process.pid, signal.SIGKILL)
     return process
 
+def run_via_custom_cmdline(logger, host, command, environment, arguments, config):
+    """
+    Dispatch a remote command via a customisable command line
+
+    We return a Popen object pointing at the running executable, to which we add a
+    kill method for shutting down the connection if required.
+
+    The command line is taken from the "remote.cmdline" configuration option,
+    with the following strings replaced:
+
+      {host}         := host to execute command on
+      {command}      := bash command line to be executed
+      {uid}          := uid of the calling user
+
+      {image}        := docker.image configuration option
+      {slurm_job_id} := the SLURM job id to allocate resources in
+
+    """
+    commandArray = ["%s=%s" % (key, value) for key, value in environment.items()]
+    commandArray.append(command)
+    commandArray.extend(re.escape(str(arg)) for arg in arguments)
+    commandStr = " ".join(commandArray)
+
+    try:
+        image = config.get('docker', 'image')
+    except:
+        image = "lofar"
+
+    # Construct the full command line, except for {command}, as that itself
+    # can contain spaces which we don't want to split on.
+    full_command_line = config.get('remote', 'cmdline').format(
+      uid          = os.geteuid(),
+      slurm_job_id = os.environ.get("SLURM_JOB_ID"),
+      docker_image = image,
+      host         = host,
+      command      = "{command}"
+    ).split(' ')
+
+    # Fill in {command} somewhere
+    full_command_line = [x.format(command = commandStr) for x in full_command_line]
+
+    logger.debug("Dispatching command to %s with custom_cmdline: %s" % (host, full_command_line))
+
+    process = spawn_process(full_command_line, logger)
+    process.kill = lambda : os.kill(process.pid, signal.SIGKILL)
+    return process
+
 def run_via_paramiko(logger, host, command, environment, arguments, key_filename):
     """
     Dispatch a remote command via paramiko.
@@ -270,8 +323,7 @@ class ComputeJob(object):
                     "PYTHONPATH": os.environ.get('PYTHONPATH'),
                     "LD_LIBRARY_PATH": os.environ.get('LD_LIBRARY_PATH'),
                     "LOFARROOT" : os.environ.get('LOFARROOT'),
-                    "QUEUE_PREFIX" : os.environ.get('QUEUE_PREFIX',''),
-                    "LOFAR_OBSID" : os.environ.get('LOFAR_OBSID','')
+                    "QUEUE_PREFIX" : os.environ.get('QUEUE_PREFIX','')
                 },
                 arguments = [id, jobhost, jobport]
             )
diff --git a/CEP/Pipeline/recipes/sip/pipeline.cfg.thead01.cep4 b/CEP/Pipeline/recipes/sip/pipeline.cfg.thead01.cep4
new file mode 100644
index 0000000000000000000000000000000000000000..62ad298207d88a02f6ed3c1c416a505127967774
--- /dev/null
+++ b/CEP/Pipeline/recipes/sip/pipeline.cfg.thead01.cep4
@@ -0,0 +1,89 @@
+# This pipeline.cfg was used on the CEP4 test system to show how Docker and SLURM
+# can be used to distribute and run jobs.
+#
+# Is called as follows (inside a SLURM job allocation, f.e. "salloc -N 2"). Replace directory names
+# where needed:
+#
+# # Create this on every node
+# CONFIGDIR=/globalhome/mol/regression_test
+# HOSTS=(`scontrol show hostnames $SLURM_JOB_NODELIST`)
+#
+# # $CONFIGDIR is local, and ocntains both the working_dir (for input/output data) and the config files
+# # /share is a shared disk for the vds files, map files, logs.
+#
+# docker run --rm -e SLURM_JOB_ID=${SLURM_JOB_ID} -e LUSER=${UID} -v $HOME/.ssh:/home/lofar/.ssh:ro -v $CONFIGDIR:$CONFIGDIR -v /shared:/shared --net=host lofar-patched /bin/bash -c "\"$EXTRA_CMDS;python $CONFIGDIR/regression_test_runner.py preprocessing_pipeline --pipelinecfg $CONFIGDIR/pipeline.cfg --testdata $CONFIGDIR/data --computehost1 ${HOSTS[0]} --computehost2 ${HOSTS[1]} --workdir $CONFIGDIR/working_dir --rundir $CONFIGDIR/rundir\""
+
+
+[DEFAULT]
+lofarroot = /opt/lofar
+casaroot = /opt/casacore
+pyraproot = /opt/python-casacore/pyrap
+hdf5root = 
+wcsroot = /opt/wcslib
+pythonpath = /opt/lofar/lib/python2.7/site-packages
+# runtime dir is a global FS (nfs, lustre) to exchange small files (parsets, vds, map files, etc)
+runtime_directory = /shared/mol/regression_test/rundir
+recipe_directories = [%(pythonpath)s/lofarpipe/recipes]
+# working dir is the local dir in which input/output dataproducts reside
+working_directory = /globalhome/mol/regression_test/working_dir
+task_files = [%(lofarroot)s/share/pipeline/tasks.cfg]
+
+[layout]
+job_directory = %(runtime_directory)s/%(job_name)s
+
+[cluster]
+clusterdesc = %(lofarroot)s/share/local.clusterdesc
+
+[deploy]
+engine_ppath = %(pythonpath)s:%(pyraproot)s/lib:/opt/cep/pythonlibs/lib/python/site-packages
+engine_lpath = %(lofarroot)s/lib:%(casaroot)s/lib:%(pyraproot)s/lib:%(hdf5root)s/lib:%(wcsroot)s/lib
+
+[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 = none
+
+[docker]
+image = lofar-patched
+
+[remote]
+#method = slurm_srun_cep3 
+#method = ssh_docker
+method = custom_cmdline
+max_per_node = 1 
+
+# We take the following path to start a remote container:
+#
+#  [container] --SSH--> [host] --SRUN--> [worker node] --DOCKER--> [container]
+#
+# This path is needed because running SRUN from within the container needs a lot of cluster-specific infra
+# (SLURM config files, Munge keys, correct Munge user ID, munged).
+#
+# Throughout this path, we maintain:
+#   * userid, which is set to the user that started the master script container (-e LUSER=`id -u`)
+#   * environment (sudo -p, docker -e K=V, etc)
+#   * pseudo-tty to prevent buffering logs (ssh -tt, docker -t)
+
+#
+# host -> worker node:       srun -w {host} -N 1 -n 1 --jobid={slurm_job_id}
+#                            Needs the specific host, because the test system does not have a global file system.
+#
+# worker node -> container:  docker run -t --rm -e LUSER={uid} -w g -v /home/mol/.ssh:/home/lofar/.ssh:ro -v /globalhome/mol/regression_test:/globalhome/mol/regression_test -v /shared:/shared --net=host {docker_image}
+#                            Starts the container on the worker node, with pretty much the same parameters as the master container:
+#
+#                            --rm: don't linger resources when the container exits
+#                            -e LUSER=(uid): set the user to run as (the calling user)
+#                            -h {host}: set container hostname (for easier debugging) (doesnt work yet, using --net=host instead)
+#                            -v:   map the directories for input/output data, shared storage (parsets, vds files, etc)
+#
+#                            /bin/bash -c
+#
+#                            Required because the pipeline framework needs some bash functionality in the commands it starts.
+#cmdline = ssh -n -tt -x localhost srun -w {host} -N 1 -n 1 --jobid={slurm_job_id} docker run -t --rm -e LUSER={uid} -w g -v /home/mol/.ssh:/home/lofar/.ssh:ro -v /globalhome/mol/regression_test:/globalhome/mol/regression_test -v /shared:/shared --net=host {docker_image} /bin/bash -c
+cmdline = ssh -n -tt -x localhost srun -w {host} -N 1 -n 1 --jobid={slurm_job_id} docker run -t --rm -e LUSER={uid} -v %(runtime_directory)s:%(runtime_directory)s -v %(working_directory)s:%(working_directory)s --net=host {docker_image} /bin/bash -c "\"{command}\""
diff --git a/CMake/LofarPackageList.cmake b/CMake/LofarPackageList.cmake
index c1990c2763c8a3e6ce317952a67fff78c7aae35d..1e8ed2516bee6c38dc4c7c2eb12901c084f97c5a 100644
--- a/CMake/LofarPackageList.cmake
+++ b/CMake/LofarPackageList.cmake
@@ -16,6 +16,7 @@ if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(LOFAR_PACKAGE_LIST_INCLUDED TRUE)
   set(Calibration_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Calibration)
   set(DP3_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/DP3)
+  set(Docker_SOURCE_DIR ${CMAKE_SOURCE_DIR}/Docker)
   set(GSM_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/GSM)
   set(Imager_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/Imager)
   set(LMWCommon_SOURCE_DIR ${CMAKE_SOURCE_DIR}/CEP/LMWCommon)
diff --git a/CMake/UpdatePackageVersion.cmake.in b/CMake/UpdatePackageVersion.cmake.in
index 6732c27242cc2db0c4d64eb43aca04dc8ae306e7..84f72ac731cefeec683bb723e84d0824dae066a1 100644
--- a/CMake/UpdatePackageVersion.cmake.in
+++ b/CMake/UpdatePackageVersion.cmake.in
@@ -77,7 +77,11 @@ if(_result EQUAL 0)
   endif(_root MATCHES ".+")
   if(_rvers MATCHES "^/trunk/")
     set(_rvers "trunk")
+    set(_branch "trunk")
   elseif(_rvers MATCHES "^/tags/" OR _rvers MATCHES "^/branches/")
+    # branch = directory right under tags/ or branches/
+    string(REGEX REPLACE "^/([^/]*/[^/]*)/.*$" "\\1" _branch "${_rvers}")
+
     # We have a task branch (for a bug) or a release branch.
     # Remove all but version and replace _ in version by .
     string(REGEX REPLACE "^/[^/]*/([^/]*)/.*$" "\\1" _rvers "${_rvers}")
@@ -121,6 +125,8 @@ file(WRITE "${_file}.tmp"
   "    // Get the info for this package.\n"
   "    static Version getInfo();\n"
   "\n"
+  "    // Get the branch that was checked out (relative to repository root).\n"
+  "    static std::string getBranch();\n"
   "    // Get the version number of the package (as given in repository).\n"
   "    static std::string getVersion();\n"
   "    // Get the svn version number of the package according to CMakeLists.txt.\n"
@@ -168,12 +174,15 @@ file(APPEND "${_file}.tmp"
   "  Version ${_pkg}Version::getInfo()\n"
   "  {\n"
   "    return Version (\"@PACKAGE_NAME@\",\n"
+  "                    getBranch(),\n"
   "                    getVersion(), getConfVersion(),\n"
   "                    getRevision(), getPackageRevision(),\n"
   "                    getNrChangedFiles(),\n"
   "                    getBuildTime(), getBuildUser(), getBuildMachine());\n"
   "  }\n"
   "\n"
+  "  std::string ${_pkg}Version::getBranch()\n"
+  "    { return \"${_branch}\"; }\n"
   "  std::string ${_pkg}Version::getVersion()\n"
   "    { return \"${_rvers}\"; }\n"
   "  std::string ${_pkg}Version::getConfVersion()\n"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ccb788fe33c4bb7b2458a73210da07d583a68bda..ea914605bb0e6cfd80c3f8dcb4117ad3c8697aa1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,7 @@ include(LofarGeneral)
 ## ---------------------------------------------------------------------------
 include(LofarPackage)
 if(NOT DEFINED BUILD_PACKAGES)
+  lofar_add_package(Docker)
   lofar_add_package(LCS)
   lofar_add_package(CEP)
   lofar_add_package(RTCP)
diff --git a/Docker/CMakeLists.txt b/Docker/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..060eea1d0c446ffeb5ac0433df0432c95964c845
--- /dev/null
+++ b/Docker/CMakeLists.txt
@@ -0,0 +1,65 @@
+# $Id$
+
+lofar_package(Docker 1.0 DEPENDS Common)
+
+include(LofarPackageVersion)
+
+# Build version info
+set(docker_LIB_SRCS
+  Package__Version.cc
+)
+
+lofar_add_library(docker ${docker_LIB_SRCS})
+
+lofar_add_bin_program(versiondocker versiondocker.cc)
+
+#
+# For given directories, we generate the Dockerfile
+# by parsing their Dockerfile.tmpl through "docker-template".
+#
+# "docker-template" is a script that fills in variables with
+# respect to the build info (branch name, build time, etc)
+#
+
+# Directories with Dockerfile.tmpl to parse
+set(DOCKER_TEMPLATE_DIRS
+  lofar-base
+  lofar-pipeline
+  lofar-outputproc)
+
+# Note: "docker-template" only works as long as the sources are still around,
+# since it uses svn to query information from them.
+lofar_add_bin_scripts(docker-template)
+lofar_add_sbin_scripts(docker-build-all.sh)
+
+# Convert Dockerfile.tmpl -> Dockerfile in ${DOCKER_TEMPLATE_DIRS}
+foreach(_dir ${DOCKER_TEMPLATE_DIRS})
+  # _src -> _dst
+  set(_src ${CMAKE_CURRENT_SOURCE_DIR}/${_dir}/Dockerfile.tmpl)
+  set(_dst ${CMAKE_CURRENT_BINARY_DIR}/${_dir}_Dockerfile)
+
+  # add generating command, and (any) target to force the generation
+  # when "all" is build.
+  add_custom_command(
+    OUTPUT ${_dst}
+    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/docker-template < ${_src} > ${_dst}
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docker-template ${_src} ${CMAKE_CURRENT_BINARY_DIR}/versiondocker
+  )
+  add_custom_target(${_dir}_Dockerfile_target ALL DEPENDS ${_dst})
+
+  # install resulting Dockerfile
+  install(FILES
+    ${_dst}
+    DESTINATION share/docker/${_dir}
+    RENAME Dockerfile
+  )
+endforeach()
+
+# Install everything else
+install(DIRECTORY
+  lofar-base
+  lofar-pipeline
+  lofar-outputproc
+  DESTINATION share/docker
+  USE_SOURCE_PERMISSIONS
+  PATTERN Dockerfile.tmpl EXCLUDE)
diff --git a/Docker/docker-build-all.sh b/Docker/docker-build-all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..71eb409a42c9e125646f6f19af6d99e96c176c21
--- /dev/null
+++ b/Docker/docker-build-all.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+TAG=`echo '${LOFAR_TAG}' | docker-template`
+
+function build {
+  IMAGE=$1
+  docker build -t ${IMAGE}:${TAG} ${IMAGE}
+}
+
+cd ${LOFARROOT}/share/docker
+
+build lofar-base && \
+build lofar-pipeline && \
+build lofar-outputproc
+
diff --git a/Docker/docker-template b/Docker/docker-template
new file mode 100755
index 0000000000000000000000000000000000000000..8cac4023c1e08281bdd89b8e23629812c5b084b6
--- /dev/null
+++ b/Docker/docker-template
@@ -0,0 +1,61 @@
+#!/bin/bash 
+#
+# Template engine for LOFAR
+#
+#   Reads stdin, replaces variables, writes stdout.
+#
+#   Variables replaced:
+#       ${LOFAR_BRANCH_NAME}  = Name of this branch, relative to root
+#       ${LOFAR_BRANCH_URL}   = Full subversion URL for this branch
+#       ${LOFAR_TAG}          = Tag for a Docker image
+#       ${LOFAR_REVISION}     = SVN revision number of this checkout (or HEAD if trunk)
+#       ${NOW}          = now in UTC (format: 2016-01-01 10:11:12)
+#       ${BUILD_UID}    = uid of building user (=caller)
+#
+
+# ----- LOFAR_BRANCH_NAME = branches/LOFAR-Task1234 -----
+# ----- LOFAR_BRANCH_NAME = trunk -----
+# ----- LOFAR_BRANCH_NAME = tags/LOFAR-Release-2_15_1 -----
+# ----- LOFAR_BRANCH_NAME = UNKNOWN -----
+
+# Make sure we obtain info about the project source!
+#PATH=$PATH:.
+VERSION_INFO=`(versiondocker || ./versiondocker) 2>/dev/null` # in cmake, executable is in .
+
+# Extract branch name w.r.t. repository root, e.g. branches/LOFAR-Task1234
+export LOFAR_BRANCH_NAME=`echo "$VERSION_INFO" | perl -ne 'print "$1" if /branch += +(.+)/;'`
+
+# ----- LOFAR_BRANCH_URL = https://svn.astron.nl/LOFAR/branches/LOFAR-Task1234 -----
+# ----- LOFAR_BRANCH_URL = https://svn.astron.nl/LOFAR/trunk -----
+# ----- LOFAR_BRANCH_URL = https://svn.astron.nl/LOFAR/tags/LOFAR-Release-2_15_1 -----
+
+export LOFAR_BRANCH_URL="https://svn.astron.nl/LOFAR/${LOFAR_BRANCH_NAME}"
+
+# ----- LOFAR_TAG = 1234 -----
+# ----- LOFAR_TAG = trunk -----
+# ----- LOFAR_TAG = 2_15_1 -----
+
+case "${LOFAR_BRANCH_NAME}" in
+  trunk)      export LOFAR_TAG=trunk ;;
+  tags/*)     export LOFAR_TAG=${LOFAR_BRANCH_NAME##tags/LOFAR-Release-} ;;
+  branches/*) export LOFAR_TAG=${LOFAR_BRANCH_NAME##branches/LOFAR*Task} ;;
+  *)          export LOFAR_TAG=latest ;;
+esac
+
+# ----- LOFAR_REVISION = 12345 -----
+
+export LOFAR_REVISION=`echo "$VERSION_INFO" | perl -ne 'print "$1" if /overall revision += +([0-9]+)/;'`
+
+# ----- NOW = 2016-01-01 10:11:12 -----
+
+export NOW="`date -u +'%F %T'`"
+
+# ----- BUILD_UID = 1001 ----
+
+export BUILD_UID=`id -u`
+
+# ----- Process input -----
+
+# Insert our knowledge when processing stdin -> stdout
+envsubst '$LOFAR_BRANCH_NAME $LOFAR_BRANCH_URL $LOFAR_TAG $LOFAR_REVISION $NOW $BUILD_UID'
+
diff --git a/Docker/lofar-base/Dockerfile.tmpl b/Docker/lofar-base/Dockerfile.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..42d5fb3913e4db10f7c6e6aa521e0c56947f1985
--- /dev/null
+++ b/Docker/lofar-base/Dockerfile.tmpl
@@ -0,0 +1,167 @@
+#
+# base
+#
+FROM ubuntu:14.04
+
+#
+# common-environment
+#
+ENV USER=lofar
+ENV INSTALLDIR=/opt
+
+#
+# environment
+#
+ENV DEBIAN_FRONTEND=noninteractive \
+    PYTHON_VERSION=2.7
+
+#
+# versions
+#
+ENV CASACORE_VERSION=2.0.3 \
+    CASAREST_VERSION=1.4.1 \
+    PYTHON_CASACORE_VERSION=2.0.1 \
+    BOOST_VERSION=1.54
+
+#
+# set-uid
+#
+ENV UID=${BUILD_UID}
+
+#
+# set-build-options
+#
+ENV J=4
+
+#
+# Base and runtime dependencies
+#
+#RUN sed -i 's/archive.ubuntu.com/osmirror.rug.nl/' /etc/apt/sources.list 
+RUN apt-get update && apt-get upgrade -y
+RUN apt-get install -y sudo python2.7 libpython2.7 && \
+    apt-get install -y libblas3 liblapacke python-numpy libcfitsio3 libwcs4 libfftw3-bin libhdf5-7 libboost-python${BOOST_VERSION}.0
+
+#
+# setup-account
+#
+RUN (getent group sudo &>/dev/null || groupadd sudo) && \
+    echo "useradd -m ${USERADD_FLAGS} ${USER}" && \
+    useradd -m -u ${UID} ${USER} && \
+    usermod -a -G sudo ${USER} && \
+    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
+    sed -i 's/requiretty/!requiretty/g' /etc/sudoers
+
+#
+# setup install dir
+#
+RUN mkdir -p ${INSTALLDIR} && chown ${USER}.${USER} ${INSTALLDIR}
+
+USER ${USER}
+
+#
+# *******************
+#   Casacore
+# *******************
+#
+RUN sudo apt-get install -y wget git cmake g++ gfortran flex bison libblas-dev liblapacke-dev libfftw3-dev libhdf5-dev libboost-python-dev libcfitsio3-dev wcslib-dev && \
+    mkdir -p ${INSTALLDIR}/casacore/build && \
+    mkdir -p ${INSTALLDIR}/casacore/data && \
+    cd ${INSTALLDIR}/casacore && git clone https://github.com/casacore/casacore.git src && \
+    if [ "${CASACORE_VERSION}" != "latest" ]; then cd ${INSTALLDIR}/casacore/src && git checkout tags/v${CASACORE_VERSION}; fi && \
+    cd ${INSTALLDIR}/casacore/data && wget --retry-connrefused ftp://ftp.astron.nl/outgoing/Measures/WSRT_Measures.ztar && \
+    cd ${INSTALLDIR}/casacore/data && tar xf WSRT_Measures.ztar  && rm -f WSRT_Measures.ztar && \
+    cd ${INSTALLDIR}/casacore/build && cmake -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/casacore/ -DDATA_DIR=${INSTALLDIR}/casacore/data -DBUILD_PYTHON=True -DUSE_OPENMP=True -DUSE_FFTW3=TRUE ../src/ && \
+    cd ${INSTALLDIR}/casacore/build && make -j ${J} && \
+    cd ${INSTALLDIR}/casacore/build && make install && \
+    bash -c "strip ${INSTALLDIR}/casacore/{lib,bin}/* || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/casacore/{build,src}" && \
+    sudo apt-get purge -y wget git cmake g++ gfortran flex bison libblas-dev liblapacke-dev libfftw3-dev libhdf5-dev libboost-python-dev libcfitsio3-dev wcslib-dev && \
+    sudo apt-get autoremove -y
+
+#
+# *******************
+#   Casarest
+# *******************
+#
+RUN sudo apt-get install -y git cmake g++ gfortran libboost-system-dev libboost-thread-dev libhdf5-dev libcfitsio3-dev wcslib-dev && \
+    mkdir -p ${INSTALLDIR}/casarest/build && \
+    cd ${INSTALLDIR}/casarest && git clone https://github.com/casacore/casarest.git src && \
+    if [ "${CASAREST_VERSION}" != "latest" ]; then cd ${INSTALLDIR}/casarest/src && git checkout tags/v${CASAREST_VERSION}; fi && \
+    cd ${INSTALLDIR}/casarest/build && cmake -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/casarest -DCASACORE_ROOT_DIR=${INSTALLDIR}/casacore ../src/ && \
+    cd ${INSTALLDIR}/casarest/build && make -j ${J} && \
+    cd ${INSTALLDIR}/casarest/build && make install && \
+    bash -c "strip ${INSTALLDIR}/casarest/{lib,bin}/* || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/casarest/{build,src}" && \
+    sudo apt-get purge -y git cmake g++ gfortran libboost-system-dev libboost-thread-dev libhdf5-dev libcfitsio3-dev wcslib-dev && \
+    sudo apt-get autoremove -y
+
+#
+# *******************
+#   Pyrap
+# *******************
+#
+RUN sudo apt-get install -y git make g++ python-setuptools libboost-python-dev libcfitsio3-dev wcslib-dev && \
+    mkdir ${INSTALLDIR}/python-casacore && \
+    cd ${INSTALLDIR}/python-casacore && git clone https://github.com/casacore/python-casacore && \
+    if [ "$PYTHON_CASACORE_VERSION" != "latest" ]; then cd ${INSTALLDIR}/python-casacore/python-casacore && git checkout tags/v${PYTHON_CASACORE_VERSION}; fi && \
+    cd ${INSTALLDIR}/python-casacore/python-casacore && ./setup.py build_ext -I${INSTALLDIR}/casacore/include/ -L${INSTALLDIR}/casacore/lib/ && \
+    mkdir -p ${INSTALLDIR}/python-casacore/lib/python${PYTHON_VERSION}/site-packages/ && \
+    mkdir -p ${INSTALLDIR}/python-casacore/lib64/python${PYTHON_VERSION}/site-packages/ && \
+    export PYTHONPATH=${INSTALLDIR}/python-casacore/lib/python${PYTHON_VERSION}/site-packages:${INSTALLDIR}/python-casacore/lib64/python${PYTHON_VERSION}/site-packages:$PYTHONPATH && cd ${INSTALLDIR}/python-casacore/python-casacore && ./setup.py install --prefix=${INSTALLDIR}/python-casacore/ && \
+    bash -c "find ${INSTALLDIR}/python-casacore/lib -name '*.so' | xargs strip || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/python-casacore/python-casacore" && \
+    sudo apt-get purge -y git make g++ python-setuptools libboost-python-dev libcfitsio3-dev wcslib-dev && \
+    sudo apt-get autoremove -y
+
+#
+# *******************
+#   QPID client
+# *******************
+#
+
+# Allow auto-checkout from lofar repo
+RUN mkdir /home/${USER}/.subversion
+COPY subversion_servers /home/${USER}/.subversion/servers
+
+# Run-time dependencies
+# QPID daemon legacy store would require: libaio1 libdb5.1++
+RUN sudo apt-get install -y sasl2-bin libuuid1 libnss3 libnspr4 xqilla libboost-program-options${BOOST_VERSION}.0 libboost-filesystem${BOOST_VERSION}.0
+
+# Install
+# QPID daemon legacy store would require: libaio-dev libdb5.1++-dev
+RUN sudo apt-get install -y subversion swig ruby ruby-dev python-dev libsasl2-dev pkg-config cmake libtool uuid-dev libxerces-c-dev libnss3-dev libnspr4-dev help2man fakeroot build-essential debhelper libsslcommon2-dev libxqilla-dev python-setuptools libboost-program-options${BOOST_VERSION}-dev libboost-filesystem${BOOST_VERSION}-dev && \
+    mkdir /opt/qpid && \
+    svn --non-interactive -q --username lofar-guest --password lofar-guest co ${LOFAR_BRANCH_URL}/LCS/MessageBus/qpid/ /opt/qpid; \
+    /opt/qpid/local/sbin/build_qpid && \
+    bash -c "strip /opt/qpid/{bin,lib}/* || true" && \
+    bash -c "rm -rf ~/sources" && \
+    sudo apt-get purge -y subversion swig ruby ruby-dev python-dev libsasl2-dev pkg-config cmake libtool uuid-dev libxerces-c-dev libnss3-dev libnspr4-dev help2man fakeroot build-essential debhelper libsslcommon2-dev libxqilla-dev python-setuptools libboost-program-options${BOOST_VERSION}-dev libboost-filesystem${BOOST_VERSION}-dev && \
+    sudo apt-get autoremove -y
+#
+# *******************
+#   DAL
+# *******************
+#
+RUN sudo apt-get install -y git cmake g++ swig python-dev libhdf5-dev && \
+    mkdir ${INSTALLDIR}/DAL && \
+    cd ${INSTALLDIR}/DAL && git clone https://github.com/nextgen-astrodata/DAL.git src && \
+    mkdir ${INSTALLDIR}/DAL/build && cd ${INSTALLDIR}/DAL/build && cmake -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/DAL ../src && \
+    make -j ${J} && \
+    make install && \
+    bash -c "find ${INSTALLDIR}/DAL/lib -name '*.so' | xargs strip || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/DAL/{src,build}" && \
+    sudo apt-get purge -y git cmake g++ swig python-dev libhdf5-dev && \
+    sudo apt-get autoremove -y
+
+#
+# config
+#
+COPY bashrc /home/${USER}/.bashrc
+
+#
+# entry
+#
+COPY chuser.sh /usr/local/bin/chuser.sh
+WORKDIR /home/${USER}
+ENTRYPOINT ["sudo","-E","/usr/local/bin/chuser.sh"]
+
diff --git a/Docker/lofar-base/bashrc b/Docker/lofar-base/bashrc
new file mode 100644
index 0000000000000000000000000000000000000000..74dbbeef1254fd1c50e3454a8b19b441379788d1
--- /dev/null
+++ b/Docker/lofar-base/bashrc
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# lofar
+[ -r ${INSTALLDIR}/lofar/lofarinit.sh ] && source ${INSTALLDIR}/lofar/lofarinit.sh
+
+# qpid
+source ${INSTALLDIR}/qpid/.profile
+
+# python-casacore
+export PYTHONPATH=${PYTHONPATH}:${INSTALLDIR}/python-casacore/lib/python2.7/site-packages
+
+# casacore
+export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${INSTALLDIR}/casacore/lib
diff --git a/Docker/lofar-base/chuser.sh b/Docker/lofar-base/chuser.sh
new file mode 100755
index 0000000000000000000000000000000000000000..294e58c7d30e9288aa263d632c738a8ab06c0b98
--- /dev/null
+++ b/Docker/lofar-base/chuser.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# Fetch the user name used in this container
+export USER=${SUDO_USER}
+
+if [ -n "${LUSER}" ]; then
+  if [ -z "${LGROUP}" ]; then
+    LGROUP=${LUSER}
+  fi
+
+  OLDID=`id -u ${USER}`
+
+  # Replace USER by LUSER:LGROUP
+  sed -i -e "s/${USER}:x:[0-9]\+:[0-9]\+/${USER}:x:${LUSER}:${LGROUP}/g" /etc/passwd
+  sed -i -e "s/${USER}:x:[0-9]\+:/${USER}:x:${LGROUP}:/g" /etc/group
+
+  # Set ownership of home dir to new user
+  chown --from=${OLDID} -R ${LUSER}:${LGROUP} ${HOME}
+fi
+
+# Switch to the updated user
+export HOME=/home/${USER}
+touch -a $HOME/.bashrc
+sudo -u ${USER} -E -s /bin/bash -c "source $HOME/.bashrc;$*"
diff --git a/Docker/lofar-base/subversion_servers b/Docker/lofar-base/subversion_servers
new file mode 100644
index 0000000000000000000000000000000000000000..986b312078ec2bdd8474d33f6dce788756d3f609
--- /dev/null
+++ b/Docker/lofar-base/subversion_servers
@@ -0,0 +1,6 @@
+[groups]
+astron = svn.astron.nl
+
+[astron]
+store-passwords = yes
+store-plaintext-passwords = yes
diff --git a/Docker/lofar-outputproc/Dockerfile.tmpl b/Docker/lofar-outputproc/Dockerfile.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..85474bfcb585b82dc4018a994dfb2322d63263ed
--- /dev/null
+++ b/Docker/lofar-outputproc/Dockerfile.tmpl
@@ -0,0 +1,33 @@
+#
+# base
+#
+FROM lofar-base:${LOFAR_TAG}
+
+#
+# *******************
+#   LOFAR
+# *******************
+#
+
+# Run-time dependencies
+RUN sudo apt-get install -y liblog4cplus-1.0-4 libxml2 libboost-thread${BOOST_VERSION}.0 libboost-filesystem${BOOST_VERSION}.0 libboost-date-time${BOOST_VERSION}.0 libpng12-0 libsigc++-2.0-dev libxml++2.6-2 libboost-regex${BOOST_VERSION}.0
+
+# Tell image build information
+ENV LOFAR_BRANCH=${LOFAR_BRANCH_NAME} \
+    LOFAR_REVISION=${LOFAR_REVISION}
+
+# Install
+RUN sudo apt-get install -y subversion cmake g++ gfortran bison flex autogen liblog4cplus-dev libhdf5-dev libblitz0-dev libboost-dev libboost-python${BOOST_VERSION}-dev libxml2-dev pkg-config libpng12-dev libfftw3-dev libunittest++-dev libxml++2.6-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev libboost-regex${BOOST_VERSION} binutils-dev && \
+    mkdir -p ${INSTALLDIR}/lofar/build/gnu_opt libcfitsio3-dev wcslib-dev && \
+    cd ${INSTALLDIR}/lofar && \
+    svn --non-interactive -q --username lofar-guest --password lofar-guest co -r ${LOFAR_REVISION} -N ${LOFAR_BRANCH_URL} src; \
+    svn --non-interactive -q up src/CMake && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && cmake -DBUILD_PACKAGES=Online_OutputProc -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/lofar/ -DCASACORE_ROOT_DIR=${INSTALLDIR}/casacore/ -DLOG4CPLUS_ROOT_DIR=${INSTALLDIR}/log4cplus/ -DQPID_ROOT_DIR=/opt/qpid/ -DDAL_ROOT_DIR=${INSTALLDIR}/DAL -DUSE_OPENMP=True ${INSTALLDIR}/lofar/src/ && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && sed -i '29,31d' include/ApplCommon/PosixTime.h && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && make -j ${J} && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && make install && \
+    bash -c "strip ${INSTALLDIR}/lofar/{bin,sbin,lib64}/* || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/lofar/{build,src}" && \
+    sudo apt-get purge -y subversion cmake g++ gfortran bison flex autogen liblog4cplus-dev libhdf5-dev libblitz0-dev libboost-dev libboost-python${BOOST_VERSION}-dev libxml2-dev pkg-config libpng12-dev libfftw3-dev libunittest++-dev libxml++2.6-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev binutils-dev libcfitsio3-dev wcslib-dev && \
+    sudo apt-get autoremove -y
+
diff --git a/Docker/lofar-pipeline/Dockerfile.tmpl b/Docker/lofar-pipeline/Dockerfile.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..4443b94a15f41ffd3134d6279785e7aa0147983e
--- /dev/null
+++ b/Docker/lofar-pipeline/Dockerfile.tmpl
@@ -0,0 +1,58 @@
+#
+# base
+#
+FROM lofar-base:${LOFAR_TAG}
+
+ENV AOFLAGGER_VERSION=2.7.1
+
+# Run-time dependencies
+RUN sudo apt-get install -y python-xmlrunner python-scipy liblog4cplus-1.0-4 libxml2 libboost-thread${BOOST_VERSION}.0 libboost-filesystem${BOOST_VERSION}.0 libboost-date-time${BOOST_VERSION}.0 libboost-signals${BOOST_VERSION}.0 libpng12-0 libsigc++-2.0-dev libxml++2.6-2 libgsl0ldbl openssh-client libboost-regex${BOOST_VERSION}.0 && \
+    sudo apt-get -y install python-pip python-dev && \
+    sudo pip install pyfits pywcs python-monetdb && \
+    sudo apt-get -y purge python-pip python-dev && \
+    sudo apt-get -y autoremove
+
+#
+# *******************
+#   AOFlagger
+# *******************
+#
+
+RUN sudo apt-get install -y wget cmake g++ libxml++2.6-dev libpng12-dev libfftw3-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-signals${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev libcfitsio3-dev && \
+    mkdir -p ${INSTALLDIR}/aoflagger/build && \
+    bash -c "cd ${INSTALLDIR}/aoflagger && wget --retry-connrefused http://downloads.sourceforge.net/project/aoflagger/aoflagger-${AOFLAGGER_VERSION%%.?}.0/aoflagger-${AOFLAGGER_VERSION}.tar.bz2" && \
+    cd ${INSTALLDIR}/aoflagger && tar xf aoflagger-${AOFLAGGER_VERSION}.tar.bz2 && \
+    cd ${INSTALLDIR}/aoflagger/build && cmake -DCASACORE_ROOT_DIR=${INSTALLDIR}/casacore/ -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/aoflagger ../aoflagger-${AOFLAGGER_VERSION} && \
+    cd ${INSTALLDIR}/aoflagger/build && make -j ${J} && \
+    cd ${INSTALLDIR}/aoflagger/build && make install && \
+    bash -c "strip ${INSTALLDIR}/aoflagger/{lib,bin}/* || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/aoflagger/{build,aoflagger-${AOFLAGGER_VERSION}}" && \
+    bash -c "rm -rf ${INSTALLDIR}/aoflagger/aoflagger-${AOFLAGGER_VERSION}.tar.bz2" && \
+    sudo apt-get -y purge wget cmake g++ libxml++2.6-dev libpng12-dev libfftw3-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-signals${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev libcfitsio3-dev && \
+    sudo apt-get -y autoremove
+
+#
+# *******************
+#   LOFAR
+# *******************
+#
+
+# Tell image build information
+ENV LOFAR_BRANCH=${LOFAR_BRANCH_NAME} \
+    LOFAR_REVISION=${LOFAR_REVISION}
+
+# Install
+RUN sudo apt-get install -y subversion cmake g++ gfortran bison flex liblog4cplus-dev libhdf5-dev libblitz0-dev libboost-dev libboost-python-dev python-dev libxml2-dev pkg-config libpng12-dev libfftw3-dev libunittest++-dev libxml++2.6-dev libgsl0-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev libboost-regex${BOOST_VERSION} binutils-dev libcfitsio3-dev wcslib-dev && \
+    mkdir -p ${INSTALLDIR}/lofar/build/gnu_opt && \
+    cd ${INSTALLDIR}/lofar && \
+    svn --non-interactive -q --username lofar-guest --password lofar-guest co -r ${LOFAR_REVISION} -N ${LOFAR_BRANCH_URL} src; \
+    svn --non-interactive -q up src/CMake && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && cmake -DBUILD_PACKAGES=Offline -DCMAKE_INSTALL_PREFIX=${INSTALLDIR}/lofar/ -DCASAREST_ROOT_DIR=${INSTALLDIR}/casarest/ -DCASACORE_ROOT_DIR=${INSTALLDIR}/casacore/ -DAOFLAGGER_ROOT_DIR=${INSTALLDIR}/aoflagger/ -DLOG4CPLUS_ROOT_DIR=${INSTALLDIR}/log4cplus/ -DQPID_ROOT_DIR=/opt/qpid/ -DUSE_OPENMP=True ${INSTALLDIR}/lofar/src/ && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && sed -i '29,31d' include/ApplCommon/PosixTime.h && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && make -j ${J} && \
+    cd ${INSTALLDIR}/lofar/build/gnu_opt && make install && \
+    bash -c "strip ${INSTALLDIR}/lofar/{bin,sbin,lib64}/* || true" && \
+    bash -c "rm -rf ${INSTALLDIR}/lofar/{build,src}" && \
+    sudo apt-get purge -y subversion cmake g++ gfortran bison flex liblog4cplus-dev libhdf5-dev libblitz0-dev libboost-dev libboost-python-dev python-dev libxml2-dev pkg-config libpng12-dev libfftw3-dev libunittest++-dev libxml++2.6-dev libgsl0-dev libboost-filesystem${BOOST_VERSION}-dev libboost-date-time${BOOST_VERSION}-dev libboost-thread${BOOST_VERSION}-dev binutils-dev wcslib-dev && \
+    sudo apt-get autoremove -y
+
diff --git a/LCS/Common/include/Common/Version.h b/LCS/Common/include/Common/Version.h
index 3e9697c0c402d1f67411dbee067ff166c5edbf2b..3cd389e1ec4677505d62b882abd34c606a03813d 100644
--- a/LCS/Common/include/Common/Version.h
+++ b/LCS/Common/include/Common/Version.h
@@ -63,6 +63,7 @@ namespace LOFAR {
 
     // Construct a Version object from the relevant package info.
     Version (const std::string& packageName,
+	     const std::string& branch,
 	     const std::string& version,
 	     const std::string& confVersion,
 	     const std::string& revision,
@@ -75,6 +76,9 @@ namespace LOFAR {
     // Get the package name.
     const std::string& packageName() const
       { return itsPackageName; }
+    // Get the LOFAR branch version (relative to repository root)
+    const std::string& branch() const
+      { return itsBranch; }
     // Get the package version (as in repository)
     const std::string& version() const
       { return itsVersion; }
@@ -195,6 +199,7 @@ namespace LOFAR {
 
     //# Data members.
     std::string itsPackageName;
+    std::string itsBranch;
     std::string itsVersion;
     std::string itsConfVersion;
     std::string itsRevision;
diff --git a/LCS/Common/src/Version.cc b/LCS/Common/src/Version.cc
index fd9dd09dc1995236f2df3c9668fcbab1abe10e37..a64c78bf84f081d6beb26800f9cf066bccddab82 100644
--- a/LCS/Common/src/Version.cc
+++ b/LCS/Common/src/Version.cc
@@ -29,6 +29,7 @@
 namespace LOFAR {
 
   Version::Version (const std::string& packageName,
+		    const std::string& branch,
 		    const std::string& version,
 		    const std::string& confVersion,
 		    const std::string& revision,
@@ -38,6 +39,7 @@ namespace LOFAR {
 		    const std::string& buildUser,
 		    const std::string& buildMachine)
     : itsPackageName     (packageName),
+      itsBranch          (branch),
       itsVersion         (version),
       itsConfVersion     (confVersion),
       itsRevision        (revision),
@@ -129,6 +131,7 @@ namespace LOFAR {
       os << " (in CMakeLists.txt: " << confVersion() << ')';
     }
     os << std::endl;
+    os << indent << " branch = " << branch() << std::endl;
     os << indent << " overall revision  = " << revision();
     if (!sameRev) os << " (note: used packages have different revision)";
     os << std::endl;
diff --git a/MAC/Navigator2/panels/Test/test.pnl b/MAC/Navigator2/panels/Test/test.pnl
index 3e671f0fd0fb7e48fb280543de59fd201beccab6..c6942e2382e422309a050144de85e3d30d75a467 100644
--- a/MAC/Navigator2/panels/Test/test.pnl
+++ b/MAC/Navigator2/panels/Test/test.pnl
@@ -5,8 +5,52 @@ LANG:6 0
 PANEL,-1 -1 838 396 N "_3DFace" 0
 "main()
 {
-  dyn_string aS = makeDynString(\"A\",\"B\",\"kjbdkbdsk\",\"TempObs0123\",\"kjbndkbna\");
-  DebugN(dynPatternMatch(\"TempObs*\", aS));
+  dyn_string statedps;
+  string observation = \"402147\";
+  
+  string CEPDBNAME = \"CCU001\";
+  string connectToStates = \"SELECT '_online.._value' FROM '{LOFAR**CobaltGPUProc*.status.state,LOFAR**CobaltGPUProc*.status.childState,LOFAR**CobaltStationInput.status.state,LOFAR**CobaltStationInput.status.childState}' REMOTE '\"+CEPDBNAME+\"' WHERE 'observationName:_online.._value' == '\"+observation+\"'\";
+
+  dyn_dyn_anytype aResult;
+  dpQuery(connectToStates,aResult);
+    
+//  DebugN(\"result: \", aResult);
+
+  // Iterate through the results and collect the state and childState dps
+  dyn_string stateDPs;
+  for( int t = 2; t <= dynlen( aResult ); t++)
+  {
+    // skip the lines that contain the observationNames
+    string line = aResult[t][1];
+    if (strpos(line,\"observationName\") >= 0) continue;
+    if (!dynContains(stateDPs, line) && dynlen(stateDPs) < 99) dynAppend(stateDPs,line);
+  }
+    
+  
+  // append the main hardware state
+  dynAppend(stateDPs,CEPDBName+\"LOFAR_PIC_Cobalt.status.state\");
+  dynAppend(stateDPs,CEPDBName+\"LOFAR_PIC_Cobalt.status.childState\");
+    
+  DebugN(\"connectCobaltNodesAndProcesses nr stateDPS to connect:\", dynlen(stateDPs));
+
+  dpConnect(\"CB\",TRUE,stateDPs);
+      
+  dyn_errClass err = getLastError(); //test whether an error occurred 
+  if(dynlen(err) > 0) { 
+    errorDialog(err); 
+    // open dialog box with errors 
+    throwError(err); // write errors to stderr 
+  
+      LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:connectCobaltNodesAndProcesses| ERROR: connect fails:\"+ stateDPs);
+  } else {
+    DebugN(\" No error\");
+  }
+}
+
+void CB(dyn_string dpList,  dyn_int stateList) 
+{
+  DebugN(\"CB| has \" + dynlen( dpList) + \" results\" );
+  DebugN(dpList);
 }" 0
  E E E E 1 -1 -1 0  50 30
 ""0  1
diff --git a/MAC/Navigator2/panels/main.pnl b/MAC/Navigator2/panels/main.pnl
index d7d791b53d870dd3ffcc3b1232853df269eac743..1d60ce83cb8aacca4fa20a161f65d7cc29b8e5c7 100644
--- a/MAC/Navigator2/panels/main.pnl
+++ b/MAC/Navigator2/panels/main.pnl
@@ -59,6 +59,7 @@ dyn_string stationList;
 dyn_string observationsList;
 dyn_string backLinesRefNames;
 dyn_string observationRefNames;
+string observationFlowRefName = \"MainObservationFlowRefName1\";
 
 string strPanelName;
 string strModuleName;
@@ -84,6 +85,7 @@ void clearObservationRefNames() {
   for (int i=1; i <= dynlen(observationRefNames); i++) {
     removeSymbol(strModuleName,\"\",observationRefNames[i]);
   }
+  removeSymbol(strModuleName,\"\",observationFlowRefName);
   dynClear(observationRefNames);
 }
 
@@ -91,9 +93,19 @@ void redrawObservations() {
   if (dynlen(observationRefNames) > 0) {
     clearObservationRefNames();
   }
+  dynClear(observationsList);
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
 
   addObservations();
-
+  addObservationFlow();
+  
   // trigger that the panel values are calculated and ready
   dynClear(highlight);
   dynClear(strHighlight);
@@ -220,10 +232,10 @@ void addObservations() {
   int yPos_AddSymbol = 685; 
   int ref = 1;
   string addPanelName    = \"objects/Observations/observation_smallCEPView.pnl\";
-  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",observationsList);
+
   //loop over list and prepare panel with all stations and swlevel objects   
   for (int i=1; i<= dynlen(observationsList); i++) {
-    if (!navFunct_isObservation(observationsList[i])) continue;
+
     observationRefNames[ref]=\"stationObs\"+(ref);
     if (  addSymbol(  strModuleName,                   // Stay in this modul
                       \"\",                              // Name of this panel
@@ -242,6 +254,23 @@ void addObservations() {
   }
 }
 
+void addObservationFlow() {
+  int xPos_AddSymbol = 0; 
+  int yPos_AddSymbol = 756; 
+  string addPanelName    = \"Observations/MainObservationFlow.pnl\";
+  if (  addSymbol(  strModuleName,                   // Stay in this modul
+                    \"\",                              // Name of this panel
+                    addPanelName,                    // Panel to add
+                    observationFlowRefName,          // Ref of the addedPanel
+                    makeDynString() , // Define all $values
+                    xPos_AddSymbol,                  // Xpos of the AddedSymbol
+                    yPos_AddSymbol,                  // Ypos of the AddedSymbol
+                    0,                               // angle
+                    1    ,1                          // zoomX , zoomY
+      ) < 0 ) {
+    LOG_ERROR(\"swlevel.pnl:addObservationFlow|Error Appending observationFlow panel.\");
+  }
+}
 " 0
  2
 "CBRef" "1"
@@ -726,32 +755,6 @@ E E 0 1 1 2 1 E U  0 E 950 10 997 23
 LANG:1 34 MS Shell Dlg 2,8,-1,5,75,0,0,0,0,0
 0 1
 LANG:1 7 streams
-1 173 0 "" 1
-0
-1 174 0 "" 2
-0
-1 175 1 "" 1
-0
-1 176 1 "" 2
-0
-4 127
-"LINE5"
-""
-1 130 786 E E E 1 E 1 E N {0,0,0} E N {255,255,255} E E
- E E
-61 0 0 0 0 0
-E E E
-0
-1
-LANG:1 0 
-
-1
-"dashclr"N "_Transparent"
-E E 0 2 1 2 1 E  130 786 160 786
-1 177 3 "" 1
-0
-1 178 3 "" 2
-0
 2 172
 "PRIMITIVE_TEXT40"
 ""
@@ -771,28 +774,6 @@ E E 0 1 1 2 1 E U  0 E 790 10 823 23
 LANG:1 34 MS Shell Dlg 2,8,-1,5,75,0,0,0,0,0
 0 1
 LANG:1 5 AardF
-1 179 4 "" 0
-0
-1 180 4 "" 1
-0
-1 181 4 "" 2
-0
-1 182 4 "" 3
-0
-1 183 4 "" 4
-0
-1 184 5 "" 0
-0
-1 185 5 "" 1
-0
-1 186 6 "" 1
-0
-1 187 6 "" 2
-0
-1 188 7 "" 0
-0
-1 189 7 "" 1
-0
 0
 LAYER, 1 
 1
@@ -864,25 +845,4 @@ LAYER, 7
 1
 LANG:1 0 
 0
-3 0 "PANEL_REF0" -1
-"objects\\Observations\\observationFlow.pnl" 110 740 T 60 1 0 1 -49.99999999999997 79.99999999999989
-0
-3 1 "PANEL_REF1" -1
-"objects\\Hardware\\observationFlow_stations.pnl" 220 810 T 60 1 0 1 0 10
-0
-3 3 "PANEL_REF3" -1
-"objects\\Processes\\observationFlow_cobaltLocusNodeProcesses.pnl" 500 810 T 64 1 0 1 0 10
-0
-3 4 "PANEL_REF4" -1
-"objects\\Processes\\observationFlow_cobaltInputStreams.pnl" 280 750 T 66 1 0 1 0 10
-0
-3 5 "PANEL_REF5" -1
-"objects\\Processes\\observationFlow_cobaltGPUProcs.pnl" 430 750 T 66 1 0 1 0 5
-0
-3 6 "PANEL_REF6" -1
-"objects\\Processes\\observationFlow_cobaltNodeProcesses.pnl" 340 810 T 66 1 0 1 0 10
-0
-3 7 "PANEL_REF7" -1
-"objects\\Processes\\observationFlow_cobaltOutputProc.pnl" 590 750 T 66 1 0 1 0 14
-0
 0
diff --git a/MAC/Navigator2/panels/objects/Processes/GPUProcSubbandInfo.pnl b/MAC/Navigator2/panels/objects/Processes/GPUProcSubbandInfo.pnl
index 5fc49e3bcdc206d7e1500a87d67bbe298d910597..8b4f08034342797ae93b6ea1e2ec49ddf1ae8e58 100644
--- a/MAC/Navigator2/panels/objects/Processes/GPUProcSubbandInfo.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/GPUProcSubbandInfo.pnl
@@ -16,6 +16,7 @@ PANEL,-1 -1 114 79 N "_3DFace" 5
     subbandInfo.backCol(\"Lofar_invalid\");
     subbandInfo.toolTipText = \"\";
   } else {
+    if (written + dropped <= 0) return;
     // calc % dropped
     float percdropped = dropped / (written + dropped) * 100;
     subbandInfo.backCol(getColor(percdropped));
diff --git a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltGPUProcs.pnl b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltGPUProcs.pnl
index af27d587e6ea96f76b734e969e5c418a32f9fac4..c6903f50fc9aa22d1fe82c89ad764f48c5e871aa 100644
--- a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltGPUProcs.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltGPUProcs.pnl
@@ -7,18 +7,49 @@ PANEL,-1 -1 177 78 N "_3DFace" 0
   baseDP = \"LOFAR_PermSW\";
   database=dpSubStr(baseDP,DPSUB_SYS);
   
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
+  
   activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";  
-  // check if MACScheduler pointenabled and accessible
-  if (dpExists(activeObsDP)) {
-    if (dpConnect(\"updateActiveObservations\", activeObsDP+\":_online.._value\",
-                                             activeObsDP+\":_online.._invalid\") == -1) {
-      LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:main|Couldn't connect to: \"+activeObsDP);
+  
+  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
+  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
+  
+  LOG_DEBUG(\"ObservationFlow_cobaltGPUProcs.pnl:main|observationList: \"+observationsList);
+
+  dyn_string obsConnections = makeDynString();  
+  for (int i = 1; i <= dynlen(observationsList) ; i++) {
+    // compose the WinCC OA DP name 
+    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
+
+    // Ask the claimmanager for the temp obs representation
+    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
+
+    // add DP to list with all connects
+    if (! dynContains(obsConnections,obsDP+\".runState\")) dynAppend(obsConnections,obsDP+\".runState\");
+  }
+  
+  if (dynlen(oldObsConnections) > 0) {
+    // disconnect old observations
+    if (dpDisconnect(\"monitorRunStates\",oldObsConnections) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltGPUProcs.pnl:main\", getLastError());
     }
-  } else {
-    if (!isStandalone()) LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:main|Couldn't find DP to connect to: \"+activeObsDP);
+    dynClear(oldObsConnections);
   }
   
-  	
+  // connect to runState for all active observations  
+  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
+    LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:main|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
+  } else if (dynlen(obsConnections) > 0) {
+    oldObsConnections = obsConnections;
+  }  else {
+    setValue(\"GPUProcsObject\", \"foreCol\", \"Lofar_off\");
+  }       	
 }" 0
  E "main(int x, int y)
 {
@@ -82,65 +113,6 @@ void rClick() {
   }
 }
 
-void updateActiveObservations(string dp1, dyn_string obs,
-                              string dp2, bool invalid)
-{
-
-  // remove pipelines from the list
-  for (int i=dynlen(obs);i > 0;  i--) if (!navFunct_isObservation(obs[i])) dynRemove(obs,i);
-  
-  activeObservations = obs;
-  // if there are selected observation check the observationsList if those selected observations still are active
-  // remove the unactive observations from the list  
-  
-  // replace old observations if there are no observations selected
-  if (selectedObservations) {
-    for (int i=dynlen(observationsList); i < 1; i--) {
-      int idx = dynContains(activeObservations,observationsList[i]);
-      if (i <= 0) dynRemove(observationsList,i);
-    }
-    if (dynlen(observationsList) ==0) {
-      selectedObservations=false;
-    }
-  }
-  
-  if (!selectedObservations) {
-    observationsList = activeObservations;
-  }
-  
-  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
-  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
-  
-  LOG_DEBUG(\"ObservationFlow_cobaltGPUProcs.pnl:updateActiveObservations|observationList: \"+observationsList);
-
-  dyn_string obsConnections = makeDynString();  
-  for (int i = 1; i <= dynlen(observationsList) ; i++) {
-    // compose the WinCC OA DP name 
-    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
-
-    // Ask the claimmanager for the temp obs representation
-    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
-
-    // add DP to list with all connects
-    if (! dynContains(obsConnections,obsDP+\".runState\" )) dynAppend(obsConnections,obsDP+\".runState\");
-  }
-  
-  if (dynlen(oldObsConnections) > 0) {
-    // disconnect old observations
-    dpDisconnect(\"monitorRunStates\",oldObsConnections);
-    dynClear(oldObsConnections);
-  }
-  
-  // connect to runState for all active observations  
-  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
-    LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:updateActiveObservations|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
-  } else if (dynlen(obsConnections) > 0) {
-    oldObsConnections = obsConnections;
-  }  else {
-     setValue(\"GPUProcsObject\", \"foreCol\", \"Lofar_off\");
-  }    
-}
-
 void monitorRunStates(dyn_string dpList,dyn_string runStates) {
   for (int i=1; i<= dynlen(runStates); i++) {
     if (runStates[i] == \"Running\" || runStates[i] == \"Quiting\") {
@@ -156,7 +128,9 @@ void connectGPUProcs(string runState) {
   
   // change all found DP's to contain all the elements that contain the .dropping
   if (connectedGPUProcs) {
-    dpDisconnect(\"gpuprocCB\",oldConnectToGPUProcs);
+    if (dpDisconnect(\"gpuprocCB\",oldConnectToGPUProcs) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltGPUProcs.pnl:connectGPUProcs\", getLastError());
+    }
     dynClear(oldConnectToGPUProcs);
     connectedGPUProcs = false;
   }  
@@ -226,19 +200,19 @@ void gpuprocCB(dyn_string dps, dyn_dyn_anytype values)
       if (i+1 <= dynlen(values)) {
         dropped = values[i+1];
       } else {
-        DebugN(\"error too less data, needed : \"+ i+1 +\" got: \"+dynlen(values));
+        LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:gpuProcCB| error too less data, needed : \"+ i+1 +\" got: \"+dynlen(values));
         error = true;
       }
       if (i+2 <= dynlen(values)){
         subband = values[i+2];
       } else {
-        DebugN(\"error too less data, needed : \"+ i+2 +\" got: \"+dynlen(values));
+        LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:gpuProcCB| error too less data, needed : \"+ i+2 +\" got: \"+dynlen(values));
         error = true;
       }
       if (i+3 <= dynlen(values)) {
         dataProductType = values[i+3];
       } else {
-        DebugN(\"error too less data, needed : \"+ i+3 +\" got: \"+dynlen(values));
+        LOG_ERROR(\"ObservationFlow_cobaltGPUProcs.pnl:gpuProcCB| error too less data, needed : \"+ i+3 +\" got: \"+dynlen(values));
         error = true;
       }
       
diff --git a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltInputStreams.pnl b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltInputStreams.pnl
index 0dc5b23ca9a0cb509265b07aa660b5aa8406fc54..e0a08ed2d6639fef08432901980de391c4422943 100644
--- a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltInputStreams.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltInputStreams.pnl
@@ -7,18 +7,52 @@ PANEL,-1 -1 273 73 N "_3DFace" 0
   baseDP = \"LOFAR_PermSW\";
   database=dpSubStr(baseDP,DPSUB_SYS);
   
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
+  
   activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";  
-  // check if MACScheduler pointenabled and accessible
-  if (dpExists(activeObsDP)) {
-    if (dpConnect(\"updateActiveObservations\", activeObsDP+\":_online.._value\",
-                                             activeObsDP+\":_online.._invalid\") == -1) {
-      LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|Couldn't connect to: \"+activeObsDP);
+  
+  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
+  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
+  
+  LOG_DEBUG(\"ObservationFlow_cobaltInputStreams.pnl:main|observationList: \"+observationsList);
+
+  dyn_string obsConnections = makeDynString();  
+  for (int i = 1; i <= dynlen(observationsList) ; i++) {
+    // compose the WinCC OA DP name 
+    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
+
+    // Ask the claimmanager for the temp obs representation
+    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
+
+    // add DP to list with all connects
+    if (! dynContains(obsConnections,obsDP+\".runState\")) dynAppend(obsConnections,obsDP+\".runState\");
+  }
+  
+  if (dynlen(oldObsConnections) > 0) {
+    // disconnect old observations
+    if (dpDisconnect(\"monitorRunStates\",oldObsConnections) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltInputStreams.pnl:main\", getLastError());
     }
-  } else {
-    if (!isStandalone()) LOG_ERROR(\"ObservationFlow_cobaltInputStreams.pnl:main|Couldn't find DP to connect to: \"+activeObsDP);
+    dynClear(oldObsConnections);
   }
   
-  	
+  // connect to runState for all active observations  
+  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
+    LOG_ERROR(\"ObservationFlow_cobaltInputStreams.pnl:main|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
+  } else if (dynlen(obsConnections) > 0) {
+    oldObsConnections = obsConnections;
+  }  else {
+    setValue(\"streamObject0\", \"foreCol\", \"Lofar_off\");
+    setValue(\"streamObject1\", \"foreCol\", \"Lofar_off\");
+    setValue(\"streamObject2\", \"foreCol\", \"Lofar_off\");
+    setValue(\"streamObject3\", \"foreCol\", \"Lofar_off\");
+  }     
 }" 0
  E "main()
 {
@@ -52,8 +86,6 @@ bool connected1;
 bool connected2;
 bool connected3;
 
-bool selectedObservations=false;
-
 bool bDoubleClicked  = false;
 
 // routine for single mouse click
@@ -88,67 +120,6 @@ void rClick() {
   }
 }
 
-void updateActiveObservations(string dp1, dyn_string obs,
-                              string dp2, bool invalid)
-{
-
-  // remove pipelines from the list
-  for (int i=dynlen(obs);i > 0;  i--) if (!navFunct_isObservation(obs[i])) dynRemove(obs,i);
-  
-  activeObservations = obs;
-  // if there are selected observation check the observationsList if those selected observations still are active
-  // remove the unactive observations from the list  
-  
-  // replace old observations if there are no observations selected
-  if (selectedObservations) {
-    for (int i=dynlen(observationsList); i < 1; i--) {
-      int idx = dynContains(activeObservations,observationsList[i]);
-      if (i <= 0) dynRemove(observationsList,i);
-    }
-    if (dynlen(observationsList) ==0) {
-      selectedObservations=false;
-    }
-  }
-  
-  if (!selectedObservations) {
-    observationsList = activeObservations;
-  }
-  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
-  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
-  
-  LOG_DEBUG(\"ObservationFlow_cobaltInputStreams.pnl:updateActiveObservations|observationList: \"+observationsList);
-
-  dyn_string obsConnections = makeDynString();  
-  for (int i = 1; i <= dynlen(observationsList) ; i++) {
-    // compose the WinCC OA DP name 
-    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
-
-    // Ask the claimmanager for the temp obs representation
-    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
-
-    // add DP to list with all connects
-    if (! dynContains(obsConnections,obsDP+\".runState\")) dynAppend(obsConnections,obsDP+\".runState\");
-  }
-  
-  if (dynlen(oldObsConnections) > 0) {
-    // disconnect old observations
-    dpDisconnect(\"monitorRunStates\",oldObsConnections);
-    dynClear(oldObsConnections);
-  }
-  
-  // connect to runState for all active observations  
-  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
-    LOG_ERROR(\"ObservationFlow_cobaltInputStreams.pnl:updateActiveObservations|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
-  } else if (dynlen(obsConnections) > 0) {
-    oldObsConnections = obsConnections;
-  }  else {
-    setValue(\"streamObject0\", \"foreCol\", \"Lofar_off\");
-    setValue(\"streamObject1\", \"foreCol\", \"Lofar_off\");
-    setValue(\"streamObject2\", \"foreCol\", \"Lofar_off\");
-    setValue(\"streamObject3\", \"foreCol\", \"Lofar_off\");
-  }     
-  
-}
 
 void monitorRunStates(dyn_string dpList,dyn_string runStates) {
   for (int i=1; i<= dynlen(runStates); i++) {
@@ -160,8 +131,6 @@ void monitorRunStates(dyn_string dpList,dyn_string runStates) {
 }
 
 
-
-
 // connect to stationInputStreams from the active observations
 void connectStationInputStreams(string runState) {
   stationInputs = \"\";
@@ -178,22 +147,30 @@ void connectStationInputStreams(string runState) {
   
   // change all found DP's to contain all the elements that contain the stream.percBad
   if (connected0) {
-    dpDisconnect(\"streamCB0\",oldConnectTo0);
+    if (dpDisconnect(\"streamCB0\",oldConnectTo0) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltInputStreams.pnl:connectStationInputStreams\", getLastError());
+    }
     dynClear(oldConnectTo0);
     connected0 = false;
   }
   if (connected1) {
-    dpDisconnect(\"streamCB1\",oldConnectTo1);
+    if (dpDisconnect(\"streamCB1\",oldConnectTo1) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltInputStreams.pnl:connectStationInputStreams\", getLastError());
+    }
     dynClear(oldConnectTo1);
     connected1 = false;
   }
   if (connected2) {
-    dpDisconnect(\"streamCB2\",oldConnectTo2);
+    if (dpDisconnect(\"streamCB2\",oldConnectTo2) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltInputStreams.pnl:connectStationInputStreams\", getLastError());
+    }
     dynClear(oldConnectTo2);
     connected2 = false;
   }
   if (connected3) {
-    dpDisconnect(\"streamCB3\",oldConnectTo3);
+    if (dpDisconnect(\"streamCB3\",oldConnectTo3) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltInputStreams.pnl:connectStationInputStreams\", getLastError());
+    }
     dynClear(oldConnectTo3);
     connected3 = false;
   }
diff --git a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltLocusNodeProcesses.pnl b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltLocusNodeProcesses.pnl
index fde18e002505c1a1104240598e519c6e25e5a18e..71fe246a8b6d8998dfb48abd8d8ce747f93c613b 100644
--- a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltLocusNodeProcesses.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltLocusNodeProcesses.pnl
@@ -7,19 +7,51 @@ PANEL,-1 -1 335 88 N "_3DFace" 0
   baseDP = \"LOFAR_PermSW\";
   database=dpSubStr(baseDP,DPSUB_SYS);
 
-  activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";
-  // check if MACScheduler pointenabled and accessible
-  if (dpExists(activeObsDP)) {
-    if (dpConnect(\"updateActiveObservations\", activeObsDP+\":_online.._value\",
-                                              activeObsDP+\":_online.._invalid\") == -1) {
-      LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|Couldn't connect to: \"+activeObsDP);
+  
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
+  
+  activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";  
+
+  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
+  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
+  
+  LOG_DEBUG(\"ObservationFlow_cobaltNodeProcesses.pnl:main|observationList: \"+observationsList);
+
+  dyn_string obsConnections = makeDynString();  
+  for (int i = 1; i <= dynlen(observationsList) ; i++) {
+    // compose the WinCC OA DP name 
+    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
+
+    // Ask the claimmanager for the temp obs representation
+    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
+
+    // add DP to list with all connects
+    dynAppend(obsConnections,obsDP+\".runState\");
+  }
+  
+  if (dynlen(oldObsConnections) > 0) {
+    // disconnect old observations
+    if (dpDisconnect(\"monitorRunStates\",oldObsConnections) < 0 ) {
+      navFunct_printLastError(\"ObservationFlow_cobaltNodeProcesses.pnl:main\", getLastError());
     }
+    dynClear(oldObsConnections);
+  }
+  
+  // connect to runState for all active observations  
+  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
+    LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
+  } else if (dynlen(obsConnections) > 0) {
+    oldObsConnections = obsConnections;
   } else {
-    if (!isStandalone()) LOG_ERROR(\"ObservationFlow_cobaltLocusNodeProcesses.pnl:main|Couldn't find DP to connect to: \"+activeObsDP);
-  }	
-
-}
-" 0
+    setStates(0,0);
+  }    
+}" 0
  E "main(int x, int y)
 {
   click();
@@ -79,64 +111,6 @@ void rClick() {
   navPanel_setEvent(\"Stations\",\"EventRightClick\");
 }
 
-void updateActiveObservations(string dp1, dyn_string obs,
-                              string dp2, bool invalid)
-{
-
-  // remove pipelines from the list
-  for (int i=dynlen(obs);i > 0;  i--) if (!navFunct_isObservation(obs[i])) dynRemove(obs,i);
-  
-  activeObservations = obs;
-  // if there are selected observation check the observationsList if those selected observations still are active
-  // remove the unactive observations from the list  
-  
-  // replace old observations if there are no observations selected
-  if (selectedObservations) {
-    for (int i=dynlen(observationsList); i < 1; i--) {
-      int idx = dynContains(activeObservations,observationsList[i]);
-      if (i <= 0) dynRemove(observationsList,i);
-    }
-    if (dynlen(observationsList) ==0) {
-      selectedObservations=false;
-    }
-  }
-  
-  if (!selectedObservations) {
-    observationsList = activeObservations;
-  }
-  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
-  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
-  
-  LOG_DEBUG(\"ObservationFlow_cobaltNodeProcesses.pnl:updateActiveObservations|observationList: \"+observationsList);
-
-  dyn_string obsConnections = makeDynString();  
-  for (int i = 1; i <= dynlen(observationsList) ; i++) {
-    // compose the WinCC OA DP name 
-    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
-
-    // Ask the claimmanager for the temp obs representation
-    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
-
-    // add DP to list with all connects
-    dynAppend(obsConnections,obsDP+\".runState\");
-  }
-  
-  if (dynlen(oldObsConnections) > 0) {
-    // disconnect old observations
-    dpDisconnect(\"monitorRunStates\",oldObsConnections);
-    dynClear(oldObsConnections);
-  }
-  
-  // connect to runState for all active observations  
-  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
-    LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:updateActiveObservations|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
-  } else if (dynlen(obsConnections) > 0) {
-    oldObsConnections = obsConnections;
-  } else {
-    setStates(0,0);
-  }    
-}
-
 void monitorRunStates(dyn_string dpList,dyn_string runStates) {
 
   for (int i=1; i<= dynlen(runStates); i++) {
@@ -152,7 +126,9 @@ void connectCobaltLocusNodesAndProcesses(string runState) {
   string connectToStates = \"\";
   // change all found DP's to contain all the elements that contain the states and childstates
   if (connectedStates) {
-    dpDisconnect(\"cobaltLocusNodesAndProcessesCB\",oldStateDPs);
+    if (dpDisconnect(\"cobaltLocusNodesAndProcessesCB\",oldStateDPs) <0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltNodeProcesses.pnl:conentCobaltLocusNodesAndProcesses\", getLastError());
+    }
     connectedStates = false;
   }
 
diff --git a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltNodeProcesses.pnl b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltNodeProcesses.pnl
index 9f9ed0bd54c8c4264e730efb95ba4991747d3c5b..5f50303641cdbb5a8856fd5c83bdffd7d0554ce8 100644
--- a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltNodeProcesses.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltNodeProcesses.pnl
@@ -7,20 +7,50 @@ PANEL,-1 -1 242 91 N "_3DFace" 0
   baseDP = \"LOFAR_PermSW\";
   database=dpSubStr(baseDP,DPSUB_SYS);
   
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
+  
   activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";  
-  // check if MACScheduler pointenabled and accessible
-  if (dpExists(activeObsDP)) {
-    if (dpConnect(\"updateActiveObservations\", activeObsDP+\":_online.._value\",
-                                             activeObsDP+\":_online.._invalid\") == -1) {
-      LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|Couldn't connect to: \"+activeObsDP);
+  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
+  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
+  
+  LOG_DEBUG(\"ObservationFlow_cobaltNodeProcesses.pnl:main|observationList: \"+observationsList);
+
+  dyn_string obsConnections = makeDynString();  
+  for (int i = 1; i <= dynlen(observationsList) ; i++) {
+    // compose the WinCC OA DP name 
+    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
+
+    // Ask the claimmanager for the temp obs representation
+    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
+
+    // add DP to list with all connects
+    dynAppend(obsConnections,obsDP+\".runState\");
+  }
+  
+  if (dynlen(oldObsConnections) > 0) {
+    // disconnect old observations
+    if (dpDisconnect(\"monitorRunStates\",oldObsConnections) <0 ) {
+      navFunct_printLastError(\"ObservationFlow_cobaltNodeProcesses.pnl:main\", getLastError());
     }
-  } else {
-    if (!isStandalone()) LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|Couldn't find DP to connect to: \"+activeObsDP);
+    dynClear(oldObsConnections);
   }
   
-  	
-}
-" 0
+  // connect to runState for all active observations  
+  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
+    LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:main|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
+  } else if (dynlen(obsConnections) > 0) {
+    oldObsConnections = obsConnections;
+  } else {
+    setStates(0,0);
+  }    
+  
+}" 0
  E "main(int x, int y)
 {
   click();
@@ -80,64 +110,6 @@ void rClick() {
   navPanel_setEvent(\"Stations\",\"EventRightClick\");
 }
 
-void updateActiveObservations(string dp1, dyn_string obs,
-                              string dp2, bool invalid)
-{
-
-  // remove pipelines from the list
-  for (int i=dynlen(obs);i > 0;  i--) if (!navFunct_isObservation(obs[i])) dynRemove(obs,i);
-  
-  activeObservations = obs;
-  // if there are selected observation check the observationsList if those selected observations still are active
-  // remove the unactive observations from the list  
-  
-  // replace old observations if there are no observations selected
-  if (selectedObservations) {
-    for (int i=dynlen(observationsList); i < 1; i--) {
-      int idx = dynContains(activeObservations,observationsList[i]);
-      if (i <= 0) dynRemove(observationsList,i);
-    }
-    if (dynlen(observationsList) ==0) {
-      selectedObservations=false;
-    }
-  }
-  
-  if (!selectedObservations) {
-    observationsList = activeObservations;
-  }
-  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
-  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
-  
-  LOG_DEBUG(\"ObservationFlow_cobaltNodeProcesses.pnl:updateActiveObservations|observationList: \"+observationsList);
-
-  dyn_string obsConnections = makeDynString();  
-  for (int i = 1; i <= dynlen(observationsList) ; i++) {
-    // compose the WinCC OA DP name 
-    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
-
-    // Ask the claimmanager for the temp obs representation
-    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
-
-    // add DP to list with all connects
-    dynAppend(obsConnections,obsDP+\".runState\");
-  }
-  
-  if (dynlen(oldObsConnections) > 0) {
-    // disconnect old observations
-    dpDisconnect(\"monitorRunStates\",oldObsConnections);
-    dynClear(oldObsConnections);
-  }
-  
-  // connect to runState for all active observations  
-  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
-    LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:updateActiveObservations|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
-  } else if (dynlen(obsConnections) > 0) {
-    oldObsConnections = obsConnections;
-  } else {
-    setStates(0,0);
-  }    
-  
-}
 
 void monitorRunStates(dyn_string dpList,dyn_string runStates) {
   for (int i=1; i<= dynlen(runStates); i++) {
@@ -153,7 +125,9 @@ void connectCobaltNodesAndProcesses(string runState) {
   
   // change all found DP's to contain all the elements that contain the states and childstates
   if (connectedStates) {
-    dpDisconnect(\"cobaltNodesAndProcessesCB\",oldStateDPs);
+    if (dpDisconnect(\"cobaltNodesAndProcessesCB\",oldStateDPs) < 0 ) {
+      navFunct_printLastError(\"ObservationFlow_cobaltNodeProcesses.pnl:connectCobaltNodesAndProcesses\", getLastError());
+    }
     connectedStates = false;
   }
 
@@ -192,8 +166,12 @@ void connectCobaltNodesAndProcesses(string runState) {
     dynAppend(stateDPs,CEPDBName+\"LOFAR_PIC_Cobalt.status.state\");
     dynAppend(stateDPs,CEPDBName+\"LOFAR_PIC_Cobalt.status.childState\");
     
-    
-    if (dpConnect(\"cobaltNodesAndProcessesCB\",TRUE,stateDPs) == -1) {
+    dpConnect(\"cobaltNodesAndProcessesCB\",TRUE,stateDPs);
+    dyn_errClass err = getLastError(); //test whether an error occurred 
+    if(dynlen(err) > 0) { 
+      errorDialog(err); 
+      // open dialog box with errors 
+      throwError(err); // write errors to stderr 
       LOG_ERROR(\"ObservationFlow_cobaltNodeProcesses.pnl:connectCobaltNodesAndProcesses| ERROR: connect fails:\"+ stateDPs);
     } else {
       connectedStates = true;
diff --git a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltOutputProc.pnl b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltOutputProc.pnl
index a9097164a2b8fd462e72838ba77f1b44dd1beaa1..3955168c5531526c719244a47e536f464814be6c 100644
--- a/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltOutputProc.pnl
+++ b/MAC/Navigator2/panels/objects/Processes/observationFlow_cobaltOutputProc.pnl
@@ -7,19 +7,49 @@ PANEL,-1 -1 447 41 N "_3DFace" 0
   baseDP= \"LOFAR_PermSW\";
   database=dpSubStr(baseDP,DPSUB_SYS);
 
-  activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";
-  // check if MACScheduler pointenabled and accessible
-  if (dpExists(activeObsDP)) {
-    if (dpConnect(\"updateActiveObservations\", activeObsDP+\":_online.._value\",
-                                              activeObsDP+\":_online.._invalid\") == -1) {
-      LOG_ERROR(\"ObservationFlow_cobaltOutputProc.pnl:main|Couldn't connect to: \"+activeObsDP);
-    }
-  } else {
-    if (!isStandalone()) LOG_ERROR(\"ObservationFlow_cobaltOutputProc.pnl:main|Couldn't find DP to connect to: \"+activeObsDP);
-  }	
+  dyn_string obslist;
+  int i = dpGet(MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\",obslist);
+  // remove all pipelines
+  for (i=1; i<=dynlen(obslist); i++) {
+    if (!navFunct_isObservation(obslist[i])) continue;
+    dynAppend(observationsList,obslist[i]);
+  }
+  
+  activeObsDP =MainDBName+\"LOFAR_PermSW_MACScheduler.activeObservations\";  
+  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
+  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
+  
+  LOG_DEBUG(\"ObservationFlow_cobaltOutputProcs.pnl:main|observationList: \"+observationsList);
 
-}
-" 0
+  dyn_string obsConnections = makeDynString();  
+  for (int i = 1; i <= dynlen(observationsList) ; i++) {
+    // compose the WinCC OA DP name 
+    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
+
+    // Ask the claimmanager for the temp obs representation
+    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
+
+    // add DP to list with all connects
+    if (! dynContains(obsConnections,obsDP+\".runState\")) dynAppend(obsConnections,obsDP+\".runState\");
+  }
+  
+  if (dynlen(oldObsConnections) > 0) {
+    // disconnect old observations
+    if (dpDisconnect(\"monitorRunStates\",oldObsConnections) < 0) {
+      navFunct_printLastError(\"ObservationFlow_cobaltOutputProcs.pnl:main\", getLastError());
+    }
+    dynClear(oldObsConnections);
+  }
+  
+  // connect to runState for all active observations  
+  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
+    LOG_ERROR(\"ObservationFlow_cobaltOutputProcs.pnl:main|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
+  } else if (dynlen(obsConnections) > 0) {
+    oldObsConnections = obsConnections;
+  }  else {
+    setValue(\"outputProcsObject\", \"foreCol\", \"Lofar_off\");
+  }    
+}" 0
  E "main(int x, int y)
 {
   click();
@@ -83,64 +113,6 @@ void rClick() {
   }
 }
 
-void updateActiveObservations(string dp1, dyn_string obs,
-                              string dp2, bool invalid)
-{
-
-  // remove pipelines from the list
-  for (int i=dynlen(obs);i > 0;  i--) if (!navFunct_isObservation(obs[i])) dynRemove(obs,i);
-  
-  activeObservations = obs;
-
-  // if there are selected observation check the observationsList if those selected observations still are active
-  // remove the unactive observations from the list  
-  
-  // replace old observations if there are no observations selected
-  if (selectedObservations) {
-    for (int i=dynlen(observationsList); i < 1; i--) {
-      int idx = dynContains(activeObservations,observationsList[i]);
-      if (i <= 0) dynRemove(observationsList,i);
-    }
-    if (dynlen(observationsList) ==0) {
-      selectedObservations=false;
-    }
-  }
-  
-  if (!selectedObservations) {
-    observationsList = activeObservations;
-  }
-  // because CobaltProcesses claim their datapoints when the observation is actually running we need to connect to all these observations
-  // and give a signal when the runstate of one of them changes to running to trigger the Cobalt point collection
-  
-  LOG_DEBUG(\"ObservationFlow_cobaltOutputProcs.pnl:updateActiveObservations|observationList: \"+observationsList);
-
-  dyn_string obsConnections = makeDynString();  
-  for (int i = 1; i <= dynlen(observationsList) ; i++) {
-    // compose the WinCC OA DP name 
-    string obsName = \"LOFAR_ObsSW_\"+observationsList[i]; 
-
-    // Ask the claimmanager for the temp obs representation
-    string obsDP=MainDBName+claimManager_nameToRealName(obsName);
-
-    // add DP to list with all connects
-    if (! dynContains(obsConnections,obsDP+\".runState\")) dynAppend(obsConnections,obsDP+\".runState\");
-  }
-  
-  if (dynlen(oldObsConnections) > 0) {
-    // disconnect old observations
-    dpDisconnect(\"monitorRunStates\",oldObsConnections);
-    dynClear(oldObsConnections);
-  }
-  
-  // connect to runState for all active observations  
-  if (dynlen(obsConnections) > 0 && dpConnect(\"monitorRunStates\",obsConnections) == -1) {
-    LOG_ERROR(\"ObservationFlow_cobaltOutputProcs.pnl:updateActiveObservations|ERROR: couldn't connect to : \"+obsConnections+ \" \" + getLastError());
-  } else if (dynlen(obsConnections) > 0) {
-    oldObsConnections = obsConnections;
-  }  else {
-    setValue(\"outputProcsObject\", \"foreCol\", \"Lofar_off\");
-  }    
-}
 
 void monitorRunStates(dyn_string dpList,dyn_string runStates) {
 
@@ -159,7 +131,9 @@ void connectOutputProcs(string runState) {
 
   // change all found DP's to contain all the elements that contain the .dropping
   if (connectedOutputProcs) {
-    dpDisconnect(\"outputProcCB\",connectToOutputProcs);
+    if (dpDisconnect(\"outputProcCB\",connectToOutputProcs) < 0 ) {
+      navFunct_printLastError(\"ObservationFlow_cobaltOutputProcs.pnl:connectOutputProcs\", getLastError());
+    }
     dynClear(connectToOutputProcs);
     connectedOutputProcs = false;
   }
diff --git a/MAC/Navigator2/scripts/libs/Station_Processes.ctl b/MAC/Navigator2/scripts/libs/Station_Processes.ctl
index d330b3f5b1aec15f1822ee2e8a4d4a909abab413..49a17713a380b9ecb69dd2887ae7bded9c800eae 100644
--- a/MAC/Navigator2/scripts/libs/Station_Processes.ctl
+++ b/MAC/Navigator2/scripts/libs/Station_Processes.ctl
@@ -72,7 +72,7 @@ bool Station_Processes_initList() {
   dynClear(station_procList);
   
   if (!navFunct_dpReachable(station_selectedStation)) {
-    return;
+    return false;
   }
   int z;
   dyn_dyn_anytype tab;
@@ -285,7 +285,7 @@ Station_Processes_UpdateStationTree() {
       LOG_TRACE("Station_Processes.ctl:updateStationTree|calling UpdateStationControllers. selected ststion: "+station_selectedStation);
       if (!Station_Processes_UpdateStationControllers()) {
         LOG_ERROR("Station_Processes.ctl:UpdateStationTree|UpdateStationControllers returned false");
-        return false;
+        return;
       }
       if (station_selectedStation != "" && stationTree.itemExists(navFunct_bareDBName(station_selectedStation))) {
         stationTree.setSelectedItem(navFunct_bareDBName(station_selectedStation),true);
diff --git a/MAC/Navigator2/scripts/libs/navFunct.ctl b/MAC/Navigator2/scripts/libs/navFunct.ctl
index 118be69b1d95046199d3609a71a8bc16666ca84b..25b75a2c4573222be3847b7e744be35318d3458c 100644
--- a/MAC/Navigator2/scripts/libs/navFunct.ctl
+++ b/MAC/Navigator2/scripts/libs/navFunct.ctl
@@ -87,6 +87,7 @@
 // navFunct_observationInPool                 : Look if a given observation is in a given pool (planned,active, finished)
 // navFunct_observationNameToNumber           : Strips Observation from the name and returns the bare number
 // navFunct_ObsToTemp                         : returns the temp observationname
+// navFunct_printLastError                    : determines if there was an error, and if so prints the errorcode text and the error text
 // navFunct_queryConnectObservations          : Queryconnect to keep track of all observations
 // navFunct_receiver2Cabinet                  : Returns the CabinetNr for a RecieverNr
 // navFunct_receiver2HBA                      : Returns the HBANr for a RecieverNr
@@ -2625,3 +2626,13 @@ bool navFunct_checkEmailAddress(string anAddress)
   if (dynlen(part2) != 2 || part2[1] == "" || part2[2] == "" ) return FALSE;
   return TRUE;
 }
+
+void navFunct_printLastError(string place, dyn_errClass err)
+{
+   if(dynlen(err) > 0) 
+   { 
+     string dpName = getErrorDpName(err); // get the dpname relatedto the error
+     string errText = getErrorText(err); //get the error text 
+     LOG_ERROR(place+"| Error : " + dpName + " : " + errText);
+   } 
+}
diff --git a/SubSystems/Online_Cobalt/test/tRTmetadataToFile.run b/SubSystems/Online_Cobalt/test/tRTmetadataToFile.run
index 13198e887a95e602a8fc42771ae36df22ddb06cb..2da44f7fe26611574690b5094ee58b8465ba3313 100755
--- a/SubSystems/Online_Cobalt/test/tRTmetadataToFile.run
+++ b/SubSystems/Online_Cobalt/test/tRTmetadataToFile.run
@@ -25,9 +25,19 @@ fi
 PVSSGatewayStub &
 gwPid=$!
 
-# Wait until both services allow connections. This is faster than delaying ~RTmetadata(),
-# since we do binary backoff connection attempts. This also keeps the delay in testing only.
-sleep 2  # often 2 is enough, but when idle, even 5 may not be enough :((((
+# Wait until PVSSGatewayStub (and ServiceBroker if we started it) are listening.
+# Just sleep X secs has proven both long and still unreliable.
+# (Remaining risk: both services started but PVSSGatewayStub not yet registered at ServiceBroker.)
+NETSTAT=/bin/netstat
+gwReady=0
+sbReady=$((1-$sbPid))
+while [ $gwReady -eq 0 -o $sbReady -eq 0 ]; do
+  echo 'Waiting for PVSSGatewayStub and ServiceBroker listening sockets to show up in netstat...' >&2
+  sleep 0.1
+  netstatout=`"$NETSTAT" -l -p -A inet -n 2>/dev/null`
+  gwReady=`echo "$netstatout" | grep $gwPid/ | wc -l`
+  [ $sbPid -ne 0 ] && sbReady=`echo "$netstatout" | grep $sbPid/ | wc -l`
+done
 
 ../../../MAC/MACIO/test/tRTmetadata > /dev/null  # logging disrupts output verif
 
diff --git a/SubSystems/Online_Cobalt/validation/cluster/ethernet/iperf-cobalt2locus.test b/SubSystems/Online_Cobalt/validation/cluster/ethernet/iperf-cobalt2locus.test
index 1d5b96c4e8666f198b29059f780b2cb3b82ef233..1796d7a22ffc9657173e0c71bdc5ba4d9a7fa553 100755
--- a/SubSystems/Online_Cobalt/validation/cluster/ethernet/iperf-cobalt2locus.test
+++ b/SubSystems/Online_Cobalt/validation/cluster/ethernet/iperf-cobalt2locus.test
@@ -124,10 +124,10 @@ run_iperf_clients()
       rm -f /tmp/iperf-$host-*.log; \
       for target in ${IPERF_NODES[$host]}; \
       do \
-        iperf -N -t $IPERF_TIME -yc -c \${target} \
+        iperf -N -t $IPERF_TIME -yc -r -c \${target} \
           > /tmp/iperf-$host-\${target}.log & \
       done"
-    run_command "ssh $host \$(eval $ssh_cmd)" || exit
+    run_command "ssh $host \$(eval $ssh_cmd)" &
   done
 }
 
@@ -137,7 +137,7 @@ run_iperf_clients()
 # wait for one extra second.
 wait_for_results()
 {
-  sleep 1
+  sleep 5
   echo "Waiting $IPERF_TIME seconds for results ..." >&2
   sleep $IPERF_TIME
 }
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt001 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt001
index 5a51b3ceb79c7157d519f53a2fe13fc2f13173b6..826464a267a340eff164396e219a8a265b620ae3 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt001
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt001
@@ -18,3 +18,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.175.255.202 dev eth3  scope link 
 10.175.255.203 dev eth4  scope link 
 10.175.255.204 dev eth5  scope link 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt002 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt002
index 342ebb26bdc58a83a0dbc9daaff4fd9951bb4d62..aa94ed0c36f107e99167a9f7772a46c368fde362 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt002
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt002
@@ -18,3 +18,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.175.255.202 dev eth3  scope link 
 10.175.255.203 dev eth4  scope link 
 10.175.255.204 dev eth5  scope link 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt003 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt003
index aad1a4134dba2094a051d612ba3d4b43e8b1f8e9..2152563b9c6aacfa021803acf4484babfdf1f034 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt003
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt003
@@ -26,3 +26,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.212.0.0/16 dev vlan2012  proto kernel  scope link  src 10.212.1.103 
 10.213.0.0/16 dev vlan2013  proto kernel  scope link  src 10.213.1.103 
 10.214.0.0/16 dev vlan2014  proto kernel  scope link  src 10.214.1.103 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt004 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt004
index 434ec50fc4430df2c87ac752286da6b3ec236be4..4a1c5caa1f236af01a3e4f397c2a2448ed1a1c15 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt004
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt004
@@ -26,3 +26,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.212.0.0/16 dev vlan2012  proto kernel  scope link  src 10.212.1.104 
 10.213.0.0/16 dev vlan2013  proto kernel  scope link  src 10.213.1.104 
 10.214.0.0/16 dev vlan2014  proto kernel  scope link  src 10.214.1.104 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt005 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt005
index 0865c5735f5c4101bc1b199848e6163a5cec14ec..180e495194ea95b755c0793435294f744d986744 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt005
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt005
@@ -26,3 +26,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.212.0.0/16 dev vlan2012  proto kernel  scope link  src 10.212.1.105 
 10.213.0.0/16 dev vlan2013  proto kernel  scope link  src 10.213.1.105 
 10.214.0.0/16 dev vlan2014  proto kernel  scope link  src 10.214.1.105 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt006 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt006
index 603fbb22898473e6d82745e3666af6dc00375acf..515d8be0b1858ecd9d0376a81046b94c927c2dfc 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt006
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt006
@@ -18,3 +18,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.175.255.202 dev eth3  scope link 
 10.175.255.203 dev eth4  scope link 
 10.175.255.204 dev eth5  scope link 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt007 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt007
index 7efeef221f8b3cf625e95228baf282ee10b1340f..7b8f38562e97851becbf71ea6487af6f2c5c66a7 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt007
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt007
@@ -18,3 +18,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.175.255.202 dev eth3  scope link 
 10.175.255.203 dev eth4  scope link 
 10.175.255.204 dev eth5  scope link 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt008 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt008
index 46eab230030b071bab35bc1c353afc65afc1c916..d13b08155de537ac9d78be71e3219fa967c3dd06 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt008
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt008
@@ -26,3 +26,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.212.0.0/16 dev vlan2012  proto kernel  scope link  src 10.212.1.108 
 10.213.0.0/16 dev vlan2013  proto kernel  scope link  src 10.213.1.108 
 10.214.0.0/16 dev vlan2014  proto kernel  scope link  src 10.214.1.108 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt009 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt009
index 0b3ec69102487a121172b527d6a3ea722d2391dc..366d63f8ed05b513d247153b1c6124fd3a87d220 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt009
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt009
@@ -26,3 +26,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.212.0.0/16 dev vlan2012  proto kernel  scope link  src 10.212.1.109 
 10.213.0.0/16 dev vlan2013  proto kernel  scope link  src 10.213.1.109 
 10.214.0.0/16 dev vlan2014  proto kernel  scope link  src 10.214.1.109 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt010 b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt010
index d94f0f4e2628faacd1adb406bb23a12fb8a8eff2..23ea8c95e9a4b56ef9ef0b5ecaf98318adbcac41 100644
--- a/SubSystems/Online_Cobalt/validation/system/network/routes.cbt010
+++ b/SubSystems/Online_Cobalt/validation/system/network/routes.cbt010
@@ -18,3 +18,4 @@ default via 10.151.255.254 dev eth0  metric 100
 10.175.255.202 dev eth3  scope link 
 10.175.255.203 dev eth4  scope link 
 10.175.255.204 dev eth5  scope link 
+192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
diff --git a/SubSystems/Online_Cobalt/validation/system/os/get_smp_affinity.reference b/SubSystems/Online_Cobalt/validation/system/os/get_smp_affinity.reference
index 4689117ad9cc3fc80353fd5d31556b7deae05996..51607fb5124bf5951dfb978cbb1a19a12951414c 100644
--- a/SubSystems/Online_Cobalt/validation/system/os/get_smp_affinity.reference
+++ b/SubSystems/Online_Cobalt/validation/system/os/get_smp_affinity.reference
@@ -142,42 +142,4 @@ eth5 irq 270 bound to core 29
 eth5 irq 271 bound to core 31
 eth5 irq 272 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
 mlx4_0 irq 273 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 274 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 275 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 276 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 277 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 278 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 279 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 280 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 281 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 282 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 283 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 284 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 285 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 286 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 287 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 288 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 289 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 290 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 291 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_0 irq 292 bound to core 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
-mlx4_1 irq 294 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 295 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 296 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 297 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 298 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 299 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 300 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 301 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 302 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 303 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 304 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 305 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
 mlx4_1 irq 306 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 307 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 308 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 309 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 310 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 311 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 312 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
-mlx4_1 irq 313 bound to core 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31