diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc b/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc
index a64a502e986cbaaecb500b103813da1228a0e161..e12187d34dd7da656846715b8e5f8b91f4fa7146 100644
--- a/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/ChildControl.cc
@@ -30,7 +30,7 @@
 #include <GCF/GCF_ServiceInfo.h>
 #include <GCF/Utils.h>
 #include <APL/APLCommon/APLUtilities.h>
-#include <APL/APLCommon/LogicalDevice_Protocol.ph>
+#include <APL/APLCommon/Controller_Protocol.ph>
 #include <APL/APLCommon/StartDaemon_Protocol.ph>
 
 namespace LOFAR {
@@ -61,11 +61,13 @@ ChildControl::ChildControl() :
 	itsStartupRetryInterval	(10),
 	itsMaxStartupRetries	(5),
 	itsCntlrList	 		(),
-	itsActionList	 		()
+	itsActionList	 		(),
+	itsCompletionTimer		(0),
+	itsCompletionPort		(0)
 {
 	// Log the protocols I use.
-	registerProtocol(LOGICALDEVICE_PROTOCOL, LOGICALDEVICE_PROTOCOL_signalnames);
-	registerProtocol(STARTDAEMON_PROTOCOL,   STARTDAEMON_PROTOCOL_signalnames);
+	registerProtocol(CONTROLLER_PROTOCOL, CONTROLLER_PROTOCOL_signalnames);
+	registerProtocol(STARTDAEMON_PROTOCOL,STARTDAEMON_PROTOCOL_signalnames);
 
 	// adopt optional redefinition of startup-retry settings
 	if (globalParameterSet()->isDefined("ChildControl.StartupRetryInterval")) {
@@ -127,11 +129,12 @@ void ChildControl::openService(const string&	aServiceName,
 }
 
 //
-// startChild (name, obsId, aCntlType, hostname)
+// startChild (name, obsId, aCntlType, instanceNr, hostname)
 //
 bool ChildControl::startChild (const string&		aName, 
 							   OTDB::treeIDType		anObsID, 
 							   const string&		aCntlrType, 
+							   uint32				instanceNr,
 							   const string&		hostname)
 {
 	// first check if child already exists
@@ -139,10 +142,41 @@ bool ChildControl::startChild (const string&		aName,
 		return (false);
 	}	
 
+	// make sure there is a parameterSet for the program.
+	if (aCntlrType != CNTLRTYPE_OBSERVATIONCTRL) {
+		// search observation-parset for controller name and determine prefix
+		string			baseSetName = formatString("%s/Observation_%d", 
+													LOFAR_SHARE_LOCATION, anObsID);
+		LOG_DEBUG_STR ("Reading parameterfile: " << baseSetName);
+		ParameterSet	wholeSet (baseSetName);
+		ParameterSet::iterator		iter = wholeSet.begin();
+		ParameterSet::iterator		end  = wholeSet.end();
+		while (iter != end) {
+			// search a parameter that is meant for this controller
+			// to determine the position of the controller in the tree.
+			if (keyName(moduleName(iter->first)) == aName) {
+				string	cntlrSetName = formatString("%s/%s", LOFAR_SHARE_LOCATION, 
+															 aName.c_str());
+				LOG_DEBUG_STR("Creating parameterfile: " << cntlrSetName);
+				ParameterSet	cntlrSet = wholeSet.makeSubset(moduleName(iter->first));
+				cntlrSet.add("prefix", moduleName(iter->first));
+				cntlrSet.writeFile (cntlrSetName);
+				break;
+			}
+			iter++;
+		}
+		if (iter == end) {		// could not create a parameterset, report failure.
+			LOG_ERROR_STR("No parameter information found for controller " << aName <<
+						  " in file " << baseSetName << ". Cannot start controller!");
+			return (false);
+		}
+	}
+
 	// Alright, child does not exist yet. 
 	// construct structure with all information
 	ControllerInfo		ci;
 	ci.name			  = aName;
+	ci.instanceNr	  = instanceNr;
 	ci.obsID		  = anObsID;
 	ci.cntlrType	  = aCntlrType;
 	ci.port			  = 0;
@@ -182,7 +216,7 @@ bool ChildControl::requestState	(LDState::LDstateNr	aState,
 {
 	bool	checkName   = (aName != "");
 	bool	checkID     = (anObsID != 0);
-	bool	checkType   = (aCntlrType != LDTYPE_NO_TYPE);
+	bool	checkType   = (aCntlrType != CNTLRTYPE_NO_TYPE);
 	time_t	currentTime = time(0);
 
 //	stateChangeEvent	request;
@@ -253,7 +287,7 @@ uint32 ChildControl::countChilds (OTDB::treeIDType	anObsID,
 								  const string&		aCntlrType)
 {
 	bool	checkID   = (anObsID != 0);
-	bool	checkType = (aCntlrType != LDTYPE_NO_TYPE);
+	bool	checkType = (aCntlrType != CNTLRTYPE_NO_TYPE);
 
 	if (!checkID && !checkType) {
 		return (itsCntlrList.size());
@@ -290,7 +324,7 @@ ChildControl::getPendingRequest (const string&		aName,
 
 	bool	checkName   = (aName != "");
 	bool	checkID     = (anObsID != 0);
-	bool	checkType   = (aCntlrType != LDTYPE_NO_TYPE);
+	bool	checkType   = (aCntlrType != CNTLRTYPE_NO_TYPE);
 
 	const_CIiter	iter  = itsCntlrList.begin();
 	const_CIiter	end   = itsCntlrList.end();
@@ -316,6 +350,37 @@ ChildControl::getPendingRequest (const string&		aName,
 	return (resultVec);
 }
 
+//
+// getCompletedStates (lastPollTime)
+//
+// Returns a vector with all requests that are completed since lastPollTime
+//
+vector<ChildControl::StateInfo> 
+ChildControl::getCompletedStates (time_t	lastPollTime)
+{
+	vector<ChildControl::StateInfo>	resultVec;
+
+	const_CIiter	iter  = itsCntlrList.begin();
+	const_CIiter	end   = itsCntlrList.end();
+	while (iter != end) {
+		if (iter->establishTime > lastPollTime) {
+			// add info to vector
+			StateInfo	si;
+			si.name			  = iter->name;
+			si.cntlrType	  = iter->cntlrType;
+			si.isConnected	  = (iter->port != 0);
+			si.requestedState = iter->requestedState;
+			si.requestTime	  = iter->requestTime;
+			si.currentState	  = iter->currentState;
+			si.establishTime  = iter->establishTime;
+			resultVec.push_back(si);
+		}
+		iter++;
+	}	
+
+	return (resultVec);
+}
+
 // -------------------- PRIVATE ROUTINES --------------------
 
 //
@@ -402,18 +467,19 @@ void ChildControl::_processActionList()
 					LOG_DEBUG_STR("Requesting start of " << action->name << " at " 
 																	<< action->hostname);
 					STARTDAEMONCreateEvent		startRequest;
-					startRequest.logicalDeviceType = action->cntlrType;
-					startRequest.taskName 		   = action->name;
-					startRequest.parentHost		   = GCF::Common::myHostname();
-					startRequest.parentService	   = itsListener->makeServiceName();
+					startRequest.cntlrType 	   = action->cntlrType;
+					startRequest.cntlrName 	   = action->name;
+					startRequest.parentHost	   = GCF::Common::myHostname();
+					startRequest.parentService = itsListener->makeServiceName();
 					startDaemon->second->send(startRequest);
 
-					// we don't know if startup is successfull, reschedule startup
-					// over x seconds for safety. Note: when a succesfull startup
+					// we don't know if startup is successful, reschedule startup
+					// over x seconds for safety. Note: when a successful startup
 					// is received the rescheduled action is removed.
-					action->retryTime = time(0) + itsStartupRetryInterval;
-					action->nrRetries++;
-					itsActionList.push_back(*action);	// reschedule
+//					action->retryTime = time(0) + itsStartupRetryInterval;
+//					action->nrRetries++;
+//					itsActionList.push_back(*action);	// reschedule
+//					... Parent is responsible for rescheduling! ...
 				}
 				else {
 					LOG_WARN_STR ("Could not start controller " << action->name << 
@@ -425,28 +491,32 @@ void ChildControl::_processActionList()
 
 		case LDState::CLAIMED:
 			{
-				LOGICALDEVICEClaimEvent		request;
+				CONTROLClaimEvent		request;
+				request.cntlrName = controller->name;
 				controller->port->send(request);
 			}
 			break;
 
 		case LDState::PREPARED:
 			{
-				LOGICALDEVICEPrepareEvent		request;
+				CONTROLPrepareEvent		request;
+				request.cntlrName = controller->name;
 				controller->port->send(request);
 			}
 			break;
 
 		case LDState::ACTIVE:
 			{
-				LOGICALDEVICEResumeEvent		request;
+				CONTROLResumeEvent		request;
+				request.cntlrName = controller->name;
 				controller->port->send(request);
 			}
 			break;
 
 		case LDState::SUSPENDED:
 			{
-				LOGICALDEVICESuspendEvent		request;
+				CONTROLSuspendEvent		request;
+				request.cntlrName = controller->name;
 				controller->port->send(request);
 			}
 			break;
@@ -454,7 +524,8 @@ void ChildControl::_processActionList()
 		case LDState::RELEASED:
 		case LDState::FINISHED:
 			{
-				LOGICALDEVICEReleaseEvent		request;
+				CONTROLReleaseEvent		request;
+				request.cntlrName = controller->name;
 				controller->port->send(request);
 			}
 			break;
@@ -498,7 +569,8 @@ void ChildControl::_removeAction (const string&			aName,
 //
 void ChildControl::_setEstablishedState(const string&		aName,
 										LDState::LDstateNr	newState,
-										time_t				atTime)
+										time_t				atTime,
+										bool				successful)
 {
 	CIiter	controller = findController(aName);
 	if (controller == itsCntlrList.end()) {
@@ -506,8 +578,84 @@ void ChildControl::_setEstablishedState(const string&		aName,
 		return;
 	}
 
-	controller->currentState  = newState;
+	// update controller information
+	if (!(controller->failed = !successful)) {;
+		controller->currentState  = newState;
+	}
 	controller->establishTime = atTime;
+
+	if (itsCompletionTimer) {
+		itsCompletionTimer->setTimer(0.0);
+	}
+
+	if (!itsCompletionPort) {
+		return;
+	}
+
+	LOG_DEBUG_STR("newState=" << newState);
+
+	TLDResult	result = controller->failed ? LD_RESULT_UNSPECIFIED : LD_RESULT_NO_ERROR;
+	switch (newState) {
+	case LDState::CREATED: {
+			CONTROLStartedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.successful= successful;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::CONNECTED: {
+			CONTROLConnectedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::CLAIMED: {
+			CONTROLClaimedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::PREPARED: {
+			CONTROLPreparedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::ACTIVE: {
+			CONTROLResumedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::SUSPENDED: {
+			CONTROLSuspendedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::RELEASED: {
+			CONTROLReleasedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	case LDState::FINISHED: {
+			CONTROLFinishedEvent	msg;
+			msg.cntlrName = controller->name;
+			msg.result    = result;
+			itsCompletionPort->sendBack(msg);
+		}
+		break;
+	default:
+		// do nothing
+		break;
+	}
 }
 
 // -------------------- STATE MACHINES FOR GCFTASK --------------------
@@ -542,6 +690,7 @@ GCFEvent::TResult	ChildControl::initial (GCFEvent&			event,
 		break;
 
 	case F_DISCONNECTED:
+		port.close();
 		if (&port == itsListener) {
 			port.setTimer(1.0);
 		}
@@ -556,7 +705,7 @@ GCFEvent::TResult	ChildControl::initial (GCFEvent&			event,
 		break;
 
 	default:
-		LOG_DEBUG_STR ("ChildControl(" << getName() << ")::initial, default");
+		LOG_DEBUG ("ChildControl::initial, default");
 		status = GCFEvent::NOT_HANDLED;
 		break;
 	}
@@ -574,7 +723,8 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 											  GCFPortInterface&	port)
 
 {
-	LOG_DEBUG ("ChildControl::operational");
+	LOG_DEBUG_STR ("ChildControl::operational:" << evtstr(event) 
+											    << "@" << port.getName());
 
 	GCFEvent::TResult	status = GCFEvent::HANDLED;
 
@@ -587,14 +737,12 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 
 	case F_ACCEPT_REQ: {
 			// Should be from a just started Child.
-			ASSERTSTR(port.getProtocol() == LOGICALDEVICE_PROTOCOL, 
-											"AcceptReq on port " << port.getName());
-
 			// accept connection and add port to port-vector
 			GCFTCPPort* client(new GCFTCPPort);
+
 			// reminder: init (task, name, type, protocol [,raw])
 			client->init(*this, "newChild", GCFPortInterface::SPP, 
-														LOGICALDEVICE_PROTOCOL);
+														CONTROLLER_PROTOCOL);
 			itsListener->accept(*client);
 
 			// Note: we do not keep an administration of the accepted child
@@ -607,6 +755,8 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 		break;
 
 	case F_DISCONNECTED: {
+			port.close();		// always close port
+
 			CIiter		controller = itsCntlrList.begin();
 			CIiter		end		   = itsCntlrList.end();
 			while (controller != end) {
@@ -617,8 +767,7 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 				}
 
 				// found controller, close port
-				port.close();
-				if (controller->currentState == LDState::FINISHED) {	// expected disconnect?
+				if (controller->currentState == LDState::FINISHED) {// expected disconnect?
 					itsCntlrList.erase(controller);			// just remove
 				}
 				else {
@@ -638,31 +787,28 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 	case STARTDAEMON_CREATED:	// startDaemon reports startup of program
 		{
 		STARTDAEMONCreatedEvent		result(event);
-		LOG_DEBUG_STR("Startup of " << result.taskName << "ready, result=" 	
+		LOG_DEBUG_STR("Startup of " << result.cntlrName << " ready, result=" 	
 														<< result.result);
-		if (result.result == SD_RESULT_NO_ERROR) {
-			// startup is successfull, remove rescheduled startup.
-			_removeAction(result.taskName, LDState::CONNECTED);
-		}
-		// note: when startup of child failed the state is not updated and the
-		// 		 parent will discover this when checking the pending requests.
+		_setEstablishedState(result.cntlrName, LDState::CREATED, time(0),
+							 result.result == SD_RESULT_NO_ERROR);
 		}
 		break;
 
-	case LOGICALDEVICE_CONNECT:
+	case CONTROL_CONNECT:		// received from just started controller
 		{
-			LOGICALDEVICEConnectEvent		msg(event);
-			LOGICALDEVICEConnectedEvent		answer;
+			CONTROLConnectEvent		msg(event);
+			CONTROLConnectedEvent		answer;
 
-			CIiter	controller = findController(msg.nodeId);
+			CIiter	controller = findController(msg.cntlrName);
 			if (controller == itsCntlrList.end()) {		// not found?
 				LOG_WARN_STR ("CONNECT event received from unknown controller: " <<
-							  msg.nodeId);
+							  msg.cntlrName);
 				answer.result = LD_RESULT_UNSPECIFIED;
 			}
 			else {
-				LOG_DEBUG_STR("CONNECT event received from " << msg.nodeId);
-				_setEstablishedState(msg.nodeId, LDState::CONNECTED, time(0));
+				LOG_DEBUG_STR("CONNECT event received from " << msg.cntlrName);
+				_setEstablishedState(msg.cntlrName, LDState::CONNECTED, time(0), true);
+				// first direct contact with controller, remember port
 				controller->port = &port;
 				answer.result = LD_RESULT_NO_ERROR;
 			}
@@ -670,8 +816,27 @@ GCFEvent::TResult	ChildControl::operational(GCFEvent&			event,
 		}
 		break;
 
+	case CONTROL_CLAIMED:
+		break;
+	
+	case CONTROL_PREPARED:
+		break;
+	
+	case CONTROL_RESUMED:
+		break;
+	
+	case CONTROL_SUSPENDED:
+		break;
+	
+	case CONTROL_RELEASED:
+		break;
+	
+	case CONTROL_FINISH:
+		break;
+	
+
 	default:
-		LOG_DEBUG_STR ("ChildControl(" << getName() << ")::operational, default");
+		LOG_DEBUG ("ChildControl::operational, default");
 		status = GCFEvent::NOT_HANDLED;
 		break;
 	}
diff --git a/MAC/APL/MainCU/src/MACScheduler/ChildControl.h b/MAC/APL/MainCU/src/MACScheduler/ChildControl.h
index f26d04ee24dc6787e0513ea4daa58f7775a0ffe1..332915cf399cc6740d04f51430deaf8fae041cb9 100644
--- a/MAC/APL/MainCU/src/MACScheduler/ChildControl.h
+++ b/MAC/APL/MainCU/src/MACScheduler/ChildControl.h
@@ -32,7 +32,9 @@
 #include <Common/lofar_map.h>
 #include <Common/lofar_list.h>
 #include <GCF/TM/GCF_Task.h>
+#include <GCF/TM/GCF_ITCPort.h>
 #include <GCF/TM/GCF_TCPPort.h>
+#include <GCF/TM/GCF_TimerPort.h>
 #include <APL/APLCommon/APL_Defines.h>
 #include <OTDB/OTDBtypes.h>
 #include "LDState.h"
@@ -44,6 +46,8 @@ namespace LOFAR {
   using GCF::TM::GCFEvent;
   using GCF::TM::GCFTask;
   using GCF::TM::GCFPortInterface;
+  using GCF::TM::GCFITCPort;
+  using GCF::TM::GCFTimerPort;
   using APLCommon::LDState;
   namespace MainCU {
 
@@ -72,6 +76,7 @@ public:
 		time_t				requestTime;	// time of requested state
 		LDState::LDstateNr	currentState;	// currrent (known) state of the controller
 		time_t				establishTime;	// time this state was reached
+		bool				failed;			// the requested state could not be reached
 	} StateInfo;
 
 	// Assign a name to the service the task should offer to the childs
@@ -82,21 +87,33 @@ public:
 	bool		startChild		(const string&		aName, 
 								 OTDB::treeIDType	anObsID, 
 								 const string&		aCntlrType, 
+							     uint32				instanceNr = 0,
 								 const string&		hostname = "localhost");
 	bool		requestState	(LDState::LDstateNr	state, 
 								 const string&		aName, 
 								 OTDB::treeIDType	anObsID = 0, 
-								 const string&		aCntlrType = LDTYPE_NO_TYPE);
+								 const string&		aCntlrType = CNTLRTYPE_NO_TYPE);
 	uint32		countChilds		(OTDB::treeIDType	anObsID = 0, 
-								 const string&		aCntlrType = LDTYPE_NO_TYPE);
+								 const string&		aCntlrType = CNTLRTYPE_NO_TYPE);
 
 	LDState::LDstateNr	getCurrentState		(const string&	aName);
 	LDState::LDstateNr	getRequestedState	(const string&	aName);
 
 	// management info for creator of class.
-	vector<StateInfo> getPendingRequest (const string&		aName, 
-								 		 OTDB::treeIDType	anObsID = 0, 
-								 		 const string&		aCntlrType = LDTYPE_NO_TYPE);
+	vector<StateInfo> getPendingRequest (const string&	  aName, 
+								 		 OTDB::treeIDType anObsID = 0, 
+								 		 const string&	  aCntlrType = CNTLRTYPE_NO_TYPE);
+
+	// The 'parent' task that uses this ChildControl class has three way of getting
+	// informed about the completed actions:
+	// [A] call getCompletedStates at regular intervals.
+	// [B] call setCompletionTimer once and call getCompletedStates when timer expires
+	// [C] call setCompletionPort once and handle the CONTROL events on that port.
+	vector<StateInfo>	getCompletedStates (time_t			lastPollTime);
+	void				registerCompletionTimer (GCFTimerPort*	theTimerPort)
+						{ itsCompletionTimer = theTimerPort; }
+	void				registerCompletionPort  (GCFITCPort*	theITCPort)
+						{ itsCompletionPort = theITCPort; }
 
 private:
 	// Copying is not allowed
@@ -112,13 +129,15 @@ private:
 	void _processActionList();
 	void _setEstablishedState (const string&		aName, 
 							   LDState::LDstateNr	newState,
-							   time_t				atTime);
+							   time_t				atTime,
+							   bool					successful);
 	void _removeAction		  (const string&		aName,
 							   LDState::LDstateNr	requestedState);
 
 	// Define struct for administration of the child controllers.
 	typedef struct ControllerInfo_t {
 		string				name;			// uniq name of the controller
+		uint32				instanceNr;		// for nonshared controllers
 		OTDB::treeIDType	obsID;			// observation tree the cntlr belongs to
 		GCFPortInterface*	port;			// connection with the controller
 		string				cntlrType;		// type of controller (mnemonic)
@@ -127,6 +146,7 @@ private:
 		time_t				requestTime;	// time of requested state
 		LDState::LDstateNr	currentState;	// the state the controller has
 		time_t				establishTime;	// time the current state was reached
+		bool				failed;			// requested state could not be reached
 		time_t				retryTime;		// time the request must be retried
 		uint32				nrRetries;		// nr of retries performed
 	} ControllerInfo;
@@ -143,13 +163,15 @@ private:
 	uint32						itsStartupRetryInterval;
 	uint32						itsMaxStartupRetries;
 
-	list<ControllerInfo>		itsCntlrList;		// administration of child controller
+	list<ControllerInfo>		itsCntlrList;		// admin. of child controllers
 
 	// All actions from the parent task are queued as ControllerInfo objects
 	// and handled in the operational stateMachine.
 	list<ControllerInfo>		itsActionList;		// list of actions to perform.
 	uint32						itsActionTimer;		// ID of actiontimer.
 
+	GCFTimerPort*				itsCompletionTimer;	// to signal parent in situation B
+	GCFITCPort*					itsCompletionPort;	// to signal parent in situation C
 //	...
 
 };
diff --git a/MAC/APL/MainCU/src/MACScheduler/LDState.cc b/MAC/APL/MainCU/src/MACScheduler/LDState.cc
index fdf0cbdd3c0ae3531d3fd07836ff2b059ae2b658..7eaad2b716fb22f8d36100b5984b738e2937cfb7 100644
--- a/MAC/APL/MainCU/src/MACScheduler/LDState.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/LDState.cc
@@ -37,6 +37,7 @@ LDState::LDState()
 {
 	itsStates.resize(LAST_STATE);
 	itsStates[NOSTATE] 				= "Unknown";
+	itsStates[CREATED] 				= "Created";
 	itsStates[CONNECT]				= "Connecting";
 	itsStates[CONNECTED]			= "Connected";
 	itsStates[CLAIM]				= "Claiming";
@@ -64,8 +65,7 @@ LDState::~LDState()
 //
 string	LDState::name(uint16			aStateNr)
 { 
-	return (((aStateNr >= NOSTATE) && (aStateNr < LAST_STATE)) ?
-											itsStates[aStateNr] : "");
+	return ((aStateNr < LAST_STATE) ?  itsStates[aStateNr] : "");
 }
 
 //
diff --git a/MAC/APL/MainCU/src/MACScheduler/LDState.h b/MAC/APL/MainCU/src/MACScheduler/LDState.h
index 0bba6a1eabebd8e6e1725ca272f68dd4e02e0360..a32f85482373ff1049719819efc23534b2c42b0c 100644
--- a/MAC/APL/MainCU/src/MACScheduler/LDState.h
+++ b/MAC/APL/MainCU/src/MACScheduler/LDState.h
@@ -51,6 +51,7 @@ public:
 	typedef enum {
 		ANYSTATE = -1,
 		NOSTATE = 0,
+		CREATED,
 		CONNECT,
 		CONNECTED,
 		CLAIM,
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
index 67321093b59e1899a83a46a5622960826ef8a168..5e155ac56f41a78427f839ee4ef7e486de9ec4dd 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
@@ -30,6 +30,7 @@
 #include <GCF/Utils.h>
 #include <APL/APLCommon/APL_Defines.h>
 #include <APL/APLCommon/APLCommonExceptions.h>
+#include <APL/APLCommon/Controller_Protocol.ph>
 
 #include "MACSchedulerDefines.h"
 #include "MACScheduler.h"
@@ -56,6 +57,7 @@ MACScheduler::MACScheduler() :
 //	itsObsCntlrMap		(),
 	itsDummyPort		(0),
 	itsChildControl		(0),
+	itsChildPort		(0),
 	itsSecondTimer		(0),
 	itsQueuePeriod		(0),
 	itsClaimPeriod		(0),
@@ -65,17 +67,17 @@ MACScheduler::MACScheduler() :
 {
 	LOG_TRACE_OBJ ("MACscheduler construction");
 
-#ifndef USE_PVSSPORT
-	LOG_WARN("Using GCFTCPPort in stead of GCFPVSSPort");
-#endif
-
 	// Readin some parameters from the ParameterSet.
 	itsOTDBpollInterval = globalParameterSet()->getTime("OTDBpollInterval");
 	itsQueuePeriod 		= globalParameterSet()->getTime("QueuePeriod");
 	itsClaimPeriod 		= globalParameterSet()->getTime("ClaimPeriod");
 
-	// get pointer to childcontrol task
+	// attach to child control task
 	itsChildControl = ChildControl::instance();
+	itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", 
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol");
+	itsChildPort->open();		// will result in F_CONNECTED
 }
 
 
@@ -164,17 +166,15 @@ void MACScheduler::handlePropertySetAnswer(GCFEvent& answer)
 //
 GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface& /*port*/)
 {
-	LOG_DEBUG ("MACScheduler::initial_state");
+	LOG_DEBUG_STR ("MACScheduler::initial_state:" << evtstr(event));
 
 	GCFEvent::TResult status = GCFEvent::HANDLED;
   
 	switch (event.signal) {
     case F_INIT:
-		LOG_TRACE_FLOW("initial_state:F_INIT");
    		break;
 
 	case F_ENTRY: {
-		LOG_TRACE_FLOW("initial_state:F_ENTRY");
 		// Get access to my own propertyset.
 		LOG_DEBUG ("Activating PropertySet");
 		itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(MS_PROPSET_NAME,
@@ -210,13 +210,14 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface&
 		// Start ChildControl task
 		LOG_DEBUG ("Enabling ChildControltask");
 		itsChildControl->openService(MAC_SVCMASK_SCHEDULERCTRL, 0);
+		itsChildControl->registerCompletionPort(itsChildPort);
 
 		// need port for timers(!)
 		itsDummyPort = new GCFTimerPort(*this, "MACScheduler:dummy4timers");
 		TRAN(MACScheduler::recover_state);				// go to next state.
 		}
 		break;
-#if 0
+
 	case F_CONNECTED:
 		break;
 
@@ -225,9 +226,9 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface&
 	
 	case F_TIMER:
 		break;
-#endif  
+  
 	default:
-		LOG_DEBUG_STR ("MACScheduler(" << getName() << ")::initial_state, default");
+		LOG_DEBUG ("MACScheduler::initial, default");
 		status = GCFEvent::NOT_HANDLED;
 		break;
 	}    
@@ -243,7 +244,8 @@ GCFEvent::TResult MACScheduler::initial_state(GCFEvent& event, GCFPortInterface&
 //
 GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface& port)
 {
-	LOG_DEBUG ("MACScheduler::recover_state");
+	LOG_DEBUG_STR ("MACScheduler::recover_state:" << evtstr(event)
+												  << "@" << port.getName());
 
 	GCFEvent::TResult status = GCFEvent::HANDLED;
 
@@ -265,7 +267,7 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface&
 	}
   
 	default:
-		LOG_DEBUG(formatString("MACScheduler(%s)::recover_state, default",getName().c_str()));
+		LOG_DEBUG("MACScheduler::recover_state, default");
 		status = GCFEvent::NOT_HANDLED;
 		break;
 	}    
@@ -280,7 +282,8 @@ GCFEvent::TResult MACScheduler::recover_state(GCFEvent& event, GCFPortInterface&
 //
 GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& port)
 {
-	LOG_DEBUG ("MACScheduler::active_state");
+	LOG_DEBUG_STR ("MACScheduler::active:" << evtstr(event)
+										   << "@" << port.getName());
 
 	GCFEvent::TResult status = GCFEvent::HANDLED;
 
@@ -335,21 +338,28 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface&
 		break;
 	}
 
-	case LOGICALDEVICE_SCHEDULED: {
-		LOGICALDEVICEScheduledEvent scheduledEvent(event);
-		// ...
+	case CONTROL_STARTED: {
+		CONTROLStartedEvent	msg(event);
+		if (msg.successful) {
+			LOG_DEBUG_STR("Start of " << msg.cntlrName << " was successful");
+		}
+		else {
+			LOG_ERROR_STR("Observation controller " << msg.cntlrName <<
+						" could n ot be started");
+		}
+		// TODO: do something usefull with this information!
 		break;
 	}
-
-	case LOGICALDEVICE_SCHEDULECANCELLED: {
-		LOGICALDEVICESchedulecancelledEvent schedulecancelledEvent(event);
+	case CONTROL_CONNECT: {
+		CONTROLConnectEvent conEvent(event);
+		LOG_DEBUG_STR("Received CONNECT(" << conEvent.cntlrName << ")");
 		// ...
 		break;
 	}
 
+
 	default:
-		LOG_DEBUG(formatString("MACScheduler(%s)::active_state, default",
-								getName().c_str()));
+		LOG_DEBUG("MACScheduler::active, default");
 		status = GCFEvent::NOT_HANDLED;
 		break;
 	}
@@ -395,7 +405,7 @@ void MACScheduler::_doOTDBcheck()
 		}
 
 		// get current state of Observation
-		string		cntlrName = formatString("ObsCntlr_%d", newTreeList[idx].treeID());
+		string		cntlrName = formatString("Observation_%d", newTreeList[idx].treeID());
 		LDState::LDstateNr	observationState = itsChildControl->getRequestedState(cntlrName);
 
 		// remember: timediff <= queueperiod
@@ -406,8 +416,8 @@ void MACScheduler::_doOTDBcheck()
 				OTDB::TreeMaintenance	tm(itsOTDBconnection);
 				OTDB::treeIDType		treeID = newTreeList[idx].treeID();
 				OTDBnode				topNode = tm.getTopNode(treeID);
-				string					filename = formatString("%s/Observation_%d", 
-														LOFAR_SHARE_LOCATION, treeID);
+				string					filename = string(LOFAR_SHARE_LOCATION) + 
+																	"/" + cntlrName;
 				if (!tm.exportTree(treeID, topNode.nodeID(), filename)) {
 					LOG_ERROR_STR ("Cannot create startup file " << filename << 
 								" for new observation. Observation CANNOT BE STARTED!");
@@ -415,9 +425,10 @@ void MACScheduler::_doOTDBcheck()
 				else {
 					// fire request for new controller
 					itsChildControl->startChild(cntlrName, 
-											treeID, 
-											LDTYPE_OBSERVATIONCTRL, 
-											myHostname());
+												treeID, 
+												CNTLRTYPE_OBSERVATIONCTRL, 
+												0,		// instanceNr
+												myHostname());
 				}
 				idx++;
 				continue;
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
index e29612d78dd9568757b7db80c6346a15c1851214..e313c12d5608f6a10f0635def61e9544572eb2ef 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
@@ -29,6 +29,7 @@
 //# GCF Includes
 #include <GCF/PAL/GCF_MyPropertySet.h>
 #include <GCF/TM/GCF_Port.h>
+#include <GCF/TM/GCF_ITCPort.h>
 #include <GCF/TM/GCF_TimerPort.h>
 #include <GCF/TM/GCF_Task.h>
 #include <GCF/TM/GCF_Event.h>
@@ -37,8 +38,7 @@
 #include "APL/APLCommon/PropertySetAnswerHandlerInterface.h"
 #include "APL/APLCommon/PropertySetAnswer.h"
 #include "APL/APLCommon/APLCommonExceptions.h"
-#include "APL/APLCommon/LogicalDevice_Protocol.ph"
-#include "APL/APLCommon/StartDaemon_Protocol.ph"
+#include "APL/APLCommon/Controller_Protocol.ph"
 
 //# Common Includes
 #include <Common/lofar_string.h>
@@ -59,6 +59,7 @@ namespace LOFAR {
 	namespace MainCU {
 
 using	GCF::TM::GCFTimerPort;
+using	GCF::TM::GCFITCPort;
 using	GCF::TM::GCFPort;
 using	GCF::TM::GCFEvent;
 using	GCF::TM::GCFPortInterface;
@@ -122,6 +123,7 @@ private:
 
 	// pointer to child control task
 	ChildControl*			itsChildControl;
+	GCFITCPort*				itsChildPort;
 
 	// Second timer used for internal timing.
 	uint32					itsSecondTimer;			// 1 second hardbeat
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in
index c5531d1e00011da09bbd1f0408e0963c1f008eca..e036dd6d88d3ffbc0f59762cac3f6eccfd00ff0b 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.log_prop.in
@@ -1,14 +1,14 @@
 # add your custom loggers and appenders here
 #
 
-log4cplus.rootLogger=DEBUG, STDOUT
+log4cplus.rootLogger=DEBUG, STDOUT, FILE
 
-log4cplus.logger.TRC=TRACE
+log4cplus.logger.TRC=TRACE2
 log4cplus.additivity.TRC=FALSE
 
 log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
 log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
-log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S} %-5p %c{9} - %m [%.25l]%n
+log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{9} - %m [%.25l]%n
 log4cplus.appender.STDOUT.logToStdErr=true
 
 log4cplus.appender.FILE=log4cplus::RollingFileAppender
@@ -16,15 +16,5 @@ log4cplus.appender.FILE.File=../log/MACScheduler.log
 log4cplus.appender.FILE.MaxFileSize=5MB
 log4cplus.appender.FILE.MaxBackupIndex=5
 log4cplus.appender.FILE.layout=log4cplus::PatternLayout
-log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n
+log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n
 
-log4cplus.appender.XMLFILE=log4cplus::RollingFileAppender
-log4cplus.appender.XMLFILE.File=../log/MACSchedulerlog.xml
-log4cplus.appender.XMLFILE.MaxFileSize=5MB
-log4cplus.appender.XMLFILE.MaxBackupIndex=5
-log4cplus.appender.XMLFILE.layout=log4cplus::XMLLayout
-
-log4cplus.appender.CHAINSAW=log4cplus::XMLSocketAppender
-log4cplus.appender.CHAINSAW.host=localhost
-log4cplus.appender.CHAINSAW.port=4448
-log4cplus.appender.CHAINSAW.layout=log4cplus::XMLLayout
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h
index fe9949ab65fa658c23d81d6c19c6a904c091a2b9..397840acb7d23e196ec006d626435b19b6c4c46f 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h
+++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerDefines.h
@@ -41,6 +41,9 @@ namespace LOFAR {
 #define PVSSNAME_FSM_STATE			"state"
 #define PVSSNAME_FSM_ERROR			"error"
 
+#define OC_PROPSET_NAME				"LOFAR_ObsSW_Observation%d"
+#define OC_PROPSET_TYPE				"Observation"
+
 }; // MCU
 }; // LOFAR
 
diff --git a/MAC/APL/MainCU/src/MACScheduler/Makefile.am b/MAC/APL/MainCU/src/MACScheduler/Makefile.am
index 1d22e68a2bd4ce2dc45a09452a8128d0271314fc..21d2cca60b487f065164ca11bf331f57520ad584 100644
--- a/MAC/APL/MainCU/src/MACScheduler/Makefile.am
+++ b/MAC/APL/MainCU/src/MACScheduler/Makefile.am
@@ -1,4 +1,4 @@
-bin_PROGRAMS 				= MACScheduler
+bin_PROGRAMS 				= MACScheduler ObservationControl
 
 MACScheduler_CPPFLAGS		= -DBOOST_DISABLE_THREADS \
 							  -Wno-deprecated \
@@ -8,16 +8,31 @@ MACScheduler_CPPFLAGS		= -DBOOST_DISABLE_THREADS \
 MACScheduler_SOURCES		= MACScheduler.cc \
 							  MACSchedulerMain.cc \
 							  ChildControl.cc \
-							  LDState.cc \
-							  Controller.cc
+							  LDState.cc
+							  ParentControl.cc
 
 MACScheduler_LDADD			= -lpqxx $(LOFAR_DEPEND)
 MACScheduler_DEPENDENCIES	= $(LOFAR_DEPEND)
 
+ObservationControl_CPPFLAGS		= -DBOOST_DISABLE_THREADS \
+								  -Wno-deprecated \
+								  -fmessage-length=0 \
+								  -fdiagnostics-show-location=once
+
+ObservationControl_SOURCES		= ObservationControl.cc \
+								  ObservationControlMain.cc \
+								  ChildControl.cc \
+								  LDState.cc\
+								  ParentControl.cc
+
+ObservationControl_LDADD		= $(LOFAR_DEPEND)
+ObservationControl_DEPENDENCIES	= $(LOFAR_DEPEND)
+
 NOINSTHDRS 					= MACScheduler.h \
 							  MACSchedulerDefines.h
 
 INSTHDRS 					= ChildControl.h \
+							  ParentControl.h \
 							  LDState.h
 
 pkginclude_HEADERS 			= $(NOINSTHDRS) $(INSTHDRS)
@@ -31,7 +46,9 @@ configfilesdir=$(bindir)
 configfiles_DATA 	= customPrepPVSSDB.ctl
 
 sysconf_DATA		= MACScheduler.conf \
-					  MACScheduler.log_prop
+					  MACScheduler.log_prop \
+					  ObservationControl.conf \
+					  ObservationControl.log_prop
 
 %.log_prop: %.log_prop.in
 	cp $< $@
diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4831f8772e6d515d208d7912c5be28e31a32bcbf
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.cc
@@ -0,0 +1,357 @@
+//#  ObservationControl.cc: Implementation of the MAC Scheduler task
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include <boost/shared_array.hpp>
+#include <APS/ParameterSet.h>
+#include <GCF/GCF_PVTypes.h>
+#include <GCF/PAL/GCF_PVSSInfo.h>
+#include <GCF/Utils.h>
+#include <GCF/GCF_ServiceInfo.h>
+#include <APL/APLCommon/APL_Defines.h>
+#include <APL/APLCommon/APLCommonExceptions.h>
+#include <APL/APLCommon/Controller_Protocol.ph>
+
+#include "ObservationControl.h"
+#include "MACSchedulerDefines.h"
+
+using namespace LOFAR::GCF::Common;
+using namespace LOFAR::GCF::TM;
+using namespace LOFAR::GCF::PAL;
+using namespace LOFAR::OTDB;
+using namespace std;
+
+namespace LOFAR {
+	using namespace APLCommon;
+	using namespace ACC::APS;
+	namespace MainCU {
+	
+//
+// ObservationControl()
+//
+ObservationControl::ObservationControl(const string&	cntlrName) :
+	GCFTask 			((State)&ObservationControl::initial_state,cntlrName),
+	PropertySetAnswerHandlerInterface(),
+	itsPropertySetAnswer(*this),
+	itsPropertySet		(),
+	itsChildControl		(0),
+	itsChildPort		(0),
+	itsParentControl	(0),
+	itsParentPort		(0)
+{
+	LOG_TRACE_OBJ_STR (cntlrName << " construction");
+
+	// Readin some parameters from the ParameterSet.
+	itsTreePrefix = globalParameterSet()->getString("prefix");
+	itsInstanceNr = globalParameterSet()->getUint32(itsTreePrefix + ".instanceNr");
+	itsStartTime  = globalParameterSet()->getTime  (itsTreePrefix + ".starttime");
+	itsStopTime   = globalParameterSet()->getTime  (itsTreePrefix + ".stoptime");
+
+	// attach to child control task
+	itsChildControl = ChildControl::instance();
+	itsChildPort = new GCFITCPort (*this, *itsChildControl, "childITCport", 
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for childcontrol");
+	itsChildPort->open();		// will result in F_CONNECTED
+
+	// attach to parent control task
+	itsParentControl = ParentControl::instance();
+	itsParentPort = new GCFITCPort (*this, *itsParentControl, "ParentITCport", 
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsChildPort, "Cannot allocate ITCport for Parentcontrol");
+	itsParentPort->open();		// will result in F_CONNECTED
+}
+
+
+//
+// ~ObservationControl()
+//
+ObservationControl::~ObservationControl()
+{
+	LOG_TRACE_OBJ_STR (getName() << " destruction");
+
+	if (itsPropertySet) {
+		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("down"));
+		itsPropertySet->disable();
+	}
+
+	// ...
+}
+
+
+//
+// handlePropertySetAnswer(answer)
+//
+void ObservationControl::handlePropertySetAnswer(GCFEvent& answer)
+{
+	switch(answer.signal) {
+	case F_MYPS_ENABLED: {
+		GCFPropSetAnswerEvent* pPropAnswer=static_cast<GCFPropSetAnswerEvent*>(&answer);
+		if(pPropAnswer->result != GCF_NO_ERROR) {
+			LOG_ERROR(formatString("%s : PropertySet %s NOT ENABLED",
+										getName().c_str(), pPropAnswer->pScope));
+		}
+		break;
+	}
+
+	case F_PS_CONFIGURED:
+	{
+		GCFConfAnswerEvent* pConfAnswer=static_cast<GCFConfAnswerEvent*>(&answer);
+		if(pConfAnswer->result == GCF_NO_ERROR) {
+			LOG_DEBUG(formatString("%s : apc %s Loaded",
+										getName().c_str(), pConfAnswer->pApcName));
+			//apcLoaded();
+		}
+		else {
+			LOG_ERROR(formatString("%s : apc %s NOT LOADED",
+										getName().c_str(), pConfAnswer->pApcName));
+		}
+		break;
+	}
+
+	case F_VGETRESP:
+	case F_VCHANGEMSG: {
+		// check which property changed
+		GCFPropValueEvent* pPropAnswer=static_cast<GCFPropValueEvent*>(&answer);
+
+		// TODO: implement something usefull.
+		// change of queueTime
+		if ((strstr(pPropAnswer->pPropName, MS_PROPSET_NAME) != 0) &&
+			(pPropAnswer->pValue->getType() == LPT_INTEGER)) {
+			uint32	newVal = (uint32) ((GCFPVInteger*)pPropAnswer->pValue)->getValue();
+#if 0
+			if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_QUEUEPERIOD) != 0) {
+				LOG_INFO_STR ("Changing QueuePeriod from " << itsQueuePeriod <<
+							  " to " << newVal);
+				itsQueuePeriod = newVal;
+			}
+			else if (strstr(pPropAnswer->pPropName, PVSSNAME_MS_CLAIMPERIOD) != 0) {
+				LOG_INFO_STR ("Changing ClaimPeriod from " << itsClaimPeriod <<
+							  " to " << newVal);
+				itsClaimPeriod = newVal;
+			}
+#endif
+		}
+		break;
+	}  
+
+	default:
+		break;
+	}  
+}
+
+
+//
+// initial_state(event, port)
+//
+// Setup all connections.
+//
+GCFEvent::TResult ObservationControl::initial_state(GCFEvent& event, GCFPortInterface& /*port*/)
+{
+	LOG_DEBUG_STR ("ObservationControl::initial:" << evtstr(event));
+
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+  
+	switch (event.signal) {
+    case F_INIT:
+   		break;
+
+	case F_ENTRY: {
+		// Get access to my own propertyset.
+		LOG_DEBUG ("Activating PropertySet");
+		string	propSetName = formatString(OC_PROPSET_NAME, itsInstanceNr);
+		itsPropertySet = GCFMyPropertySetPtr(new GCFMyPropertySet(propSetName.c_str(),
+																  OC_PROPSET_TYPE,
+																  PS_CAT_TEMPORARY,
+																  &itsPropertySetAnswer));
+		itsPropertySet->enable();
+	  
+		// update PVSS.
+		LOG_TRACE_FLOW ("Updateing state to PVSS");
+		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString  ("initial"));
+		itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString  (""));
+      
+		// Start ChildControl task
+		LOG_DEBUG ("Enabling ChildControl task");
+		itsChildControl->openService(MAC_SVCMASK_OBSERVATIONCTRL, itsInstanceNr);
+		itsChildControl->registerCompletionPort(itsChildPort);
+
+		// Start ParentControl task
+		LOG_DEBUG ("Enabling ParentControl task");
+		itsParentPort = itsParentControl->registerTask(this);
+
+		TRAN(ObservationControl::active_state);				// go to next state.
+		}
+		break;
+
+	case F_CONNECTED:
+		break;
+
+	case F_DISCONNECTED:
+		break;
+	
+	case F_TIMER:
+		break;
+  
+	default:
+		LOG_DEBUG_STR ("ObservationControl::initial, default");
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}    
+	return (status);
+}
+
+
+//
+// active_state(event, port)
+//
+// Normal operation state. 
+//
+GCFEvent::TResult ObservationControl::active_state(GCFEvent& event, GCFPortInterface& port)
+{
+	LOG_DEBUG_STR ("ObservationControl::active:" << evtstr(event) 
+												 << "@" << port.getName());
+
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+
+	switch (event.signal) {
+	case F_INIT:
+		break;
+
+	case F_ENTRY: {
+		// update PVSS
+		itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active"));
+		itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString(""));
+		break;
+	}
+
+	case F_ACCEPT_REQ:
+		break;
+
+	case F_CONNECTED:	
+		_connectedHandler(port);
+		break;
+
+	case F_DISCONNECTED:	
+		_disconnectedHandler(port);
+		break;
+
+	case F_TIMER: 
+//		GCFTimerEvent& timerEvent=static_cast<GCFTimerEvent&>(event);
+		break;
+
+	// -------------------- EVENT RECEIVED FROM CHILD CONTROL --------------------
+	case CONTROL_STARTED: {
+		CONTROLStartedEvent	msg(event);
+		LOG_DEBUG(formatString("Start of %s was %ssuccessful", msg.cntlrName.c_str(), 
+						msg.successful ? "" : "NOT "));
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_CONNECT: {
+		CONTROLConnectEvent		msg(event);
+		LOG_DEBUG_STR("Received CONNECT(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_SCHEDULED: {
+		CONTROLScheduledEvent		msg(event);
+		LOG_DEBUG_STR("Received SCHEDULED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_CLAIMED: {
+		CONTROLClaimedEvent		msg(event);
+		LOG_DEBUG_STR("Received CLAIMED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_PREPARED: {
+		CONTROLPreparedEvent		msg(event);
+		LOG_DEBUG_STR("Received PREPARED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_RESUMED: {
+		CONTROLResumedEvent		msg(event);
+		LOG_DEBUG_STR("Received RESUMED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_SUSPENDED: {
+		CONTROLSuspendedEvent		msg(event);
+		LOG_DEBUG_STR("Received SUSPENDED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_RELEASED: {
+		CONTROLReleasedEvent		msg(event);
+		LOG_DEBUG_STR("Received RELEASED(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+	case CONTROL_FINISH: {
+		CONTROLFinishEvent		msg(event);
+		LOG_DEBUG_STR("Received FINISH(" << msg.cntlrName << ")");
+		// TODO: do something usefull with this information!
+		break;
+	}
+
+
+	default:
+		LOG_DEBUG(formatString("ObservationControl(%s)::active_state, default",
+								getName().c_str()));
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}
+
+	return (status);
+}
+
+
+//
+// _connectedHandler(port)
+//
+void ObservationControl::_connectedHandler(GCFPortInterface& port)
+{
+}
+
+//
+// _disconnectedHandler(port)
+//
+void ObservationControl::_disconnectedHandler(GCFPortInterface& port)
+{
+	port.close();
+}
+
+
+};
+};
diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in
new file mode 100644
index 0000000000000000000000000000000000000000..a92957c18ce62d80f87bec0b8500f109d6a9d311
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.conf.in
@@ -0,0 +1,11 @@
+# new setup
+prefix	=	Observation0
+
+Observation0.instanceNr = 0
+Observation0.starttime	= 0
+Observation0.stoptime	= 1
+
+# next parameters are optional, defaultvalues are shown
+#ChildControl.StartupRetryInterval = 10s
+#ChildControl.MaxStartupRetry	   = 5
+
diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h
new file mode 100644
index 0000000000000000000000000000000000000000..6169b8cd624ecaf55637bcd8baf96d998f1a48b9
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.h
@@ -0,0 +1,131 @@
+//#  ObservationControl.h: Interface between MAC and SAS.
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef ObservationControl_H
+#define ObservationControl_H
+
+//# Includes
+#include <boost/shared_ptr.hpp>
+
+//# GCF Includes
+#include <GCF/PAL/GCF_MyPropertySet.h>
+#include <GCF/TM/GCF_Port.h>
+#include <GCF/TM/GCF_ITCPort.h>
+#include <GCF/TM/GCF_TimerPort.h>
+#include <GCF/TM/GCF_Task.h>
+#include <GCF/TM/GCF_Event.h>
+
+//# local includes
+#include "APL/APLCommon/PropertySetAnswerHandlerInterface.h"
+#include "APL/APLCommon/PropertySetAnswer.h"
+#include "APL/APLCommon/APLCommonExceptions.h"
+#include "APL/APLCommon/Controller_Protocol.ph"
+
+//# Common Includes
+#include <Common/lofar_string.h>
+#include <Common/lofar_vector.h>
+#include <Common/LofarLogger.h>
+
+//# ACC Includes
+#include <APS/ParameterSet.h>
+#include "ChildControl.h"
+#include "ParentControl.h"
+#include "LDState.h"
+
+// forward declaration
+
+namespace LOFAR {
+	namespace MainCU {
+
+using	GCF::TM::GCFTimerPort;
+using	GCF::TM::GCFITCPort;
+using	GCF::TM::GCFPort;
+using	GCF::TM::GCFEvent;
+using	GCF::TM::GCFPortInterface;
+using	GCF::TM::GCFTask;
+
+
+class ObservationControl : public GCFTask,
+						   APLCommon::PropertySetAnswerHandlerInterface
+{
+public:
+	explicit ObservationControl(const string& cntlrName);
+	~ObservationControl();
+
+   	// PropertySetAnswerHandlerInterface method
+   	virtual void handlePropertySetAnswer(GCFEvent& answer);
+
+	// During the initial state all connections with the other programs are made.
+   	GCFEvent::TResult initial_state (GCFEvent& e, 
+									 GCFPortInterface& p);
+	
+	// Normal control mode. 
+   	GCFEvent::TResult active_state  (GCFEvent& e, 
+									 GCFPortInterface& p);
+
+private:
+	// avoid defaultconstruction and copying
+	ObservationControl();
+	ObservationControl(const ObservationControl&);
+   	ObservationControl& operator=(const ObservationControl&);
+
+   	void _connectedHandler(GCFPortInterface& port);
+   	void _disconnectedHandler(GCFPortInterface& port);
+   	boost::shared_ptr<ACC::APS::ParameterSet> 
+		 readObservationParameters (OTDB::treeIDType	ObsTreeID);
+
+   	typedef boost::shared_ptr<GCF::PAL::GCFMyPropertySet> GCFMyPropertySetPtr;
+
+   	APLCommon::PropertySetAnswer  itsPropertySetAnswer;
+   	GCFMyPropertySetPtr           itsPropertySet;
+
+#if 0
+	// Administration of the ObservationControllers
+	typedef struct {
+		OTDB::treeIDType	treeID;		// tree in the OTDB
+		GCFTCPPort*			port;		// TCP connection with controller
+		uint16				state;		// state the controller has
+	} ObsCntlr_t;
+
+	// Map with all active ObservationControllers.
+	map<GCFTCPPort*, ObsCntlr_t>	itsObsCntlrMap;
+	vector<GCFTCPPort*>				itsObsCntlrPorts;
+#endif
+
+	// pointer to child control task
+	ChildControl*			itsChildControl;
+	GCFITCPort*				itsChildPort;
+
+	// pointer to parent control task
+	ParentControl*			itsParentControl;
+	GCFITCPort*				itsParentPort;
+
+	// ParameterSet variables
+	string					itsTreePrefix;
+	uint32					itsInstanceNr;
+	time_t					itsStartTime;
+	time_t					itsStopTime;
+};
+
+  };//MainCU
+};//LOFAR
+#endif
diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in
new file mode 100644
index 0000000000000000000000000000000000000000..014e32162d939ee0cd2716348fc1e2e9117c10ad
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ObservationControl.log_prop.in
@@ -0,0 +1,20 @@
+# add your custom loggers and appenders here
+#
+
+log4cplus.rootLogger=DEBUG, STDOUT, FILE
+
+log4cplus.logger.TRC=TRACE2
+log4cplus.additivity.TRC=FALSE
+
+log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
+log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
+log4cplus.appender.STDOUT.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{9} - %m [%.25l]%n
+log4cplus.appender.STDOUT.logToStdErr=true
+
+log4cplus.appender.FILE=log4cplus::RollingFileAppender
+log4cplus.appender.FILE.File=../log/ObservationControl.log
+log4cplus.appender.FILE.MaxFileSize=5MB
+log4cplus.appender.FILE.MaxBackupIndex=5
+log4cplus.appender.FILE.layout=log4cplus::PatternLayout
+log4cplus.appender.FILE.layout.ConversionPattern=%x %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%.25l]%n
+
diff --git a/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc b/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc
new file mode 100644
index 0000000000000000000000000000000000000000..085868055868317950b9ed1314587ae9e46717eb
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ObservationControlMain.cc
@@ -0,0 +1,49 @@
+//#  ObservationControlMain.cc: Main entry for the ObservationControl controller.
+//#
+//#  Copyright (C) 2006
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+//#
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include "ObservationControl.h"
+
+using namespace LOFAR::GCF::TM;
+using namespace LOFAR::MainCU;
+
+int main(int argc, char* argv[])
+{
+	// args: cntlrname, parentHost, parentService
+	GCFTask::init(argc, argv);
+
+	ChildControl*	cc = ChildControl::instance();
+	cc->start();	// make initial transition
+
+	ParentControl*	pc = ParentControl::instance();
+	pc->start();	// make initial transition
+
+	ObservationControl	oc(argv[1]);
+	oc.start(); // make initial transition
+
+	GCFTask::run();
+
+	return 0;
+}
+
diff --git a/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc b/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7dc67f2a7c6721d7ef82304fbdf86e62ec5db172
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ParentControl.cc
@@ -0,0 +1,572 @@
+//#  ParentControl.cc: Task that handles and dispatches all controllers events.
+//#
+//#  Copyright (C) 2006
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <APS/ParameterSet.h>
+#include <MainCU/MACScheduler/ParentControl.h>
+#include <GCF/GCF_ServiceInfo.h>
+#include <GCF/Utils.h>
+#include <APL/APLCommon/APLUtilities.h>
+#include <APL/APLCommon/Controller_Protocol.ph>
+#include <APL/APLCommon/StartDaemon_Protocol.ph>
+#include "ParentControl.h"
+
+namespace LOFAR {
+  using namespace GCF::TM;
+  using namespace APLCommon;
+  using namespace ACC::APS;
+  namespace MainCU {
+
+typedef struct stateFlow_t {
+	uint16				signal;
+	LDState::LDstateNr	currentState;
+	LDState::LDstateNr	requestedState;
+} stateFlow;
+
+static	stateFlow	stateFlowTable[] = {
+//		received signal			expected in state		requested state
+//		------------------------------------------------------------------
+	{	CONTROL_CONNECTED,		LDState::CONNECT,		LDState::CONNECTED	},
+	{	CONTROL_CLAIM,			LDState::CONNECTED,		LDState::CLAIMED	},
+	{	CONTROL_PREPARE,		LDState::CLAIMED,		LDState::PREPARED	},
+	{	CONTROL_RESUME,			LDState::PREPARED,		LDState::ACTIVE		},
+	{	CONTROL_RESUME,			LDState::SUSPENDED,		LDState::ACTIVE		},
+	{	CONTROL_SUSPEND,		LDState::ACTIVE,		LDState::SUSPENDED	},
+	{	CONTROL_RELEASE,		LDState::ANYSTATE,		LDState::RELEASED	},
+	{	CONTROL_FINISHED,		LDState::FINISH,		LDState::FINISHED	},
+	{	0x00,					LDState::NOSTATE,		LDState::NOSTATE	}
+};
+
+//-------------------------- creation and destroy ---------------------------
+
+ParentControl* ParentControl::instance()
+{
+	static	ParentControl*		theirParentControl;
+
+	if (theirParentControl == 0) {
+		theirParentControl = new ParentControl();
+	}
+	return (theirParentControl);
+}
+
+
+//
+// ParentControl(name, porenthost, parentService))
+//
+ParentControl::ParentControl() :
+	GCFTask			 ((State)&ParentControl::initial, "ParentControl"),
+	itsParentList	 (),
+	itsSDPort		 (0),
+	itsMainTaskPort  (0),
+	itsTimerPort	 (*this, "parentControlTimer"),
+	itsControllerName()
+{
+	// Log the protocols I use.
+	registerProtocol(CONTROLLER_PROTOCOL,  CONTROLLER_PROTOCOL_signalnames);
+	registerProtocol(STARTDAEMON_PROTOCOL, STARTDAEMON_PROTOCOL_signalnames);
+
+}
+
+//
+// ~ParentControl
+//
+ParentControl::~ParentControl()
+{
+	// close and delete the ports I created
+	if (itsMainTaskPort) {
+		itsMainTaskPort->close();
+		delete itsMainTaskPort;
+	}
+
+	if (itsSDPort) {
+		itsSDPort->close();
+		delete itsSDPort;
+	}
+}
+
+//
+// registerTask(mainTask) : ITCPort
+//
+GCFITCPort*	ParentControl::registerTask(GCFTask*		mainTask)
+{
+	itsMainTaskPort = new GCFITCPort(*mainTask, *this, mainTask->getName(), 
+										GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+	ASSERTSTR(itsMainTaskPort, "Can not allocate ITC port for parent-control");
+	itsMainTaskPort->open();		// will result in F_CONN signal
+
+	itsSDPort = new GCFTCPPort(*this, MAC_SVCMASK_STARTDAEMON, 
+										GCFPortInterface::SAP, STARTDAEMON_PROTOCOL);
+	ASSERTSTR(itsSDPort, "Can not allocate clientport to startDaemon");
+	itsSDPort->open();				// will result in F_COON or F_DISCONN signal
+
+	itsControllerName = mainTask->getName();		// remember for later
+
+	return (itsMainTaskPort);
+}
+
+//
+// isLegalSignal(signal, parent)
+//
+bool ParentControl::isLegalSignal(uint16	aSignal,
+							   PIiter	aParent)
+{
+	uint32	i = 0;
+	while (stateFlowTable[i].signal) {
+		if (stateFlowTable[i].signal == aSignal && 
+			(stateFlowTable[i].currentState == aParent->currentState ||
+			 stateFlowTable[i].currentState == LDState::ANYSTATE)) {
+			return (true);
+		}
+		i++;
+	}
+	return (false);
+}
+
+//
+// requestedState(signal)
+//
+LDState::LDstateNr ParentControl::requestedState(uint16	aSignal)
+{
+	uint32	i = 0;
+	while (stateFlowTable[i].signal) {
+		if (stateFlowTable[i].signal == aSignal) {
+			return (stateFlowTable[i].requestedState);
+		}
+		i++;
+	}
+	ASSERTSTR(false, "No new state defined for signal " << evtstr(aSignal));
+}
+
+//
+// doRequestedAction(parent)
+//
+void ParentControl::doRequestedAction(PIiter	parent)
+{
+	LOG_TRACE_FLOW_STR("doRequestedAction:" << parent->name);
+
+	// state alredy reached? make sure the timer is off.
+	if (parent->requestedState == parent->currentState) {
+		parent->nrRetries = -1;
+		itsTimerPort.cancelTimer(parent->timerID);
+		parent->timerID = 0;
+		return;
+	}
+
+	switch (parent->requestedState) {
+	case LDState::CONNECTED: {
+			// try to make first contact with parent by identifying ourself
+			if (parent->nrRetries == 0) {	// no more retries left?
+				LOG_ERROR_STR("Cannot connect to parent: " << parent->servicename <<
+							"@" << parent->hostname << ", giving up!");
+				parent->establishTime = time(0);
+				parent->failed = true;		// TODO:let garbage collection remove this entry.
+				return;
+			}
+			// Note: when required state == CONNECTED there are two possibilities:
+			// current state == NOSTATE: CONNECT msg was sent to main task, do nothing
+			// current state == CONNECT: CONNECTED msg was received from main task,
+			//							 send CONNECT msg to parent-controller.
+			if (parent->currentState == LDState::NOSTATE) {
+				return;
+			}
+
+			ASSERTSTR(parent->currentState == LDState::CONNECT, 
+								"Unexpected state:" << parent->currentState);
+
+			// construct and send message
+			CONTROLConnectEvent		hello;
+			hello.cntlrName = parent->name;
+			parent->port->send(hello);
+			parent->timerID 	  = 0;
+			parent->nrRetries 	  = -1;
+			parent->currentState  = LDState::CONNECT;
+			parent->establishTime = time(0);
+		}
+		break;
+	case LDState::CLAIMED: {
+			CONTROLClaimEvent	request;
+			request.cntlrName = parent->name;
+			itsMainTaskPort->sendBack(request);
+		}
+		break;
+	case LDState::PREPARED:
+//		concrete_prepare(parent);
+		break;
+	case LDState::ACTIVE:
+//		concrete_resume(parent);
+		break;
+	case LDState::SUSPENDED:
+//		concrete_suspend(parent);
+		break;
+	case LDState::RELEASED:
+//		concrete_release(parent);
+		break;
+	case LDState::FINISHED:
+		parent->port->close();
+		itsParentList.erase(parent);
+		break;
+	default:
+		ASSERTSTR(false, "Serious programming error, requestedState=" << 
+					parent->requestedState << " for task " << parent->name);
+	}
+
+}
+
+
+// -------------------- THE GCF STATEMACHINES --------------------
+
+// Wait for the F_CONNECTED event from the ITC port with the master-task.
+// Connect and register at startDaemon
+//
+GCFEvent::TResult	ParentControl::initial(GCFEvent&			event, 
+										   GCFPortInterface&	port)
+
+{
+	LOG_DEBUG_STR ("ParentControl::initial:" << evtstr(event)
+											 << "@" << port.getName());
+
+	GCFEvent::TResult	status = GCFEvent::HANDLED;
+
+	switch (event.signal) {
+	case F_INIT:
+	case F_ENTRY:
+		break;
+
+	case F_CONNECTED:
+		if (&port == itsMainTaskPort) {		// ITC port with parent open?
+			LOG_DEBUG("Connection with maintask opened");
+		}
+		if (&port == itsSDPort) {
+			STARTDAEMONAnnouncementEvent	msg;
+			msg.cntlrName = itsControllerName;
+			itsSDPort->send(msg);
+
+			LOG_DEBUG_STR("Registered at startdaemon as " << itsControllerName
+						<< 	", going to operation mode");
+			TRAN(ParentControl::operational);
+		}
+		break;
+
+	case F_DISCONNECTED:
+		if (&port == itsSDPort) {
+			port.close();
+			itsTimerPort.setTimer(1.0);
+			LOG_DEBUG("Could not connect to startDaemon, retry in 1 second");
+		}
+		break;
+
+	case F_TIMER:
+		// must be reconnect timer for startDaemon
+		itsSDPort->open();
+		break;
+
+	default:
+		LOG_DEBUG ("ParentControl::initial, default");
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}
+
+	return (status);
+}
+
+
+//
+// operational (event, port)
+//
+// Since this base class is also used for shared controllers the controller supports
+// multiple parents. For each of these parents the controller plays the role of
+// stand-alone controller having a certain state and allowing certain actions.
+// It is therefor difficult to implement multiple statemachine since the controller
+// should be in a (different) state for each parent.
+//
+GCFEvent::TResult	ParentControl::operational(GCFEvent&			event, 
+											   GCFPortInterface&	port)
+
+{
+	LOG_DEBUG_STR ("ParentControl::operational:" << evtstr(event) 
+												 << "@" << port.getName());
+
+	GCFEvent::TResult	status = GCFEvent::HANDLED;
+
+	switch (event.signal) {
+	case F_INIT:
+		break;
+
+	case F_ENTRY:
+		break;
+
+	case F_ACCEPT_REQ:	// will not occur, using SPP port for startDaemon
+		break;
+
+	case F_CONNECTED: {
+			// search which connection is succesfull connected.
+			PIiter		parent = findParent(&port);
+			if (isParent(parent)) {
+				// TODO: should we send an 'alive' msg to our parent
+				// so that recovered(?) parent knows we are still running?
+				// CHECK: is servicemask resolved at each open()?
+
+				// contact with parent is (re)made
+				doRequestedAction(parent);
+			}
+			else {
+				LOG_DEBUG("F_CONNECTED on non-parent port");
+			}
+		}
+		break;
+
+	case F_DISCONNECTED: {
+			// StartDaemonPort? no problem SD will reconnect when neccesary.
+			if (&port == itsSDPort) {
+				port.close();			// close connection with current SD
+				port.open();			// start listener again
+				break;
+			}
+
+			// Parent port? Might be temporarely problem, try to reconnect for a while.
+			PIiter	parent = findParent(&port);
+			if (isParent(parent)) {
+				// trying to make first contact?
+				if (parent->requestedState == LDState::CONNECTED &&
+									parent->currentState != LDState::CONNECTED) {
+					// try again in one second.
+					parent->port->close();
+					parent->timerID = itsTimerPort.setTimer(1.0);
+					if (parent->nrRetries < 0) {
+						parent->nrRetries = 30;
+						LOG_WARN_STR ("Lost connection with new parent " << parent->name <<
+									  ", starting reconnect sequence");
+					}
+					LOG_TRACE_VAR_STR("parent:" << parent->name << ", timerID:" 
+												<< parent->timerID);
+					break;
+				}
+				
+				// lost connection during normal operation, start reconnect sequence
+				parent->port->close();
+				parent->timerID   = itsTimerPort.setTimer(10.0);// retry every 10 seconds
+				if (parent->nrRetries < 0) {
+					parent->nrRetries = 360;						// for 1 hour
+					LOG_WARN_STR ("Lost connection with parent " << parent->name <<
+								  ", starting reconnect sequence");
+				}
+				LOG_TRACE_VAR_STR("parent:" << parent->name << ", timerID:" 
+											<< parent->timerID);
+				break;
+			} 
+
+			// unknown port. just close it.
+			LOG_INFO ("Lost connection with unknown port, closing it");
+			port.close();
+		}
+		break;
+
+	case F_TIMER: {
+			GCFTimerEvent&		timerEvent = static_cast<GCFTimerEvent&>(event);
+			LOG_TRACE_VAR_STR("timerID:" << timerEvent.id);
+			PIiter				parent = findParent(timerEvent.id);
+			if (!isParent(parent)) {
+				LOG_DEBUG ("timerevent is not of a known parent, ignore");
+				break;
+			}
+
+			if (parent->port->isConnected()) {		// not the reconnect timer?
+				doRequestedAction(parent);
+			}
+
+			// its the reconnect timer of this parent.
+			if (parent->nrRetries > 0) {
+				parent->port->open();
+				parent->nrRetries--;
+				parent->timerID = 0;
+				if (!parent->nrRetries%60) {
+					LOG_WARN_STR ("Still no connection with parent " << parent->name);
+				}
+			}
+			else {
+				LOG_WARN_STR ("Could not reconnect to parent " << 
+							parent->name << ", deleting entry");
+//					concrete_release(parent);
+				itsParentList.erase(parent);
+			}
+		}
+		break;
+
+	case STARTDAEMON_NEWPARENT: {
+		// a new parent wants us to connect to it, read info.
+		STARTDAEMONNewparentEvent	NPevent(event);
+		ParentInfo_t				parent;
+
+		// construct the state information the parent think we have.
+		parent.name 		  = NPevent.cntlrName;
+		parent.port			  = new GCFTCPPort(*this, NPevent.parentService,
+									GCFPortInterface::SAP, CONTROLLER_PROTOCOL);
+		parent.hostname 	  = NPevent.parentHost;
+		parent.servicename 	  = NPevent.parentService;
+		parent.requestedState = LDState::CONNECTED;
+		parent.requestTime 	  = time(0);
+		parent.currentState   = LDState::NOSTATE;
+		parent.establishTime  = 0;
+		parent.timerID	 	  = 0;
+		parent.nrRetries 	  = -1;	// means: not set
+		ASSERTSTR(parent.port, "Unable to allocate socket for " << NPevent.cntlrName);
+
+		// add parent to the pool and open the connection with the parent
+		itsParentList.push_back(parent);
+		dynamic_cast<GCFTCPPort*>(parent.port)->setHostName (parent.hostname);
+		parent.port->open();		// results in F_CONN of F_DISCONN
+		LOG_DEBUG_STR("Registered parent "<< parent.name <<" on port "<< parent.port);
+
+		// pass newParent event to mainTask as Connect event
+		LOG_DEBUG_STR("Sending CONNECT(" << parent.name << ") event to maintask");
+		CONTROLConnectEvent		request;
+		request.cntlrName = parent.name;
+		itsMainTaskPort->sendBack(request);
+		}
+		break;
+
+	case CONTROL_CONNECTED: {
+		// this event can be received from maintask and parent-controllers
+		// is it the maintask? --> send CONNECT to parent controller.
+		if (&port == itsMainTaskPort) {
+			CONTROLConnectedEvent	inMsg(event);
+			PIiter	parent = findParent(inMsg.cntlrName);
+			if (!isParent(parent)) {
+				LOG_ERROR_STR("Cannot forward CONNECT event for " << inMsg.cntlrName);
+				break;
+			}
+			CONTROLConnectEvent	outMsg;
+			outMsg.cntlrName = inMsg.cntlrName;
+			parent->port->send(outMsg);
+			parent->currentState = LDState::CONNECT;
+			break;
+		}
+				
+		// should be a parentport
+		PIiter		parent = findParent(&port);
+		if (!isParent(parent)) {
+			LOG_WARN_STR ("Received CONNECTED event from unknown parent, ignoring");
+			break;
+		}
+
+		// warn operator when we are out of sync with our parent.
+		if (parent->requestedState != LDState::CONNECTED) {
+			LOG_WARN_STR ("Received 'CONNECTED' event while requested state is " <<
+						parent->requestedState);
+		}
+		// always accept new state because parent thinks we are in this state.
+		// TODO: when we are already beyond the claiming state should we release
+		//		 the claimed resources?
+		parent->port->cancelTimer(parent->timerID);
+		parent->timerID 	  = 0;
+		parent->currentState  = LDState::CONNECTED;
+		parent->establishTime = time(0);
+		parent->timerID		  = 0;
+		parent->nrRetries 	  = -1;
+		parent->failed 	 	  = false;
+		}
+		break;
+
+	case CONTROL_CLAIM:
+	case CONTROL_PREPARE:
+	case CONTROL_RESUME:
+	case CONTROL_SUSPEND:
+	case CONTROL_RELEASE:
+	case CONTROL_FINISHED:
+		{
+			// do we know this parent?
+			PIiter		parent = findParent(&port);
+			if (isParent(parent)) {
+				LOG_WARN_STR ("Received " << evtstr(event) << 
+								" event from unknown parent, ignoring");
+				break;
+			}
+
+			// warn operator when we are out of sync with our parent.
+			if (!isLegalSignal(event.signal, parent)) {
+				LOG_WARN_STR ("Received " << evtstr(event.signal) <<
+							" event while requested state is " << parent->requestedState);
+			}
+
+			parent->requestedState = requestedState(event.signal);	// use stateFlowTable
+			parent->requestTime	   = time(0);
+			doRequestedAction(parent);
+		}
+		break;
+
+	default:
+		LOG_DEBUG ("ParentControl::operational, default");
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}
+
+	return (status);
+}
+
+//
+// findParent(port)
+//
+ParentControl::PIiter	ParentControl::findParent(GCFPortInterface*	aPort)
+{
+	LOG_TRACE_COND_STR("findParent: " << aPort);
+	const_PIiter	end  = itsParentList.end();
+	PIiter			iter = itsParentList.begin();
+	while (iter != end && iter->port != aPort) {
+		iter++;	
+	}
+	return (iter);
+}
+
+//
+// findParent(timerID)
+//
+ParentControl::PIiter	ParentControl::findParent(uint32	aTimerID)
+{
+	LOG_TRACE_COND_STR("findParent: " << aTimerID);
+	const_PIiter	end  = itsParentList.end();
+	PIiter			iter = itsParentList.begin();
+	while (iter != end && iter->timerID != aTimerID) {
+		iter++;	
+	}
+	return (iter);
+}
+
+//
+// findParent(name)
+//
+ParentControl::PIiter	ParentControl::findParent(const string&		aName)
+{
+	LOG_TRACE_COND_STR("findParent: " << aName);
+	const_PIiter	end  = itsParentList.end();
+	PIiter			iter = itsParentList.begin();
+	while (iter != end && iter->name != aName) {
+		iter++;	
+	}
+	return (iter);
+}
+
+  } // namespace MainCU
+} // namespace LOFAR
diff --git a/MAC/APL/MainCU/src/MACScheduler/ParentControl.h b/MAC/APL/MainCU/src/MACScheduler/ParentControl.h
new file mode 100644
index 0000000000000000000000000000000000000000..33c7c33700e8f9386e357c69136b0ef1a950aaab
--- /dev/null
+++ b/MAC/APL/MainCU/src/MACScheduler/ParentControl.h
@@ -0,0 +1,148 @@
+//#  ParentControl.h: Task that handles and dispatches all controllers events.
+//#
+//#  Copyright (C) 2006
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef MAINCU_CONTROLLER_H
+#define MAINCU_CONTROLLER_H
+
+// \file
+// Task that handles and dispatches all controllers events.
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <Common/lofar_string.h>
+#include <Common/lofar_map.h>
+#include <Common/lofar_list.h>
+#include <GCF/TM/GCF_Task.h>
+#include <GCF/TM/GCF_TCPPort.h>
+#include <GCF/TM/GCF_ITCPort.h>
+#include <GCF/TM/GCF_TimerPort.h>
+#include <APL/APLCommon/APL_Defines.h>
+#include <OTDB/OTDBtypes.h>
+#include "LDState.h"
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  using GCF::TM::GCFTCPPort;
+  using GCF::TM::GCFITCPort;
+  using GCF::TM::GCFTimerPort;
+  using GCF::TM::GCFEvent;
+  using GCF::TM::GCFTask;
+  using GCF::TM::GCFPortInterface;
+  using APLCommon::LDState;
+  namespace MainCU {
+
+// \addtogroup MainCU
+// @{
+
+//# --- Forward Declarations ---
+//# classes mentioned as parameter or returntype without virtual functions.
+//class ...;
+
+
+// class_description
+// ...
+class ParentControl : public GCFTask
+{
+public:
+	// the only way to create the object is via instance.
+	static ParentControl*	instance();
+	~ParentControl();
+
+	// Main controller task should identify itself at ParentControlTask.
+	// Its gets an ITCport pointer in return.
+	GCFITCPort* registerTask (GCFTask*			mainTask);
+
+private:
+	// Copying and default construction is not allowed
+	ParentControl();
+	ParentControl(const ParentControl&	that);
+	ParentControl& operator=(const ParentControl& that);
+
+	// GCFTask statemachine
+	GCFEvent::TResult	initial		(GCFEvent&	event, GCFPortInterface&	port);
+	GCFEvent::TResult	operational	(GCFEvent&	event, GCFPortInterface&	port);
+
+
+	// Note: When the controller is a shared controller it will have multiple
+	//		 parents and for each of these parents it must handle its own
+	//		 state machine.
+	typedef struct ParentInfo {
+		string				name;			// uniq name we have for the parent
+		GCFPortInterface*	port;			// connection with the parent
+		string				hostname;		// host the controller runs on
+		string				servicename;	// servicename to connect to
+		LDState::LDstateNr	requestedState;	// the state the controller requested
+		time_t				requestTime;	// time of requested state
+		LDState::LDstateNr	currentState;	// the state we reached for that parent
+		time_t				establishTime;	// time the current state was reached
+		int32				nrRetries;		// nr of retries performed
+		uint32				timerID;		// timer for this parent
+		bool				failed;			// reaching requested state failed.
+	} ParentInfo_t;
+	typedef list<ParentInfo_t>::iterator		PIiter;
+	typedef list<ParentInfo_t>::const_iterator	const_PIiter;
+
+	// internal routines for managing the ParentInfo pool.
+	PIiter	findParent(GCFPortInterface*	port);
+	PIiter	findParent(uint32				timerID);
+	PIiter	findParent(const string&		name);
+	bool	isParent  (PIiter				parentPtr) 
+	{	return (parentPtr != itsParentList.end());	}
+	bool 				isLegalSignal (uint16	aSignal, PIiter	aParent);
+	LDState::LDstateNr	requestedState(uint16	aSignal);
+
+	// Internal routines
+	void doRequestedAction(PIiter	parent);
+
+
+	//# --- Datamembers ---
+	list<ParentInfo_t>			itsParentList;		// administration of child controller
+
+	GCFTCPPort*					itsSDPort;			// clientport to StartDaemon
+
+	GCFITCPort*					itsMainTaskPort;	// gateway to main task
+
+	GCFTimerPort				itsTimerPort;		// for internal timers
+
+	string						itsServiceName;		// serviceinfo of program
+	uint32						itsInstanceNr;
+
+	string						itsControllerName;	// name to program is known as
+
+	// All actions from the parent task are queued as ParentControlInfo objects
+	// and handled in the operational stateMachine.
+//	list<ParentControlInfo>		itsActionList;		// list of actions to perform.
+//	uint32						itsActionTimer;		// ID of actiontimer.
+
+//	...
+
+};
+
+
+//# --- Inline functions ---
+
+// @}
+  } // namespace MainCU
+} // namespace LOFAR
+
+#endif