diff --git a/.gitattributes b/.gitattributes
index 08e4a357b42b220e246a02b9a8f3089552dd93d8..15d87b117de51006e3b3c7b31031d2931610c2aa 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -462,6 +462,8 @@ MAC/GCF/lofarconf.in -text svneol=native#application/octet-stream
 MAC/MACIO/bootstrap -text
 MAC/MACIO/src/KVT_Protocol.prot -text
 MAC/MACIO/src/LOG_Protocol.prot -text
+MAC/MACIO/src/SB_Protocol.prot -text svneol=native#application/octet-stream
+MAC/MACIO/test/Echo_Protocol.prot -text
 MAC/Navigator/CS1-Navigator-Panels.doc -text
 MAC/Navigator/colorDB/Lofar[!!-~]colors -text svneol=native#application/octet-stream
 MAC/Navigator/colorDB/colorDB_fw -text svneol=native#application/octet-stream
diff --git a/MAC/MACIO/Makefile.am b/MAC/MACIO/Makefile.am
index 90d82dbb21ef35ce74d0ff4e2369f9442755b76d..1068f5729e1a0d057ac416dc652127617af6ec70 100644
--- a/MAC/MACIO/Makefile.am
+++ b/MAC/MACIO/Makefile.am
@@ -1,11 +1,11 @@
-SUBDIRS=src include
+SUBDIRS=autogen src include
 
 pkgextdir     = $(prefix)/config/$(PACKAGE)
 pkgext_DATA   = pkgext pkgextcppflags pkgextcxxflags pkgextldflags
 
 EXTRA_DIST = \
       Makefile.common \
-      APLProtocol.spec \
+      MACIO.spec \
       autoconf_share/compiletool
 
 include $(top_srcdir)/Makefile.common
diff --git a/MAC/MACIO/autogen/Makefile.am b/MAC/MACIO/autogen/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..1b769ff602fc0580b9c156ea2bee50c8ca42355a
--- /dev/null
+++ b/MAC/MACIO/autogen/Makefile.am
@@ -0,0 +1,7 @@
+pkgdatadir = $(datadir)/MACIO
+pkgdata_DATA = protocol.tpl
+
+EXTRA_DIST = $(pkgdata_DATA)
+
+include $(top_srcdir)/Makefile.common
+
diff --git a/MAC/MACIO/autogen/protocol.tpl b/MAC/MACIO/autogen/protocol.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..d555f86df4c93109a0c0b376f9d87e548ffc3b7e
--- /dev/null
+++ b/MAC/MACIO/autogen/protocol.tpl
@@ -0,0 +1,218 @@
+[+ AutoGen5 template ph cc +]
+//
+[+ (dne "//  ") +][+ (out-push-add "/dev/null") +]
+[+ DEFINE prefix_cap +][+ IF (exist? "prefix") +][+ (get "prefix") +][+ ENDIF +][+ ENDDEF +]
+[+ DEFINE prefix_ucase +][+ IF (exist? "prefix") +][+ (string-upcase (get "prefix")) +][+ ENDIF +][+ ENDDEF +]
+[+ DEFINE protocol_id +][+ IF (exist? "id") +][+ (get "id") +][+ ENDIF +][+ ENDDEF +]
+[+ DEFINE signal_name +][+ prefix_ucase +]_[+ (get "signal") +][+ ENDDEF +]
+[+ DEFINE signal_id +][+ signal_name +]_ID[+ ENDDEF +]
+[+ DEFINE cap_signal +][+ (string-substitute (string-capitalize! (get "signal")) '( "_" )' ( "" )) +][+ ENDDEF +]
+[+ DEFINE event_class_name +][+ prefix_cap +][+ cap_signal +]Event[+ ENDDEF +]
+[+ DEFINE event_class_decl +][+ event_class_name +] : public MACIO::GCFEvent[+ ENDDEF +]
+[+ DEFINE protocol_name +][+ (string-upcase (base-name)) +][+ ENDDEF +]
+[+ DEFINE event_class_member_type +][+ IF (*== (get "type") "]") +][+ (substring (get "type") 0 (string-index (get "type") #\[)) +][+ ELSE +][+ (get "type") +][+ ENDIF +][+ ENDDEF +]
+[+ DEFINE event_class_member +][+ event_class_member_type +][+ IF (*== (get "type") "[]") +]*[+ ENDIF +] [+ (get "name") +][+ IF (and (*== (get "type") "]") (not (*== (get "type") "[]"))) +][+ (substring (get "type") (string-index (get "type") #\[) (string-length (get "type"))) +][+ ENDIF +][+ ENDDEF +]
+
+[+ (out-pop) +]
+//
+//  [+ (base-name) +].[+ (suffix) +]: [+ description +]
+//
+//  Copyright (C) 2003-2008
+//  ASTRON (Netherlands Foundation for Research in Astronomy)
+//  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//
+[+ (lgpl "This program" "ASTRON" "//  ") +]
+//
+//  $Id$
+//
+[+ IF (== (suffix) "cc") +]
+#include "[+ (base-name) +].ph"
+
+using namespace LOFAR::MACIO;
+
+const char* LOFAR::[+ (base-name) +]::[+ protocol_name +]_signalnames[] = 
+{
+  "[+ protocol_name +]: invalid signal",[+ FOR event "," +]
+  "[+ signal_name +]"[+ ENDFOR +]
+};
+
+const char* [+ protocol_name +]_errornames[] = 
+{ [+ FOR error "," +]
+	"[+ (get "msg") +]"[+ ENDFOR error +]
+};
+
+const struct protocolStrings		LOFAR::[+ (base-name) +]::[+ protocol-name +]_STRINGS = {
+	[+ (count "event") +]+1, [+ (count "error") +], 
+	LOFAR::[+ (base-name) +]::[+ protocol_name +]_signalnames,
+	[+ protocol_name +]_errornames
+};
+[+ ELSE +]
+#ifndef [+ protocol_name +]_H
+#define [+ protocol_name +]_H
+
+[+ FOR include "" +]
+#include [+ (get "include") +][+ ENDFOR +]
+#include <MACIO/ProtocolDefs.h>
+#include <Common/LofarTypes.h>
+#include <string>
+
+namespace LOFAR
+{
+	namespace [+ (base-name) +]
+	{
+
+[+ (get "prelude") +]
+
+//
+// Define protocol ID
+//
+enum 
+{
+  [+ protocol_name +] = [+ protocol_id +]
+};
+
+//
+// Define error numbers and names
+//
+enum
+{ [+ FOR error "," +]
+	[+ prefix_ucase +]_[+ (get "id") +]_ERR[+ IF (= 0 (for-index)) +] = F_ERROR([+ protocol_name +], [+ (for-index) +])[+ ENDIF +][+ ENDFOR error +]
+};
+
+//
+// Define protocol message types
+//
+enum 
+{ [+ FOR event "," +]
+  [+ signal_id +][+ IF (= 0 (for-index)) +] = 1[+ ENDIF +][+ ENDFOR event +]
+};
+
+[+ FOR event "" +] 
+#define [+ prefix_ucase +]_[+ (get "signal") +] F_SIGNAL([+ protocol_name +], [+ prefix_ucase +]_[+ (get "signal") +]_ID, F_[+ (get "dir")+])[+ ENDFOR event +]
+
+extern const char* [+ protocol_name +]_signalnames[];  // for backwards compatibility 
+extern const struct LOFAR::MACIO::protocolStrings [+ protocol-name +]_STRINGS;
+
+[+ ENDIF +]
+[+ FOR event "" +][+ IF (= (suffix) "ph") +][+ FOR param "" +]
+[+ IF (*== (get "type") "&") +][+ (error "reference types not supported") +][+ ENDIF +]
+[+ IF (and (==* (get "type") "string") (> (string-length (get "type")) 6)) +][+ (error "only scalar 'string' is supported") +][+ ENDIF +][+ ENDFOR +]
+  class [+ event_class_decl +]
+  {
+    public:
+      [+ event_class_name +](MACIO::GCFEvent& e);
+      [+ event_class_name +]();
+      virtual ~[+ event_class_name +]();
+
+      [+ FOR param ";" +]
+      [+ IF (== (get "type") "string") +]std::[+ ENDIF +][+ event_class_member +][+ IF (*== (get "type") "[]") +]; uint32 [+ (get "name") +]NOE[+ ENDIF +][+ ENDFOR +];
+
+      void* pack(uint32& __packsize);
+
+    private:
+      [+ event_class_name +]([+ event_class_name +]&);
+      [+ event_class_name +]& operator= (const [+ event_class_name +]&);
+      
+	    void unpack();
+  };   [+ ELSE +]
+[+ event_class_name +]::[+ event_class_name +](MACIO::GCFEvent& e)
+  : MACIO::GCFEvent(e)[+ FOR param "" +][+ IF (or (*== (get "type") "[]") (*== (get "type") "*")) +],
+    [+ (get "name") +](0)[+ ENDIF +][+ IF (*== (get "type") "[]") +],
+    [+ (get "name") +]NOE(0)[+ ENDIF +][+ ENDFOR +]
+{
+	unpack();
+}
+      
+[+ event_class_name +]::[+ event_class_name +]()
+  : MACIO::GCFEvent([+ signal_name +])[+ FOR param "" +][+ IF (or (*== (get "type") "[]") (*== (get "type") "*")) +],
+    [+ (get "name") +](0)[+ ENDIF +][+ IF (*== (get "type") "[]") +],
+    [+ (get "name") +]NOE(0)[+ ENDIF +][+ ENDFOR +]
+{        
+}
+
+[+ event_class_name +]::~[+ event_class_name +]() 
+{
+  if (_unpackDone)
+  {[+ FOR param "" +][+ IF (and (exist? "userdefined") (*== (get "type") "*")) +]
+    if ([+ (get "name") +]) delete [+ (get "name") +];[+ ENDIF +][+ ENDFOR +]
+  }
+}
+    
+void* [+ event_class_name +]::pack(uint32& __packsize)
+{
+  [+ FOR param "" +][+ IF (or (*== (get "type") "[]") (*== (get "type") "*")) +][+ IF (*== (get "type") "[]") +]if ([+ (get "name") +]NOE > 0) [+ ENDIF +]assert([+ (get "name") +]);[+ ENDIF +]
+  [+ ENDFOR +]
+  uint32 __requiredSize = [+ IF (not (exist? "noheader")) +]sizeof(signal) + sizeof(length)[+ ELSE +]0[+ ENDIF +][+ FOR param "" +]
+    [+ IF (exist? "userdefined") +]+ [+ (get "name") +][+ IF (*== (get "type") "*") +]->[+ ELSE +].[+ ENDIF +]getSize()
+    [+ ELIF (not (*== (get "type") "]")) +]+ [+ IF (== (get "type") "string") +][+ (get "name") +].length() + sizeof(uint16)[+ ELSE +]sizeof([+ (get "name") +])[+ ENDIF+]
+    [+ ELIF (*== (get "type") "[]") +]+ sizeof([+ (get "name") +]NOE) + ([+ (get "name") +]NOE * sizeof([+ event_class_member_type +]))
+    [+ ELSE +]+ sizeof([+ (get "name") +])[+ ENDIF +][+ ENDFOR +];
+
+  resizeBuf(__requiredSize);
+  uint32 __offset = __packsize = 0;
+  [+ IF (not (exist? "noheader")) +]
+  MACIO::GCFEvent::pack(__offset);[+ ENDIF +]
+  [+ FOR param "" +]
+  [+ IF (exist? "userdefined") +]
+  __offset += [+ (get "name") +][+ IF (*== (get "type") "*") +]->[+ ELSE +].[+ ENDIF +]pack(_buffer + __offset);
+  [+ ELIF (not (*== (get "type") "]")) +]
+    [+ IF (== (get "type") "string") +]
+  __offset += packString(_buffer + __offset, [+ (get "name") +]);
+    [+ ELSE +]
+  memcpy(_buffer + __offset, &[+ (get "name") +], sizeof([+ (get "type") +]));
+  __offset += sizeof([+ (get "type") +]);
+    [+ ENDIF +]
+  [+ ELIF (*== (get "type") "[]") +]
+  __offset += packMember(__offset, [+ (get "name") +], [+ (get "name") +]NOE, sizeof([+ event_class_member_type +]));
+  [+ ELSE +]
+  memcpy(_buffer + __offset, [+ (get "name") +], sizeof([+ (get "name") +]));
+  __offset += sizeof([+ (get "name") +]);
+  [+ ENDIF +][+ ENDFOR +]
+	[+ IF (= (count "param") 0) +]
+  // no params in this event to pack
+	[+ ENDIF +]
+          
+  __packsize = __offset;
+  return _buffer;
+}
+
+void [+ event_class_name +]::unpack()
+{
+  if (length > 0)
+  {
+  	[+ IF (> (count "param") 0) +]
+  	uint32 __offset = sizeof(MACIO::GCFEvent);
+    char* __data = (char*) _base;
+    [+ ELSE +]
+    // no params in this event to unpack
+    [+ ENDIF +]
+    [+ FOR param "" +]
+    [+ IF (exist? "userdefined") +]
+      [+ IF (*== (get "type") "*") +]
+    [+ (get "name") +] = new [+ (substring (get "type") 0 (string-index (get "type") #\*)) +]();
+      [+ ENDIF +]
+    __offset += [+ (get "name") +][+ IF (*== (get "type") "*") +]->[+ ELSE +].[+ ENDIF +]unpack(__data + __offset);
+    [+ ELIF (not (*== (get "type") "]")) +]
+      [+ IF (== (get "type") "string") +]
+    __offset += MACIO::GCFEvent::unpackString([+ (get "name") +], __data + __offset);
+      [+ ELSE +]
+    memcpy(&[+ (get "name") +], __data + __offset, sizeof([+ (get "type") +]));
+    __offset += sizeof([+ (get "type") +]);
+      [+ ENDIF +]
+    [+ ELIF (*== (get "type") "[]") +]
+    [+ (get "name") +] = ([+ event_class_member_type +]*) unpackMember(__data, __offset, [+ (get "name") +]NOE,  sizeof([+ event_class_member_type +]));
+    [+ ELSE +]
+    memcpy([+ (get "name") +], (__data + __offset), sizeof([+ (get "name") +]));
+    __offset += sizeof([+ (get "name") +]);
+    [+ ENDIF +][+ ENDFOR +]
+  }
+}[+ ENDIF +][+ ENDFOR +]
+[+ IF (= (suffix) "ph") +]
+	} // namespace [+ (base-name) +]
+} // namespace LOFAR
+
+
+using namespace LOFAR::[+ (base-name) +];
+
+#endif
+[+ ENDIF +]
diff --git a/MAC/MACIO/configure.in b/MAC/MACIO/configure.in
index dff8a1935d39bc8b1282ec5d6a49bee4cd2cac1b..a015beb14818e1462f30a67e6edb7c7f62659c16 100644
--- a/MAC/MACIO/configure.in
+++ b/MAC/MACIO/configure.in
@@ -54,13 +54,16 @@ dnl Check for LOFAR specific things
 dnl
 lofar_GENERAL
 lofar_COMPILETOOLS
-lofar_INTERNAL(MAC/APL/RTCCommon, rtccommon, , 1, APL/RTCCommon/Marshalling.h,,)
+lofar_INTERNAL(LCS/Common, Common, , 1, Common/LofarTypes.h,,)
+dnl lofar_INTERNAL(MAC/APL/RTCCommon, rtccommon, , 1, APL/RTCCommon/Marshalling.h,,)
 
 dnl
 dnl Output Makefiles
 dnl
 AC_OUTPUT(
+autogen/Makefile
 src/Makefile
+test/Makefile
 include/Makefile
 include/MACIO/Makefile
 Makefile
diff --git a/MAC/MACIO/include/MACIO/EventPort.h b/MAC/MACIO/include/MACIO/EventPort.h
new file mode 100644
index 0000000000000000000000000000000000000000..635605d4b4e0a1706d1378162969b568615defde
--- /dev/null
+++ b/MAC/MACIO/include/MACIO/EventPort.h
@@ -0,0 +1,122 @@
+//#  EventPort.h: LCS-Common-Socket based impl of a GCF TCPPort
+//#
+//#  Copyright (C) 2007
+//#  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 LOFAR_MACIO_EVENTPORT_H
+#define LOFAR_MACIO_EVENTPORT_H
+
+// \file EventPort.h
+// LCS-Common-Socket based impl of a GCF TCPPort
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <Common/Net/Socket.h>
+#include <MACIO/GCF_Event.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  namespace MACIO {
+
+// \addtogroup MACIO
+// @{
+
+
+// Define states for the connection fases.
+enum {
+	EP_CREATED = 0,
+	EP_SEES_SB,
+	EP_WAIT_FOR_SB_ANSWER,
+	EP_KNOWS_DEST,
+	EP_CONNECTING,
+	EP_CONNECTED,
+	EP_DISCONNECTED
+};
+
+// The EventPort class is a LCS/Common Socket based TCP port to make it
+// possible for CEP applications to use the MAC protocols.
+class EventPort
+{
+public:
+
+	// EventPort (servicename, type, protocol, hostname)
+	EventPort::EventPort(const string&		aServiceMask,
+						 bool				aServerSocket,
+						 int				aProtocol,
+						 const string&		aHostname = "",
+						 bool				syncCommunication = false);
+
+	// ~EventPort
+	EventPort::~EventPort();
+
+	// connect()
+	bool connect();
+
+	// send(Event*)
+	bool send(GCFEvent*	anEvent);
+
+	// receive() : Event
+	GCFEvent*	receive();
+
+	// getStatus()
+	int getStatus() { return (itsStatus); }
+
+private:
+	// static receiveEvent(aSocket)
+	GCFEvent*	receiveEvent(Socket*	aSocket);
+
+	// static sendEvent(Socket*, Event*)
+	void sendEvent(Socket*		aSocket,
+						  GCFEvent*		anEvent);
+
+	// _internal routines: see source code for description
+	string	_makeServiceName(const string&	aServiceMask, int32		aNumber);
+	bool	_setupConnection();
+	int32	_askBrokerThePortNumber();
+	int32	_waitForSBAnswer();
+	int32	_startConnectionToPeer();
+	int32	_waitForPeerResponse();
+	void	_peerClosedConnection();
+
+	EventPort();
+
+	// Copying is not allowed
+	EventPort(const EventPort&	that);
+	EventPort& operator=(const EventPort& that);
+
+	//# --- Datamembers ---
+	int32			itsPort;
+	string			itsHost;
+	string			itsServiceName;
+	Socket*			itsSocket;
+	Socket*			itsListenSocket;
+	Socket*			itsBrokerSocket;
+	int32			itsStatus;
+	bool			itsSyncComm;
+	bool			itsIsServer;
+};
+
+
+// @}
+  } // namespace MACIO
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/MACIO/include/MACIO/GCF_Event.h b/MAC/MACIO/include/MACIO/GCF_Event.h
new file mode 100644
index 0000000000000000000000000000000000000000..017f260d8574d14547b570180b487dcfd40489c5
--- /dev/null
+++ b/MAC/MACIO/include/MACIO/GCF_Event.h
@@ -0,0 +1,163 @@
+//#  GCF_Event.h: finite state machine events
+//#
+//#  Copyright (C) 2002-2003
+//#  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 MACIO_GCF_EVENT_H
+#define MACIO_GCF_EVENT_H
+
+#include <Common/LofarTypes.h>
+#include <Common/lofar_string.h>
+
+namespace LOFAR {
+ namespace MACIO {
+
+/**
+ * This class is the base event data container to exchange messages between two 
+ * tasks. 
+ * Application tasks will have to define their own protocol by specifying the 
+ * contents of events that are exchanged between tasks. Creating sub class from 
+ * GCFEvent creates application (tasks) specific events. All GCFEvent sub 
+ * classes are generally the same except for the parameters that make the event 
+ * unique. A protocol is a collection of events where each event has a specific 
+ * direction (IN/OUT). To create a new protocol a protocol specification file 
+ * must be created (with extension '.prot'). The autogen utility is then used to 
+ * convert this specification file into a header file containing GCFEvent sub 
+ * class definitions. 
+ * The protocol specification consists of a list of the possible events in the 
+ * protocol each with its own parameters (or no parameters) and with the 
+ * direction in which the event can be sent. The autogen utility is used to 
+ * generate a header file from this definition using a template for the header 
+ * file and the nested key-value pairs from the specification file. This header 
+ * file contains definitions of GCFEvent sub classes, one for each event. 
+ */
+
+#define SIZEOF_EVENT(e) ((ssize_t) (sizeof((e).signal) + sizeof((e).length) + (e).length))
+
+class GCFEvent
+{
+  public:  // constructors, destructors, operators
+    GCFEvent() :
+      signal(0), length(0), _unpackDone(false), _buffer(0),
+      _base(0), _upperbound(0)
+    {}
+
+    GCFEvent(unsigned short sig) :
+      signal(sig), length(0), _unpackDone(false), _buffer(0),
+      _base(0), _upperbound(0)
+    {}
+
+    /// destructor
+    virtual ~GCFEvent();
+
+  protected:
+    /// special constructor it will be call by the specialised "unpack"- 
+    /// constructor generated by autogen
+    GCFEvent(GCFEvent& e) :
+      signal(e.signal), length(e.length), _unpackDone(true), _buffer(0), 
+      _base(&e), _upperbound(0)      
+    {}
+
+  private:
+      GCFEvent& operator= (GCFEvent& e);
+  
+  public: // member methods
+    
+    /// result of a dispatch action
+    enum TResult { ERROR = -1, HANDLED = 0, NOT_HANDLED = 1};
+
+    /**
+     * packs all fields of the event into the event buffer and returns its 
+     * pointer and the number of packed bytes (output argument
+     */
+    virtual void* pack(uint32& packsize);
+
+  protected: // helper methods
+    
+    uint32 unpackString(string& value, char* buffer);   
+    uint32 packString(char* buffer, const string& value);  
+
+    void resizeBuf(uint32 requiredSize);
+    void* unpackMember(char* data, uint32& offset, uint32& memberNOE, uint32 sizeofMemberType);
+    uint32 packMember(uint32 offset, const void* member, uint32 memberNOE, uint32 sizeofMemberType);
+
+  public: // data members
+  	/**
+  	* @code
+  	* Signal format 
+  	*
+  	* 2 most significant bits indicate direction of signal:
+  	*   F_IN    = 0b01
+  	*   F_OUT   = 0b10
+  	*   F_INOUT = 0b11 (F_IN_SIGNAL | F_OUT_SIGNAL)
+  	*
+  	* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+  	* | O | I | P | P | P | P | P | P | S | S | S | S | S | S | S | S |
+  	* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+  	*  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
+  	* <- I/O-><--- protocol ---------><--------- signal -------------->
+  	* @endcode
+  	*/
+  	uint16  signal; // lsb contains signal id (0-255)
+  	                // msb contains protocol id (0-255)
+  	uint32  length; // payload length of the event (thus excl. signal and length) should be <= SSIZE_MAX)
+
+  protected:
+    /// indicates wether the event is unpacked or not
+    bool _unpackDone;
+    /// the packbuffer
+    char* _buffer;
+    /** before the event can be unpacked the "base" must be set, which 
+     * points to the received raw and not unpacked data. In memory first a
+     * GCFEvent object (with only signal and length) is placed followed by the
+     * packed buffer with size "length". This is the data of the specialized event.
+     */
+    GCFEvent* _base;
+
+  private:
+    /// upperbound of the buffer, will be used by resizeBuf method
+    unsigned int _upperbound;
+    
+};
+
+class GCFTransportable
+{
+  public:
+    virtual ~GCFTransportable() {}
+    virtual unsigned int pack(char* buffer) = 0;
+    virtual unsigned int unpack(char* buffer) = 0;
+    virtual unsigned int getSize() = 0;
+};
+
+/**
+ * Macros to aid in decoding the signal field.
+ */
+#define F_EVT_INOUT_MASK    (0xc000)
+#define F_EVT_PROTOCOL_MASK (0x3f00)
+#define F_EVT_SIGNAL_MASK   (0x00ff)
+
+#define F_EVT_INOUT(e)    (((e).signal & F_EVT_INOUT_MASK) >> 14)
+#define F_EVT_PROTOCOL(e) (((e).signal & F_EVT_PROTOCOL_MASK) >> 8)
+#define F_EVT_SIGNAL(e)    ((e).signal & F_EVT_SIGNAL_MASK)
+
+ } // namespace MACIO
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/MACIO/include/MACIO/MACServiceInfo.h b/MAC/MACIO/include/MACIO/MACServiceInfo.h
index d3a325451562e8bc56b539af1af37dd0a8aefdff..14f227cc1347bcc967f0f822fcb9065fefb7c9b7 100644
--- a/MAC/MACIO/include/MACIO/MACServiceInfo.h
+++ b/MAC/MACIO/include/MACIO/MACServiceInfo.h
@@ -20,8 +20,8 @@
 //#
 //#  $Id$
 
-#ifndef GCFCOMMON_SERVICEINFO_H
-#define GCFCOMMON_SERVICEINFO_H
+#ifndef MACIO_SERVICEINFO_H
+#define MACIO_SERVICEINFO_H
 
 // \file MACServiceInfo.h
 // Contains all information about the MAC services.
diff --git a/MAC/MACIO/include/MACIO/Makefile.am b/MAC/MACIO/include/MACIO/Makefile.am
index 02501127ff52300d4262271df414556583367eb5..2eea3950b27c626cf14d0ccd4238d711f5c329e5 100644
--- a/MAC/MACIO/include/MACIO/Makefile.am
+++ b/MAC/MACIO/include/MACIO/Makefile.am
@@ -1,5 +1,10 @@
 pkgincludedir 		= $(includedir)/MACIO
-pkginclude_HEADERS	= MACServiceInfo.h
+pkginclude_HEADERS	= EventPort.h \
+					  GCF_Event.h \
+					  MACServiceInfo.h \
+					  Marshalling.h \
+					  ProtocolDefs.h \
+					  StringVector.h
 
 include $(top_srcdir)/Makefile.common
 
diff --git a/MAC/MACIO/include/MACIO/MarshallBlitz.h b/MAC/MACIO/include/MACIO/MarshallBlitz.h
deleted file mode 100644
index 8bb5ffe268a1549b60d7d1ccf2ab8295d930a107..0000000000000000000000000000000000000000
--- a/MAC/MACIO/include/MACIO/MarshallBlitz.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//#  -*- mode: c++ -*-
-//#
-//#  MarshallBlitz.h: Macros for packing/unpacking blitz arrays
-//#
-//#  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 MARSHALLBLITZ_H_
-#define MARSHALLBLITZ_H_
-
-#include <Common/LofarTypes.h>
-#include <blitz/array.h>
-
-// SIZE blitz::array<...>
-#define MSH_ARRAY_SIZE(array, datatype)	\
-	(((array).dimensions()*sizeof(int32)) + ((array).size() * sizeof(datatype)))
-
-// PACK blitz::array<...>
-// first copy the dimensions of the array, then the array itself.
-#define MSH_PACK_ARRAY(bufptr, offset, array, datatype)	\
-do {	\
-	for (int dim = blitz::firstDim; dim < blitz::firstDim + (array).dimensions(); dim++) {	\
-		int32 extent = (array).extent(dim);	\
-		memcpy(((char*)(bufptr)) + (offset), &extent, sizeof(int32));	\
-		offset += sizeof(int32);	\
-	}	\
-	\
-	if ((array).numElements() > 0) { \
-		if ((array).isStorageContiguous()) {	\
-			memcpy(((char*)(bufptr)) + (offset), (array).data(), (array).size() * sizeof(datatype)); \
-			offset += (array).size() * sizeof(datatype);	\
-		}	\
-		else {	\
-			LOG_FATAL("array must be contiguous");	\
-			exit(EXIT_FAILURE);	\
-		} \
-	}	\
-} while (0)
-
-// UNPACK blitz::array<...>
-#define MSH_UNPACK_ARRAY(bufptr, offset, array, datatype, dims)	\
-do {	\
-	blitz::TinyVector<int, (dims)> extent;	\
-	\
-	for (int dim = blitz::firstDim; dim < blitz::firstDim + (dims); dim++) {	\
-		int32 extenttmp = array.extent(dim);	\
-		memcpy(&extenttmp, ((char*)(bufptr)) + (offset), sizeof(int32));	\
-		offset += sizeof(int32);	\
-		extent(dim - blitz::firstDim) = extenttmp;	\
-	}	\
-	\
-	/* resize the array to the correct size */	\
-	array.resize(extent);	\
-	\
-	memcpy(array.data(), ((char*)(bufptr)) + (offset), array.size() * sizeof(datatype)); \
-	offset += array.size() * sizeof(datatype);	\
-} while (0)
-
-#endif /* MARSHALLING_H_ */
diff --git a/MAC/MACIO/include/MACIO/Marshalling.h b/MAC/MACIO/include/MACIO/Marshalling.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aa8bf0a7eed582b7027e5fc51f912b00b0b87be
--- /dev/null
+++ b/MAC/MACIO/include/MACIO/Marshalling.h
@@ -0,0 +1,209 @@
+//#  -*- mode: c++ -*-
+//#
+//#  Marshalling.h: Macros for packing/unpacking some classes
+//#
+//#  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 MACIO_MARSHALLING_H_
+#define MACIO_MARSHALLING_H_
+
+#include <Common/LofarTypes.h>
+#include <Common/lofar_string.h>
+#include <Common/lofar_bitset.h>
+#include <Common/lofar_map.h>
+
+// SIZE string
+#define MSH_STRING_SIZE(stdstring) \
+	(sizeof(uint32) + (stdstring).size() * sizeof(char))
+
+// PACK string
+#define MSH_PACK_STRING(bufptr, offset, stdstring)	\
+do {	\
+	/* pack stdstring with length */	\
+	uint32 size = (stdstring).size() * sizeof(char);	\
+	memcpy(((char*)(bufptr)) + (offset), &size, sizeof(size));	\
+	offset += sizeof(size);	\
+	memcpy(((char*)(bufptr)) + (offset), (stdstring).c_str(), size * sizeof(char));	\
+	offset += size * sizeof(char);	\
+} while (0)
+
+// UNPACK string
+#define MSH_UNPACK_STRING(bufptr, offset, stdstring)	\
+do {	\
+	uint32 size = 0;	\
+	memcpy(&size, ((char*)(bufptr)) + (offset), sizeof(size));	\
+	offset += sizeof(size);	\
+	char stringbuf[size + 1];	\
+	memcpy(stringbuf, ((char*)(bufptr)) + (offset), size * sizeof(char));	\
+	stringbuf[size] = '\0';	\
+	(stdstring) = string(stringbuf); /* cast to std::string */	\
+	offset += size * sizeof(char);	\
+} while (0)
+
+// SIZE bitset<...>
+#define MSH_BITSET_SIZE(bset) sizeof(bset)
+
+// PACK bitset<...>
+#define MSH_PACK_BITSET(buffer, offset, bset) \
+do { \
+	memcpy(((char*)(buffer))+(offset), &(bset), sizeof(bset)); \
+	offset += sizeof(bset); \
+} while(0)
+
+// UNPACK bitset<...>
+#define MSH_UNPACK_BITSET(buffer,offset,bset) \
+do { \
+	memcpy(&bset, ((char*)(buffer))+(offset), sizeof(bset)); \
+    offset += sizeof(bset); \
+} while(0)
+
+// SIZE map<string, class_with_getSize>
+#define MSH_SIZE_MAP_STRING_CLASS(sizevar, themap, datatype)	\
+do {	\
+	sizevar = sizeof(int32);	\
+	map<string, datatype>::iterator	iter = themap.begin();	\
+	map<string, datatype>::iterator	end  = themap.end();	\
+	while (iter != end) {	\
+		sizevar += MSH_STRING_SIZE(iter->first);	\
+		sizevar += iter->second.getSize();	\
+		iter++;	\
+	}	\
+} while (0)
+	
+
+// PACK map<string, class_with_pack>
+#define MSH_PACK_MAP_STRING_CLASS(bufptr, offset, themap, datatype)	\
+do {	\
+	int32	nrElem = themap.size();	\
+	memcpy(((char*)(bufptr)) + (offset), &nrElem, sizeof(int32));	\
+	offset += sizeof(int32);	\
+	\
+	map<string, datatype>::iterator	iter = themap.begin();	\
+	map<string, datatype>::iterator	end  = themap.end();	\
+	while (iter != end) {	\
+		MSH_PACK_STRING(bufptr, offset, iter->first);	\
+		offset += iter->second.pack(bufptr + offset);	\
+		iter++;	\
+	}	\
+} while (0)
+
+// UNPACK map<string, class_with_unpack>
+#define MSH_UNPACK_MAP_STRING_CLASS(bufptr, offset, themap, datatype)	\
+do {	\
+	int32	nrElem = 0;	\
+	memcpy(&nrElem, ((char*)(bufptr)) + (offset), sizeof(nrElem));	\
+	offset += sizeof(nrElem);	\
+	\
+	for (int elem = 0; elem < nrElem; elem++) {	\
+		string	elem1; \
+		MSH_UNPACK_STRING(bufptr, offset, elem1);	\
+		offset += themap[elem1].unpack(bufptr + offset);	\
+	}	\
+} while (0)
+
+// SIZE map<string, ptr2class_with_getSize>
+#define MSH_SIZE_MAP_STRING_CLASSPTR(sizevar, themap, datatype)	\
+do {	\
+	sizevar = sizeof(int32);	\
+	map<string, datatype*>::iterator	iter = themap.begin();	\
+	map<string, datatype*>::iterator	end  = themap.end();	\
+	while (iter != end) {	\
+		sizevar += MSH_STRING_SIZE(iter->first);	\
+		sizevar += iter->second->getSize();	\
+		iter++;	\
+	}	\
+} while (0)
+	
+
+// PACK map<string, ptr2class_with_pack>
+#define MSH_PACK_MAP_STRING_CLASSPTR(bufptr, offset, themap, datatype)	\
+do {	\
+	int32	nrElem = themap.size();	\
+	memcpy(((char*)(bufptr)) + (offset), &nrElem, sizeof(int32));	\
+	offset += sizeof(int32);	\
+	\
+	map<string, datatype*>::iterator	iter = themap.begin();	\
+	map<string, datatype*>::iterator	end  = themap.end();	\
+	while (iter != end) {	\
+		MSH_PACK_STRING(bufptr, offset, iter->first);	\
+		offset += iter->second->pack((char*)bufptr + offset);	\
+		iter++;	\
+	}	\
+} while (0)
+
+// UNPACK map<string, ptr2class_with_unpack>
+#define MSH_UNPACK_MAP_STRING_CLASSPTR(bufptr, offset, themap, datatype)	\
+do {	\
+	int32	nrElem = 0;	\
+	memcpy(&nrElem, ((char*)(bufptr)) + (offset), sizeof(nrElem));	\
+	offset += sizeof(nrElem);	\
+	\
+	for (int elem = 0; elem < nrElem; elem++) {	\
+		string	elem1; \
+		MSH_UNPACK_STRING(bufptr, offset, elem1);	\
+		themap[elem1] = new datatype; \
+		offset += themap[elem1]->unpack((char*)bufptr + offset);	\
+	}	\
+} while (0)
+
+// SIZE vector<string>>
+#define MSH_SIZE_VECTOR_STRING(sizevar, thevector)	\
+do {	\
+	sizevar = sizeof(int32);	\
+	vector<string>::iterator	iter = thevector.begin();	\
+	vector<string>::iterator	end  = thevector.end();	\
+	while (iter != end) {	\
+		sizevar += MSH_STRING_SIZE(*iter);	\
+		iter++;	\
+	}	\
+} while (0)
+	
+
+// PACK vector<string>
+#define MSH_PACK_VECTOR_STRING(bufptr, offset, thevector)	\
+do {	\
+	int32	nrElem = thevector.size();	\
+	memcpy(((char*)(bufptr)) + (offset), &nrElem, sizeof(int32));	\
+	offset += sizeof(int32);	\
+	\
+	vector<string>::iterator	iter = thevector.begin();	\
+	vector<string>::iterator	end  = thevector.end();	\
+	while (iter != end) {	\
+		MSH_PACK_STRING(bufptr, offset, *iter);	\
+		iter++;	\
+	}	\
+} while (0)
+
+// UNPACK vector<string>
+#define MSH_UNPACK_VECTOR_STRING(bufptr, offset, thevector)	\
+do {	\
+	int32	nrElem = 0;	\
+	memcpy(&nrElem, ((char*)(bufptr)) + (offset), sizeof(nrElem));	\
+	offset += sizeof(nrElem);	\
+	\
+	for (int elem = 0; elem < nrElem; elem++) {	\
+		string	elem1; \
+		MSH_UNPACK_STRING(bufptr, offset, elem1);	\
+		thevector.push_back(elem1); \
+	}	\
+} while (0)
+
+#endif /* MARSHALLING_H_ */
diff --git a/MAC/MACIO/include/MACIO/ProtocolDefs.h b/MAC/MACIO/include/MACIO/ProtocolDefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..64c354bc79c1df41b61ce9df7bacae992124459b
--- /dev/null
+++ b/MAC/MACIO/include/MACIO/ProtocolDefs.h
@@ -0,0 +1,97 @@
+//# ProtocolDefs.h: protocols used by the framework
+//#
+//#  Copyright (C) 2002-2003
+//#  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 PROTOCOLDEFS_H
+#define PROTOCOLDEFS_H
+
+#include <MACIO/GCF_Event.h>
+
+namespace LOFAR {
+  namespace MACIO {
+
+/**
+ * Macro to encode an event's signal from the signal id, protocal an in/out direction
+ */
+#define F_SIGNAL(prot, sig, inout) (   (((unsigned short)(inout) & 0x3) << 14) \
+				     | (((unsigned short)(prot) & 0x3f) << 8)  \
+				     | ((unsigned short)(sig) & 0xff)          \
+				   )
+
+// Macros for encoding and decoding errornumbers
+#define F_ERROR(prot, num) ( (((unsigned short)(prot) & 0x3f) * 100) + (num) )
+#define F_ERR_PROTOCOL(errID) ( ((unsigned short)(errID) / 100) & 0x3f )
+#define F_ERR_NR(errID) ( (unsigned short)(errID) % 100 )
+
+/**
+ * Define different types of signals
+ */
+#define F_IN    0x01
+#define F_OUT   0x02
+#define F_INOUT (F_IN | F_OUT)
+
+// Macros for getting  the direction from a signal
+#define F_INDIR(signal)  ( ((unsigned short)signal >> 14) & F_IN)
+#define F_OUTDIR(signal) ( ((unsigned short)signal >> 14) & F_OUT)
+
+// convenience macros
+#define F_ENTRY F_SIGNAL(F_FSM_PROTOCOL, F_ENTRY_ID, F_IN)
+#define F_EXIT  F_SIGNAL(F_FSM_PROTOCOL, F_EXIT_ID,  F_IN)
+#define F_INIT  F_SIGNAL(F_FSM_PROTOCOL, F_INIT_ID,  F_IN)
+#define F_QUIT  F_SIGNAL(F_FSM_PROTOCOL, F_QUIT_ID,  F_IN)
+
+/**
+ * This enum lists all framework protocols. The application protocols should
+ * start numbering enums at F_APPLICATION_PROTOCOL, e.g.:
+ *
+ * enum {
+ *   MY_CONTROL_PROTOCOL = F_APPLICATION_PROTOCOL,
+ *   MY_MONITORING_PROTOCOL,
+ * };
+ *
+ * NOTE: All application protocols should be enumerated in the same
+ * enum to guarantee application global uniqueness.
+ *
+ */
+enum {
+    F_FSM_PROTOCOL = 1,     // state machine protocol (encoded in msb)
+    F_PORT_PROTOCOL,            // port connection protocol
+    F_GCF_PROTOCOL,             // GCF specific protocol numbers start here
+    F_APL_PROTOCOL = 10,    // APPlication specific protocol numbers start here
+};
+
+// structure for administration of signalnames and errornames.
+struct protocolStrings {
+	unsigned short		nrSignals;
+	unsigned short		nrErrors;
+	const char**		signalNames;
+	const char**		errorNames;
+};
+
+void registerProtocol (unsigned short					protID, 
+					   const struct protocolStrings&	protDef);
+string eventName (const GCFEvent& 	e);
+string errorName (unsigned short	errorID);
+
+  } // namespace MACIO
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/MACIO/include/MACIO/StringVector.h b/MAC/MACIO/include/MACIO/StringVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..0abb24d70789beef1f5dc5dc95905d8330ddda17
--- /dev/null
+++ b/MAC/MACIO/include/MACIO/StringVector.h
@@ -0,0 +1,89 @@
+//#  StringVector.h: Wrapper class for protocol files.
+//#
+//#  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 MACIO_STRING_VECTOR_H
+#define MACIO_STRING_VECTOR_H
+
+// \file StringVector.h
+// Wrapper class for protocol files.
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <Common/lofar_string.h>
+#include <Common/lofar_vector.h>
+#include <MACIO/Marshalling.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  namespace MACIO {
+
+// \addtogroup MACIO
+// @{
+
+
+// class_description
+class StringVector
+{
+public:
+	StringVector() {};
+	~StringVector() {};
+
+	unsigned int StringVector::getSize();
+	unsigned int StringVector::pack  (void	*buffer);
+	unsigned int StringVector::unpack(void	*buffer);
+
+	//# --- PUBLIC Datamember ---
+	vector<string>	theVector;
+};
+
+// @}
+
+// getSize()
+inline unsigned int StringVector::getSize()
+{
+	unsigned int	offset = 0;
+	MSH_SIZE_VECTOR_STRING(offset, theVector);
+	return (offset);
+}
+
+// pack()
+inline unsigned int StringVector::pack(void	*buffer)
+{
+	unsigned int offset = 0;
+	MSH_PACK_VECTOR_STRING(buffer, offset, theVector);
+	return (offset);
+}
+
+// unpack()
+inline unsigned int StringVector::unpack(void	*buffer)
+{
+	unsigned int offset = 0;
+	MSH_UNPACK_VECTOR_STRING(buffer, offset, theVector);
+	return (offset);
+}
+
+
+  } // namespace MACIO
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/MACIO/src/EventPort.cc b/MAC/MACIO/src/EventPort.cc
new file mode 100644
index 0000000000000000000000000000000000000000..db12c0d496e8fa21e187584d9916eb838a01b74e
--- /dev/null
+++ b/MAC/MACIO/src/EventPort.cc
@@ -0,0 +1,434 @@
+//#  EventPort.cc: (raw) socket based implementation to exchange Events
+//#
+//#  Copyright (C) 2007
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <Common/StringUtil.h>
+#include <Common/SystemUtil.h>
+#include <Common/hexdump.h>
+#include <MACIO/MACServiceInfo.h>
+#include <MACIO/GCF_Event.h>
+#include <MACIO/EventPort.h>
+#include <SB_Protocol.ph>
+//#include "GSB_Defines.h"
+
+namespace LOFAR {
+  namespace MACIO {
+
+// Note: the difference with GCF-ports is that this port is only based on the
+// LCS/Common sockets and does therefor not depend on GCF_Tasks.
+
+static char			receiveBuffer[24*4096];
+
+//
+// EventPort (name, type, protocol)
+//
+EventPort::EventPort(const string&		aServiceMask,
+					 bool				aServerSocket,
+					 int				aProtocol,
+					 const string&		aHostname,
+					 bool				syncCommunication) :
+	itsPort			(0),
+	itsHost			(aHostname),
+	itsServiceName	(_makeServiceName(aServiceMask, 0)),
+	itsSocket		(0),
+	itsListenSocket	(0),
+	itsBrokerSocket	(0),
+	itsStatus		(EP_CREATED),
+	itsSyncComm		(syncCommunication),
+	itsIsServer		(aServerSocket)
+{
+	if (itsHost.empty() || itsHost == "localhost") {
+		itsHost = myHostname(false);
+	} 
+
+	// We always need a socket to the serviceBroker for getting a portnumber we may use.
+	itsBrokerSocket = new Socket("ServiceBroker", itsHost, toString(MAC_SERVICEBROKER_PORT));
+	ASSERTSTR(itsBrokerSocket, "can't allocate socket to serviceBroker");
+
+	_setupConnection();
+}
+
+//
+// ~EventPort
+//
+EventPort::~EventPort()
+{
+	if (itsSocket) {
+		itsSocket->shutdown();
+		delete itsSocket;
+	};
+
+	if (itsListenSocket) {
+		itsListenSocket->shutdown();
+		delete itsListenSocket;
+	};
+
+	if (itsBrokerSocket) {
+		itsBrokerSocket->shutdown();
+		delete itsBrokerSocket;
+	};
+}
+
+//
+// connect()
+//
+bool EventPort::connect()
+{
+	return (_setupConnection());
+}
+
+//
+// _setupConnection()
+//
+// Depending of the stage that is already reached in the connection process, this
+// function tries to continue from there till a connection is made.
+//
+// Note: all error handling is in this 'overall' routine to keep the subroutines
+//		 that are called as easy as possible.
+//
+bool EventPort::_setupConnection()
+{
+	// test most likely state first for performance
+	if (itsStatus == EP_CONNECTED) {
+		return (true);
+	}
+
+	// not connected, so we left somewhere in the connection sequence, pick the sequence
+	// at the right place.
+
+	// No connection to the SB yet?
+	if (itsStatus == EP_CREATED) {
+		LOG_DEBUG ("Trying to make connection with the ServiceBroker");
+		itsBrokerSocket->connect(itsSyncComm ? -1 : 500);	// try to connect, wait forever or 0.5 sec
+		if (!itsBrokerSocket->isConnected()) {	// failed?
+			if (itsSyncComm) {
+				ASSERTSTR(false, "Cannot connect to the ServiceBroker");
+			}
+			return (false);		// async socket allows failures.
+		}
+		itsStatus = EP_SEES_SB;
+		itsBrokerSocket->setBlocking(itsSyncComm);		// no other tasks, do rest blocking
+	}
+
+	// second step: ask service broker the portnumber
+	if (itsStatus == EP_SEES_SB) {
+		itsStatus += _askBrokerThePortNumber();
+		if (itsStatus <= EP_SEES_SB) {
+			if (itsSyncComm) {
+				ASSERTSTR(false, "Cannot contact the ServiceBroker");
+			}
+			return (false);		// async socket allows failures.
+		}
+	}
+
+	// third step: wait for the answer of the SB
+	if (itsStatus == EP_WAIT_FOR_SB_ANSWER) {
+		itsStatus += _waitForSBAnswer();
+		if (itsStatus <= EP_WAIT_FOR_SB_ANSWER) {
+			if (itsSyncComm) {
+				ASSERTSTR(false, "Cannot contact the other party");
+			}
+			return (false);		// async socket allows failures.
+		}
+	}
+
+	// fourth step: try to connect to the real socket.
+	if (itsStatus == EP_KNOWS_DEST) {
+		itsStatus += _startConnectionToPeer();
+		if (itsStatus <= EP_KNOWS_DEST) {
+			if (itsSyncComm) {
+				ASSERTSTR(false, "Cannot contact the other party");
+			}
+			return (false);		// async socket allows failures.
+		}
+	}
+
+	// fifth step: wait for response of connection request
+	if (itsStatus == EP_CONNECTING) {
+		itsStatus += _waitForPeerResponse();
+		if (itsStatus <= EP_CONNECTING) {
+			if (itsSyncComm) {
+				ASSERTSTR(false, "Cannot contact the other party");
+			}
+			return (false);		// async socket allows failures.
+		}
+	}
+
+	return (itsStatus == EP_CONNECTED);
+}
+
+//
+// send a message to the message broker requesting a portnumber
+//
+int32 EventPort::_askBrokerThePortNumber()
+{
+	// construct the question.
+	if (itsIsServer) {
+		// tell SB the name of our service
+		SBRegisterServiceEvent	request;
+		request.seqnr		= 5;	// or any other number
+		request.servicename	= itsServiceName;
+
+		// send question
+		sendEvent(itsBrokerSocket, &request);
+	}
+	else {	// client socket
+		// ask SB the portnumber of the (operational) service.
+		SBGetServiceinfoEvent	request;
+		request.seqnr		= 5;	// or any other number
+		request.servicename	= itsServiceName;
+		request.hostname	= itsHost;
+
+		// send question
+		sendEvent(itsBrokerSocket, &request);
+	}
+
+	return (1);		// goto next state
+}
+
+//
+// waitForSBAnswer()
+//
+// Wait until we received a response from the service broker.
+//
+int32 EventPort::_waitForSBAnswer()
+{
+	// wait for response
+	GCFEvent*	answerEventPtr(receiveEvent(itsBrokerSocket));
+	if (!answerEventPtr) {
+		return (0);		// stay in this mode
+	}
+
+	// a complete event was received, handle it.
+	if (itsIsServer) {
+		SBServiceRegisteredEvent response(*answerEventPtr);
+		if (response.result != 0) {
+			LOG_ERROR_STR("Service " << itsServiceName << " is already on the air.");
+			return (-1);	// next time ask again
+		}
+		itsPort = response.portnumber;
+		LOG_DEBUG_STR("Service " << itsServiceName << " will be at port " << itsPort);
+		// note: keep connection with Broker so he knows we are on the air.
+	}
+	else {	// client socket
+		SBServiceInfoEvent response(*answerEventPtr);
+		if (response.result != 0) {
+			LOG_ERROR_STR("Service " << itsServiceName << " is unknown");
+			return (-1);	// next time ask again
+		}
+		itsPort = response.portnumber;
+		LOG_DEBUG_STR("Service " << itsServiceName << " is at port " << itsPort);
+
+		// close connection with Broker.
+		itsBrokerSocket->shutdown();
+		itsBrokerSocket = 0;
+	}
+
+	return (1);		// continue with next stage
+}
+
+//
+// _startConnectionToPeer()
+//
+int32 EventPort::_startConnectionToPeer()
+{
+	// Finally we can make the real connection
+	if (itsIsServer) {
+		LOG_DEBUG_STR ("Opening listener on port " << itsPort);
+		itsListenSocket = new Socket(itsServiceName, toString(itsPort), Socket::TCP);
+		itsSocket = itsListenSocket->accept(itsSyncComm ? -1 : 500);
+	}
+	else {
+		LOG_DEBUG_STR ("Trying to make connection with " << itsServiceName);
+		itsSocket = new Socket(itsServiceName, itsHost, toString(itsPort), Socket::TCP);
+		itsSocket->connect(itsSyncComm ? -1 : 500);	// try to connect, wait forever or 0.5 sec
+	}
+	return (1);
+}
+
+//
+// _waitForPeerResponse()
+//
+int32 EventPort::_waitForPeerResponse()
+{
+	// connection (already) successful?
+	if (itsSocket->isConnected()) {
+		itsSocket->setBlocking(itsSyncComm);
+		return (1);
+	}
+
+	// do a retry
+	if (itsIsServer) {
+		itsSocket = itsListenSocket->accept(itsSyncComm ? -1 : 500);
+	}
+	else {
+		itsSocket->connect(itsSyncComm ? -1 : 500);	// try to connect, wait forever or 0.5 sec
+	}
+
+	return (0);
+}
+
+//
+// _peerClosedConnection()
+//
+void EventPort::_peerClosedConnection()
+{
+	// yeah.... what is wise to do here????
+	ASSERTSTR(false, "Other side closed the connection, bailing out");
+
+}
+
+//
+// send(Event*)
+//
+bool EventPort::send(GCFEvent*	anEvent)
+{
+	if (!_setupConnection()) {
+		return (false);
+	}
+
+	sendEvent(itsSocket, anEvent);
+	return (true);
+}
+
+//
+// receive() : Event
+//
+GCFEvent*	EventPort::receive()
+{
+	return (_setupConnection() ? receiveEvent(itsSocket) : 0L);
+}
+
+//
+// _makeServiceName(mask, number)
+//
+string	EventPort::_makeServiceName(const string&	aServiceMask, int32		aNumber)
+{
+	// NOTE: this code is copied from GCF/TM/Port/GCF_PortInterface.cc
+	string	instanceNrStr;
+	if (aNumber) {
+		instanceNrStr = toString(aNumber);
+	}
+
+	return(formatString(aServiceMask.c_str(), instanceNrStr.c_str()));
+}
+
+// -------------------- STATIC FUNCTIONS --------------------
+//
+// static sendEvent(Socket*, Event*)
+//
+void EventPort::sendEvent(Socket*		aSocket,
+						  GCFEvent*		anEvent)
+{
+	// Serialize the message and write buffer to port
+	uint32	packSize;
+	void* 	buf 	   = anEvent->pack(packSize);
+	int32 	btsWritten = aSocket->write(buf, packSize);
+	ASSERTSTR(btsWritten == (int32)packSize, 
+			  "Only " << btsWritten << " of " << packSize << " bytes written");
+}
+
+//
+// static receiveEvent(aSocket)
+//
+GCFEvent*	EventPort::receiveEvent(Socket*	aSocket)
+{
+	static int32	gBtsToRead(0);
+	static int32	gTotalBtsRead(0);
+	static int32	gReadState(0);
+
+	GCFEvent*		header ((GCFEvent*) &receiveBuffer[0]);
+	int32			btsRead(0);
+
+	// first read signal (= eventtype) field
+	if (gReadState == 0) {
+		btsRead = aSocket->read((void*) &(header->signal), sizeof(header->signal));
+		if (btsRead < 0) {
+			_peerClosedConnection();
+			return (0);
+		}
+		if (btsRead != sizeof(header->signal)) {
+			if (aSocket->isBlocking()) {
+				ASSERTSTR(false, "Event-type was not received");
+			}
+			return (0);		// async socket allows failures.
+		}
+		gReadState++;
+	}
+
+	// next read the length of the rest of the message
+	if (gReadState == 1) {
+		btsRead = aSocket->read((void*) &(header->length), sizeof(header->length));
+		if (btsRead < 0) {
+			_peerClosedConnection();
+			return (0);
+		}
+		if (btsRead != sizeof(header->length)) {
+			if (aSocket->isBlocking()) {
+				ASSERTSTR(false, "Event-length was not received");
+			}
+			return (0);		// async socket allows failures.
+		}
+		gReadState++;
+		gBtsToRead = header->length;		// get size of data part
+	}
+
+	// finally read the datapart of the event
+	if (gReadState == 2) {
+		LOG_DEBUG_STR("Still " << gBtsToRead << " bytes of data to get");
+
+		btsRead = 0;
+		if (gBtsToRead) {
+			btsRead = aSocket->read(&receiveBuffer[sizeof(GCFEvent) + gTotalBtsRead], gBtsToRead);
+			if (btsRead < 0) {
+				_peerClosedConnection();
+				return (0);
+			}
+			if (btsRead != gBtsToRead) {
+				if (aSocket->isBlocking()) {
+					ASSERTSTR(false, "Only " << btsRead << " bytes of msg read: " << gBtsToRead);
+				}
+				return (0);		// async socket allow failures
+			}
+		}
+
+		if (btsRead == gBtsToRead) {	// everything received?
+			// reset own admin
+			gReadState    = 0;
+			gTotalBtsRead = 0;
+			gBtsToRead    = 0;
+//			hexdump(receiveBuffer, sizeof(GCFEvent) + header->length);
+			return (header);
+		}
+	}
+
+	// not all information received yet
+	return (0L);
+}
+
+ 
+  } // namespace MACIO
+} // namespace LOFAR
diff --git a/MAC/MACIO/src/GCF_Event.cc b/MAC/MACIO/src/GCF_Event.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d783173d08a24bbf486bb12511085d3b789bdd88
--- /dev/null
+++ b/MAC/MACIO/src/GCF_Event.cc
@@ -0,0 +1,101 @@
+//#  GCF_Event.cc: finite state machine events
+//#
+//#  Copyright (C) 2002-2003
+//#  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 <MACIO/GCF_Event.h>
+
+using namespace std;
+
+namespace LOFAR {
+  namespace MACIO {
+
+GCFEvent::~GCFEvent() 
+{ 
+	if (_buffer)  {
+		delete [] _buffer; 
+	}
+}
+
+void* GCFEvent::pack(uint32& packsize) 
+{   
+  // packs the base event fields     
+  memcpy(_buffer, &signal, sizeof(signal));
+  memcpy(_buffer + sizeof(signal), &length, sizeof(length));
+  packsize = sizeof(signal) + sizeof(length);
+  return _buffer;
+}
+
+void GCFEvent::resizeBuf(uint32 requiredSize)
+{
+  // resizes the buffer if needed
+  if (requiredSize > _upperbound && _buffer) {
+    delete [] _buffer;
+    _buffer = 0;
+  }
+  if (!_buffer) {
+    _buffer = new char[requiredSize];
+    _upperbound = requiredSize;
+  }
+  length = requiredSize - sizeof(length) - sizeof(signal);
+}
+
+void* GCFEvent::unpackMember(char* data, uint32& offset, uint32& memberNOE, uint32 sizeofMemberType)
+{
+  void* seqPtr(0);
+  memcpy(&memberNOE, data + offset, sizeof(memberNOE));
+  seqPtr = data + offset + sizeof(memberNOE);
+  offset += sizeof(memberNOE) + (memberNOE * sizeofMemberType);
+  return seqPtr;
+}
+
+uint32 GCFEvent::packMember(uint32 offset, const void* member, uint32 memberNOE, uint32 sizeofMemberType)
+{
+  ASSERT(_buffer);
+  memcpy(_buffer + offset, &memberNOE, sizeof(memberNOE));
+  offset += sizeof(memberNOE);
+  if (memberNOE > 0) {
+    memcpy(_buffer + offset, member, memberNOE * sizeofMemberType);
+  }
+  return (memberNOE * sizeofMemberType) + sizeof(memberNOE);
+}
+
+uint32 GCFEvent::unpackString(string& value, char* buffer)
+{
+  uint16 stringLength(0);
+  memcpy((void *) &stringLength, buffer, sizeof(stringLength));
+  value.clear();
+  value.append(buffer + sizeof(stringLength), stringLength);
+  return stringLength + sizeof(stringLength);
+}
+
+uint32 GCFEvent::packString(char* buffer, const string& value)
+{
+  uint16 stringLength(value.size());
+  uint32 neededBufLength = value.size() + sizeof(stringLength);
+  memcpy(buffer, (void *) &stringLength, sizeof(stringLength));
+  memcpy(buffer + sizeof(stringLength), (void *) value.c_str(), value.size());
+  return neededBufLength;
+}  
+  } // namespace MACIO
+} // namespace LOFAR
diff --git a/MAC/MACIO/src/KVT_Protocol.prot b/MAC/MACIO/src/KVT_Protocol.prot
index 3d26095ee13a202dd7ac25790b5e21c81b0b701c..a5e9e3a84d49e96be1883d71e57aa5ba5d21a49f 100644
--- a/MAC/MACIO/src/KVT_Protocol.prot
+++ b/MAC/MACIO/src/KVT_Protocol.prot
@@ -24,10 +24,10 @@ autogen definitions protocol;
 
 description	= "Protocol for sending Key-Value-Time triples to the KeyValueLogger";
 prefix		= "KVT"; // for the signal names
-id 			= "(LOFAR::GCF::TM::F_GCF_PROTOCOL + 1)";
+id 			= "(LOFAR::MACIO::F_GCF_PROTOCOL + 1)";
 
 // specify extra include files
-include = '<APL/RTCCommon/StringVector.h>';
+include = '<MACIO/StringVector.h>';
 
 prelude = << PRELUDE_END
 
@@ -115,12 +115,12 @@ event = {
 	};
 	param = {
 		name = "keys";
-		type = "RTC::StringVector";
+		type = "MACIO::StringVector";
 		userdefined;
 	};
 	param = {
 		name = "values";
-		type = "RTC::StringVector";
+		type = "MACIO::StringVector";
 		userdefined;
 	};
 };
diff --git a/MAC/MACIO/src/LOG_Protocol.prot b/MAC/MACIO/src/LOG_Protocol.prot
index 07b0eb82a4a72bbd2c5b87ada2db156f282c58bd..db42271361a8adf789a1d7209585f6c94e139e13 100644
--- a/MAC/MACIO/src/LOG_Protocol.prot
+++ b/MAC/MACIO/src/LOG_Protocol.prot
@@ -24,11 +24,11 @@ autogen definitions protocol;
 
 description = "Protocol definition for sending LogMessages to a LoggingProcessor";
 prefix = "LOG"; // for the signal names
-id = "(LOFAR::GCF::TM::F_GCF_PROTOCOL + 0)";
+id = "(LOFAR::MACIO::F_GCF_PROTOCOL + 0)";
 // specify extra include files
 // e.g.
 //include = '<sys/time.h>';
-include = '<APL/RTCCommon/StringVector.h>';
+include = '<MACIO/StringVector.h>';
 
 prelude = << PRELUDE_END
 
@@ -83,12 +83,12 @@ event = {
 	};
 	param = {
 		name = "DPnames";
-		type = "RTC::StringVector";
+		type = "MACIO::StringVector";
 		userdefined;
 	};
 	param = {
 		name = "messages";
-		type = "RTC::StringVector";
+		type = "MACIO::StringVector";
 		userdefined;
 	};
 };
diff --git a/MAC/MACIO/src/Makefile.am b/MAC/MACIO/src/Makefile.am
index 52f2cb642afd59d77286b4f03ac148369aa72a04..4fe18fc6b75e8c037134e2a72d3ac302bfee0243 100644
--- a/MAC/MACIO/src/Makefile.am
+++ b/MAC/MACIO/src/Makefile.am
@@ -1,23 +1,25 @@
 AUTOGEN = autogen
 SUFFIXES = .ph
 %.ph: %.prot
-	$(AUTOGEN) --writable -L $(datadir)/GCF/TM $<
+	$(AUTOGEN) --writable -L $(datadir)/MACIO $<
 	cp $*.ph $(top_builddir)/include/MACIO/
 
 %.cc: %.prot
-	$(AUTOGEN) --writable -L $(datadir)/GCF/TM $<
+	$(AUTOGEN) --writable -L $(datadir)/MACIO $<
 
 clean-local:
 	rm -f *.ph
 
 bin_PROGRAMS 				= 
 bin_SCRIPTS					= 
-INSTHDRS 					= LOG_Protocol.ph KVT_Protocol.ph 
+INSTHDRS 					= LOG_Protocol.ph KVT_Protocol.ph SB_Protocol.ph
 NOINSTHDRS 					= 
 BUILT_SOURCES				= LOG_Protocol.cc \
 							  LOG_Protocol.ph \
 							  KVT_Protocol.cc \
-							  KVT_Protocol.ph
+							  KVT_Protocol.ph \
+							  SB_Protocol.cc \
+							  SB_Protocol.ph
 
 pkgincludedir				= $(includedir)/MACIO
 pkginclude_HEADERS 			= $(NOINSTHDRS) $(INSTHDRS)
@@ -25,9 +27,12 @@ DOCHDRS						= $(pkginclude_HEADERS) $(BUILT_SOURCES)
 EXTRA_DIST 					= $(configfiles_DATA) $(sysconf_DATA)
 
 # Libraries
-lib_LTLIBRARIES         	= liblog_protocol.la libkvt_protocol.la
+lib_LTLIBRARIES         	= liblog_protocol.la \
+							  libkvt_protocol.la \
+							  libmacio.la
 liblog_protocol_la_SOURCES 	= LOG_Protocol.cc
 libkvt_protocol_la_SOURCES 	= KVT_Protocol.cc
+libmacio_la_SOURCES 		= GCF_Event.cc EventPort.cc ProtocolDefs.cc SB_Protocol.cc
 
 #in case of make install these files will be copied to the bindir beside the test apps
 configfilesdir				= $(bindir)
diff --git a/MAC/MACIO/src/ProtocolDefs.cc b/MAC/MACIO/src/ProtocolDefs.cc
new file mode 100644
index 0000000000000000000000000000000000000000..66334d64e59af9d7918b342756dc72d6d0a0cb22
--- /dev/null
+++ b/MAC/MACIO/src/ProtocolDefs.cc
@@ -0,0 +1,75 @@
+//#  ProtocolDefs.cc: Generic protocol related routines
+//#
+//#  Copyright (C) 2007-2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/lofar_map.h>
+#include <Common/StringUtil.h>
+#include <MACIO/ProtocolDefs.h>
+
+namespace LOFAR {
+	namespace MACIO {
+
+typedef map<unsigned short, const struct protocolStrings*> protStringsMap;
+static protStringsMap 	_protNameTable;
+
+//
+// registerProtocol(protID, protocolStrings)
+//
+void registerProtocol (unsigned short					protID, 
+					   const struct protocolStrings&	protDef)
+{
+	_protNameTable[protID] = &protDef;
+	LOG_DEBUG_STR ("registered protocol: " << protID);
+}
+
+//
+// eventName(event&)
+//
+string eventName(const GCFEvent& e)
+{
+	protStringsMap::const_iterator iter = _protNameTable.find(F_EVT_PROTOCOL(e));
+	if ((iter != _protNameTable.end()) && (F_EVT_SIGNAL(e) <= iter->second->nrSignals)) {
+		return ((iter->second->signalNames)[F_EVT_SIGNAL(e)]);
+	}
+
+	return (formatString("unknown signal(protocol=%d, signal=%d)", 
+							F_EVT_PROTOCOL(e), F_EVT_SIGNAL(e)));
+}
+
+//
+// errorName(errorNr)
+//
+string errorName(unsigned short	errorID)
+{
+	protStringsMap::const_iterator iter = _protNameTable.find(F_ERR_PROTOCOL(errorID));
+	if ((iter != _protNameTable.end()) && (F_ERR_NR(errorID) <= iter->second->nrErrors)) {
+		return ((iter->second->errorNames)[F_ERR_NR(errorID)]);
+	}
+
+	return (formatString("unknown error(protocol=%d, error=%d)", 
+							F_ERR_PROTOCOL(errorID), F_ERR_NR(errorID)));
+}
+
+  } // namespace MACIO
+} // namespace LOFAR
diff --git a/MAC/MACIO/src/SB_Protocol.prot b/MAC/MACIO/src/SB_Protocol.prot
new file mode 100644
index 0000000000000000000000000000000000000000..ecb81edda5d86d4b254522e290d240ea806cc149
--- /dev/null
+++ b/MAC/MACIO/src/SB_Protocol.prot
@@ -0,0 +1,190 @@
+//#  SB_Protocol.prot: Protocol definition for the Service Broker Daemon
+//#
+//#  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$
+
+autogen definitions protocol;
+
+description = "Protocol for the Service Broker deamon";
+prefix = "SB"; // for the signal names
+id = "(LOFAR::MACIO::F_GCF_PROTOCOL + 3)";
+
+// specify extra include files
+// include = '<someFile.h>';
+
+prelude = << PRELUDE_END
+
+// The following messages are defined in the servicebroker protocol
+//
+// REGISTER_SERVICE    (uint16 seqnr, string servicename);
+// SERVICE_REGISTERED  (uint16 seqnr, int32  portNumber,  uint16 result);
+// GET_SERVICEINFO     (uint16 seqnr, string servicename, string hostname);
+// SERVICE_INFO        (uint16 seqnr, int32  portNumber,  string hostname, uint16 result);
+// UNREGISTER_SERVICE  (uint16 seqnr, string servicename);
+// SERVICE_UNREGISTERED(uint16 seqnr, uint16 result);
+// REREGISTER_SERVICE  (uint16 seqnr, string servicename, int32  portNumber);
+// SERVICE_REREGISTERED(uint16 seqnr, uint16 result);
+//
+
+enum {
+	SB_NO_ERROR, 
+	SB_UNKNOWN_ERROR,
+	SB_SERVICE_ALREADY_EXIST,
+	SB_NO_FREE_PORTNR,
+	SB_UNKNOWN_SERVICE,
+	SB_NO_CONNECTION,
+	SB_CANT_RECOVER
+};
+
+PRELUDE_END;
+
+//
+// An "event" has a "signal" and a "dir" (direction)
+// and zero or more "param"s.
+// "dir" can be one of "IN" or "OUT".
+// A "param" has a "name" and a "type".
+//
+event = {
+	signal = REGISTER_SERVICE;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "servicename";
+		type = "string";
+	};
+};
+
+event = {
+	signal = UNREGISTER_SERVICE;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "servicename";
+		type = "string";
+	};
+};
+
+event = {
+	signal = GET_SERVICEINFO;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "servicename";
+		type = "string";
+	};
+	param = {
+		name = "hostname";
+		type = "string";
+	};
+};
+
+event = {
+	signal = SERVICE_REGISTERED;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "portnumber";
+		type = "uint32";
+	};	
+	param = {
+		name = "result";
+		type = "uint16";
+	};
+};
+
+event = {
+	signal = SERVICE_INFO;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "portnumber";
+		type = "uint32";
+	};
+	param = {
+		name = "hostname";
+		type = "string";
+	};
+	param = {
+		name = "result";
+		type = "uint16";
+	};
+};
+
+event = {
+	signal = SERVICE_UNREGISTERED;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "result";
+		type = "uint16";
+	};
+};
+
+event = {
+	signal = REREGISTER_SERVICE;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "servicename";
+		type = "string";
+	};
+	param = {
+		name = "portnumber";
+		type = "uint32";
+	};
+};
+
+event = {
+	signal = SERVICE_REREGISTERED;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "servicename";
+		type = "string";
+	};
+	param = {
+		name = "result";
+		type = "uint16";
+	};
+};
diff --git a/MAC/MACIO/test/Echo_Protocol.prot b/MAC/MACIO/test/Echo_Protocol.prot
new file mode 100644
index 0000000000000000000000000000000000000000..5bf428ce075d32041b6115f7e1635c860472ebc6
--- /dev/null
+++ b/MAC/MACIO/test/Echo_Protocol.prot
@@ -0,0 +1,57 @@
+//
+// Protocol definition for the Echo server
+//
+autogen definitions protocol;
+
+description = "Protocol for the Echo server";
+prefix = "Echo"; // for the signal names
+id = "LOFAR::MACIO::F_APL_PROTOCOL";
+// specify extra include files
+// e.g.
+include = '<sys/time.h>';
+
+//
+// An "event" has a "signal" and a "dir" (direction)
+// and zero or more "param"s.
+// "dir" can be one of "IN" or "OUT".
+// A "param" has a "name" and a "type".
+//
+event = {
+	signal = PING;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "unsigned int";
+	};
+	param = {
+		name = "ping_time";
+		type = "timeval";
+	};
+};
+
+event = {
+	signal = ECHO;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "unsigned int";
+	};
+	param = {
+		name = "ping_time";
+		type = "timeval";
+	};
+	param = {
+		name = "echo_time";
+		type = "timeval";
+	};
+};
+
+event = {
+  signal = CLOCK;
+  dir = OUT;
+  noheader;
+  param = {
+    name = clockpulse;
+    type = char;
+  };
+};
diff --git a/MAC/MACIO/test/Makefile.am b/MAC/MACIO/test/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..d135bd052ee74d54ee7d0521d1cb56810fd2d4d9
--- /dev/null
+++ b/MAC/MACIO/test/Makefile.am
@@ -0,0 +1,32 @@
+AUTOGEN = autogen
+SUFFIXES = .ph
+%.ph: %.prot
+	$(AUTOGEN) --writable -L $(top_srcdir)/autogen $<
+
+%.cc: %.prot
+	$(AUTOGEN) --writable -L $(top_srcdir)/autogen $<
+
+check_PROGRAMS 		= tEventPort tProtocol
+
+tProtocol_SOURCES 		= testprotocol.ph testprotocol.cc \
+						  Echo_Protocol.ph Echo_Protocol.cc \
+						  tProtocol.cc 
+tProtocol_LDADD			= ../src/libmacio.la
+tProtocol_DEPENDENCIES	= ../src/libmacio.la $(LOFAR_DEPEND)
+
+tEventPort_SOURCES 		= Echo_Protocol.ph Echo_Protocol.cc \
+						  tEventPort.cc
+tEventPort_LDADD		= ../src/libmacio.la
+tEventPort_DEPENDENCIES	= ../src/libmacio.la $(LOFAR_DEPEND)
+
+BUILT_SOURCES = Echo_Protocol.ph testprotocol.ph
+
+EXTRA_DIST =  tProtocol.log_prop
+	
+clean-local:
+	rm -f *.ph
+
+include $(top_srcdir)/Makefile.common
+
+
+
diff --git a/MAC/MACIO/test/tEventPort.cc b/MAC/MACIO/test/tEventPort.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f8a994a9f2df5948c3d3c5c8d47442c2e09b73a8
--- /dev/null
+++ b/MAC/MACIO/test/tEventPort.cc
@@ -0,0 +1,101 @@
+//#  tEventPort.cc: Program to test the EventPort class
+//#
+//#  Copyright (C) 2007
+//#  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 <MACIO/EventPort.h>
+#include <MACIO/MACServiceInfo.h>
+#include "Echo_Protocol.ph"
+
+using namespace LOFAR;
+using namespace LOFAR::MACIO;
+
+static	EchoPingEvent		pingEvent;
+static	EventPort*			echoPort;
+
+int main (int32	argc, char*argv[]) 
+{
+	bool	syncMode;
+	switch (argc) {
+	case 2:	
+		syncMode = (argv[1][0] == 's' || argv[1][0] == 'S');
+		break;
+	default:
+		cout << "Syntax: " << argv[0] << " a | s" << endl;
+		cout << "  the argument ('a' or 's') chooses the asynchrone or synchrone behaviour" << endl
+			 << "of the EventPort. The synchrone mode expects the ServiceBroker and the"  << endl
+			 << "Echo server running. If not it will assert. In this mode the EventPort" << endl
+			 << "wait forever for the answer." << endl 
+			 << "In asynchrone mode the EventPort will never complain and try forever to" << endl
+			 << "reach each of the connection stages and receive the messages. You can" << endl
+			 << "check the EventPort.status() to see in what state the port is." << endl;
+		return (1);
+	}
+
+	INIT_LOGGER("tEventPort");
+
+	// open port	
+	LOG_DEBUG_STR ("Operating in " << ((syncMode) ? "" : "a") << "synchrone mode.");
+	echoPort = new EventPort("ECHO:EchoServer", false, ECHO_PROTOCOL, "", syncMode);
+
+	// construct event
+	pingEvent.seqnr = 25;
+	timeval		pingTime;
+	gettimeofday(&pingTime, 0);
+	pingEvent.ping_time = pingTime;
+
+	LOG_DEBUG("sending the ping event");
+	if (syncMode) {
+		// NOTE: we could also use the while-loop of the asyncmode here.
+		echoPort->send(&pingEvent);
+	}
+	else {
+		while (!echoPort->send(&pingEvent)) {
+			cout << "state = " << echoPort->getStatus() << endl;
+			sleep (1);
+			;
+		}
+	}
+
+	LOG_DEBUG("going to wait for the answer event");
+	GCFEvent*	ackPtr;
+	if (syncMode) {
+		// NOTE: we could also use the while-loop of the asyncmode here.
+		ackPtr = echoPort->receive();
+	}
+	else {
+		while (!(ackPtr = echoPort->receive())) {
+			cout << "state = " << echoPort->getStatus() << endl;
+			sleep (1);
+			;
+		}
+	}
+	EchoEchoEvent	ack(*ackPtr);
+
+	LOG_DEBUG_STR("seqnr: " << ack.seqnr);
+	double	delta =  (1.0 * ack.echo_time.tv_sec + (ack.echo_time.tv_usec / 1000000.0));
+			delta -= (1.0 * ack.ping_time.tv_sec + (ack.ping_time.tv_usec / 1000000.0));
+	LOG_DEBUG_STR("dTime: " << delta << " sec");
+
+	return (0);
+}
+
diff --git a/MAC/MACIO/test/tMarshalling.cc b/MAC/MACIO/test/tMarshalling.cc
new file mode 100644
index 0000000000000000000000000000000000000000..663a159e14912e09be6e8145845eaa7329b58045
--- /dev/null
+++ b/MAC/MACIO/test/tMarshalling.cc
@@ -0,0 +1,311 @@
+//#  tMarshalling.cc: test pack and unpack macros
+//#
+//#  Copyright (C) 2007
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <Common/lofar_bitset.h>
+#include <Common/lofar_map.h>
+#include <Common/hexdump.h>
+#include <APL/RTCCommon/Marshalling.h>
+#include "tMarshalling.h"
+
+using namespace LOFAR;
+
+namespace LOFAR {
+
+SubArray::SubArray(int i, double d, string s) :
+	someInt(i), someDouble(d), someString(s)
+{
+}
+
+unsigned int SubArray::getSize() {
+	return (sizeof(int) + sizeof(double) + MSH_STRING_SIZE(someString));
+}
+
+unsigned int SubArray::pack(void*	buffer) {
+	unsigned int	offset = 0;
+	memcpy(((char*)(buffer)+offset), &someInt, sizeof(int));
+	offset += sizeof (int);
+	memcpy(((char*)(buffer)+offset), &someDouble, sizeof(double));
+	offset += sizeof (double);
+	MSH_PACK_STRING(buffer, offset, someString);
+
+	return (offset);
+}
+
+unsigned int SubArray::unpack(void*	buffer) {
+	unsigned int	offset = 0;
+	memcpy(&someInt, ((char*)(buffer))+offset, sizeof(int));
+	offset += sizeof(int);
+	memcpy(&someDouble, ((char*)(buffer))+offset, sizeof(double));
+	offset += sizeof(double);
+	MSH_UNPACK_STRING(buffer, offset, someString);
+	return (offset);
+}
+
+SubArrayNC::SubArrayNC(int i, double d, string s) :
+	someInt(i), someDouble(d), someString(s)
+{
+}
+
+unsigned int SubArrayNC::getSize() {
+	return (sizeof(int) + sizeof(double) + MSH_STRING_SIZE(someString));
+}
+
+unsigned int SubArrayNC::pack(void*	buffer) {
+	unsigned int	offset = 0;
+	memcpy(((char*)(buffer)+offset), &someInt, sizeof(int));
+	offset += sizeof (int);
+	memcpy(((char*)(buffer)+offset), &someDouble, sizeof(double));
+	offset += sizeof (double);
+	MSH_PACK_STRING(buffer, offset, someString);
+
+	return (offset);
+}
+
+unsigned int SubArrayNC::unpack(void*	buffer) {
+	unsigned int	offset = 0;
+	memcpy(&someInt, ((char*)(buffer))+offset, sizeof(int));
+	offset += sizeof(int);
+	memcpy(&someDouble, ((char*)(buffer))+offset, sizeof(double));
+	offset += sizeof(double);
+	MSH_UNPACK_STRING(buffer, offset, someString);
+	return (offset);
+}
+
+
+} // namespace LOFAR
+
+int main (int	argc, char*	argv[])
+{
+	// string test
+	string	tstString("Dit is een teststring");
+	cout << "Testing string: " << tstString << endl;
+
+	cout << "size = " << MSH_STRING_SIZE(tstString) << endl;
+
+	char	buf[4096];
+	int32	offset(0);
+	MSH_PACK_STRING(buf, offset, tstString);
+	cout << "packed: " << endl;
+	hexdump(buf, offset);
+
+	string	newString;
+	offset = 0;
+	MSH_UNPACK_STRING(buf, offset, newString);
+	cout << "unpacked: " << newString << endl;
+
+	// bitmap test1
+	bitset<32>	bs1;
+	bs1.reset();
+	bs1.set(0);
+	bs1.set(5);
+	bs1.set(20);
+	cout << "Testing bitset<32>" << bs1 << endl;
+	
+	cout << "size = " << MSH_BITSET_SIZE(bs1) << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_BITSET(buf, offset, bs1);
+	cout << "packed:" << endl;
+	hexdump(buf, offset);
+
+	bitset<32>	bs2;
+	offset = 0;
+	MSH_UNPACK_BITSET(buf, offset, bs2);
+	cout << "unpacked: " << bs2 << endl;
+
+	// blitz array <double>
+	blitz::Array<double, 2>		ba1(2,4);
+	ba1 = 	10,	11,
+			20, 21,
+			30, 31,
+			40, 41;
+	cout << "Testing blitz::Array<double, 2>" << ba1 << endl;
+	
+	cout << "size = " << MSH_ARRAY_SIZE(ba1, double) << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_ARRAY(buf, offset, ba1, double);
+	cout << "packed:" << endl;
+	hexdump(buf, offset);
+
+	blitz::Array<double, 2>		ba2(2,4);
+	offset = 0;
+	MSH_UNPACK_ARRAY(buf, offset, ba2, double, 2);
+	cout << "unpacked: " << ba2 << endl;
+
+	// blitz array <int>
+	blitz::Array<int, 2>		emptyArr;
+	cout << "Testing EMPTY blitz::Array<int, 2>" << emptyArr << endl;
+	
+	cout << "size = " << MSH_ARRAY_SIZE(emptyArr, int) << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_ARRAY(buf, offset, emptyArr, int);
+	cout << "packed:" << endl;
+	hexdump(buf, offset);
+
+	blitz::Array<int, 2>		empty2;
+	offset = 0;
+	MSH_UNPACK_ARRAY(buf, offset, empty2, int, 2);
+	cout << "unpacked: " << empty2 << endl;
+
+	// SubArray		
+	SubArray		SA1(25, 3.14, "stringetje");
+	cout << "Testing SubArray class:" << SA1.someInt << "," << SA1.someDouble 
+										<< "," << SA1.someString << endl;
+	
+	unsigned int	size(SA1.getSize());
+	cout << "size = " << size << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	SA1.pack(buf);
+	cout << "packed:" << endl;
+	hexdump(buf, size);
+
+	SubArray	SA2;
+	offset = 0;
+	SA2.unpack(buf);
+	cout << "unpacked: " << SA2.someInt << "," << SA2.someDouble 
+										<< "," << SA2.someString << endl;
+
+
+	// map<string, subArray>
+	map<string, SubArray>		ms1;
+	ms1["eerste_item"] = SubArray(25, 3.14, "stringetje");
+	ms1["tweede_item"] = SubArray(0, 32, "ejtegnirts");
+	cout << "Testing map<string, SubArray>: " << endl;
+	map<string, SubArray>::iterator	iter = ms1.begin();
+	map<string, SubArray>::iterator	end  = ms1.end();
+	while (iter != end) {
+		cout << "map[" << iter->first << "]:" << iter->second.someInt << "," << 
+					iter->second.someDouble << "," << iter->second.someString << endl; 
+		iter++;
+	}
+
+	unsigned int	mapsize;
+	MSH_SIZE_MAP_STRING_CLASS(mapsize, ms1, SubArray);
+	cout << "size = " << mapsize << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_MAP_STRING_CLASS(buf, offset, ms1, SubArray);
+	cout << "packed:" << endl;
+	hexdump(buf, mapsize);
+
+	map<string, SubArray>		ms2;
+	offset = 0;
+	MSH_UNPACK_MAP_STRING_CLASS(buf, offset, ms2, SubArray);
+	cout << "Unpacked map<string, SubArray>: " << endl;
+	map<string, SubArray>::iterator	iter2 = ms2.begin();
+	map<string, SubArray>::iterator	end2  = ms2.end();
+	while (iter2 != end2) {
+		cout << "map[" << iter2->first << "]:" << iter2->second.someInt << "," << 
+					iter2->second.someDouble << "," << iter2->second.someString << endl; 
+		iter2++;
+	}
+
+
+	// map<string, subArrayNC*>
+	map<string, SubArrayNC*>		msanc1;
+	msanc1["eerste_item"] = new SubArrayNC(25, 3.14, "stringetje");
+	msanc1["tweede_item"] = new SubArrayNC(0, 32, "ejtegnirts");
+	cout << "Testing map<string, SubArrayNC*>: " << endl;
+	map<string, SubArrayNC*>::iterator	iternc = msanc1.begin();
+	map<string, SubArrayNC*>::iterator	endnc  = msanc1.end();
+	while (iternc != endnc) {
+		cout << "map[" << iternc->first << "]:" << iternc->second->someInt << "," << 
+					iternc->second->someDouble << "," << iternc->second->someString << endl; 
+		iternc++;
+	}
+
+	unsigned int	mapncsize;
+	MSH_SIZE_MAP_STRING_CLASSPTR(mapncsize, msanc1, SubArrayNC);
+	cout << "size = " << mapncsize << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_MAP_STRING_CLASSPTR(buf, offset, msanc1, SubArrayNC);
+	cout << "packed:" << endl;
+	hexdump(buf, mapncsize);
+
+	map<string, SubArrayNC*>		msanc2;
+	offset = 0;
+	MSH_UNPACK_MAP_STRING_CLASSPTR(buf, offset, msanc2, SubArrayNC);
+	cout << "Unpacked map<string, SubArrayNC*>: " << endl;
+	iternc = msanc2.begin();
+	endnc  = msanc2.end();
+	while (iternc != endnc) {
+		cout << "map[" << iternc->first << "]:" << iternc->second->someInt << "," << 
+					iternc->second->someDouble << "," << iternc->second->someString << endl; 
+		iternc++;
+	}
+
+
+	// vector<string>
+	vector<string>		sv1;
+	sv1.push_back("piet hein");
+	sv1.push_back("nelson");
+	sv1.push_back("van Swieten");
+	cout << "Testing vector<string>" << endl;
+	vector<string>::iterator	itersv = sv1.begin();
+	vector<string>::iterator	endsv  = sv1.end();
+	int	i = 0;
+	while (itersv != endsv) {
+		cout << "vector[" << i << "]:" << *itersv << endl;
+		i++;
+		itersv++;
+	}
+
+	unsigned int	svsize;
+	MSH_SIZE_VECTOR_STRING(svsize, sv1);
+	cout << "size = " << svsize << endl;
+
+	bzero(buf, 4096);
+	offset = 0;
+	MSH_PACK_VECTOR_STRING(buf, offset, sv1);
+	cout << "packed:" << endl;
+	hexdump(buf, svsize);
+
+	vector<string>	sv2;
+	offset = 0;
+	MSH_UNPACK_VECTOR_STRING(buf, offset, sv2);
+	cout << "Unpacked vector<string>" << endl;
+	itersv = sv2.begin();
+	endsv  = sv2.end();
+	i = 0;
+	while (itersv != endsv) {
+		cout << "vector[" << i << "]:" << *itersv << endl;
+		i++;
+		itersv++;
+	}
+
+	return (0);
+}
diff --git a/MAC/MACIO/test/tMarshalling.h b/MAC/MACIO/test/tMarshalling.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8acab445f96fda48fe5fbf85c2c91356da0bbdb
--- /dev/null
+++ b/MAC/MACIO/test/tMarshalling.h
@@ -0,0 +1,78 @@
+//#  tMarshalling.h: test pack and unpack routines.
+//#
+//#  Copyright (C) 2007
+//#  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 RTC_TMARSHALLING_H
+#define RTC_TMARSHALLING_H
+
+// \file tMarshalling.h
+// test pack and unpack macros
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+//#include <otherPackage/file.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+
+//# --- Forward Declarations ---
+//# classes mentioned as parameter or returntype without virtual functions.
+//class ...;
+
+
+// class_description
+// ...
+
+class	SubArray 
+{
+public:
+	int		someInt;
+	double	someDouble;
+	string	someString;
+
+	SubArray(int i, double d, string s);
+	SubArray() {};
+	unsigned int	getSize();
+	unsigned int	pack(void* buffer);
+	unsigned int	unpack(void* buffer);
+};
+
+class	SubArrayNC
+{
+public:
+	int		someInt;
+	double	someDouble;
+	string	someString;
+
+	SubArrayNC(int i, double d, string s);
+	SubArrayNC() {};
+	unsigned int	getSize();
+	unsigned int	pack(void* buffer);
+	unsigned int	unpack(void* buffer);
+private:
+	// prevent copy
+	SubArrayNC(const SubArrayNC&);
+};
+
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/MACIO/test/tProtocol.cc b/MAC/MACIO/test/tProtocol.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7a7a02d713af36123ec2c1bb6c5eb881081bea1f
--- /dev/null
+++ b/MAC/MACIO/test/tProtocol.cc
@@ -0,0 +1,61 @@
+//#  tProtocol.cc
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include "testprotocol.ph"
+#include "Echo_Protocol.ph"
+
+using namespace LOFAR;
+using namespace LOFAR::MACIO;
+
+int main (int	argc, char* argv[]) 
+{
+	INIT_LOGGER(argv[0]);
+
+	LOG_INFO_STR ("TESTPROTOCOL has id: " << TESTPROTOCOL);
+
+	TEST_PTCTestInEvent		inEvent;
+
+	LOG_INFO("Trying to print an errormsg before registering the protocol");
+	LOG_INFO_STR("errornr: " << TEST_PTC_WINDOWS_ERR << " = " 
+							 << errorName (TEST_PTC_WINDOWS_ERR));
+	LOG_INFO_STR("eventname of in-event: " << eventName(inEvent));
+
+	LOG_INFO("--- Registering the testprotocol ---");
+	registerProtocol (TESTPROTOCOL, TESTPROTOCOL_STRINGS);
+	LOG_INFO(formatString("errornr: %d = %s", TEST_PTC_WINDOWS_ERR, 
+									errorName (TEST_PTC_WINDOWS_ERR).c_str()));
+	LOG_INFO_STR("signalname of in-event: " << eventName(inEvent));
+
+	LOG_INFO ("Registering a second protocol");
+	registerProtocol (ECHO_PROTOCOL, ECHO_PROTOCOL_STRINGS);
+	
+	EchoPingEvent		pingEvent;
+	LOG_INFO_STR("signalname of ping-event: " << eventName(pingEvent));
+
+	return (0);
+}
+
diff --git a/MAC/MACIO/test/tProtocol.log_prop b/MAC/MACIO/test/tProtocol.log_prop
new file mode 100644
index 0000000000000000000000000000000000000000..642b26cfd88e17b84221cb7b5a26e663fe77ddac
--- /dev/null
+++ b/MAC/MACIO/test/tProtocol.log_prop
@@ -0,0 +1,11 @@
+
+# Configure the rootLogger
+log4cplus.rootLogger=DEBUG, STDOUT
+# Define the STDOUT appender
+log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
+log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
+log4cplus.appender.STDOUT.layout.ConversionPattern=%-5p - %m%n
+
+# Define foo at level TRACE4
+#log4cplus.logger.TRC=TRACE4
+
diff --git a/MAC/MACIO/test/testprotocol.prot b/MAC/MACIO/test/testprotocol.prot
new file mode 100644
index 0000000000000000000000000000000000000000..fab32b28692fee7f0c1a05bd7765d215592d9d24
--- /dev/null
+++ b/MAC/MACIO/test/testprotocol.prot
@@ -0,0 +1,85 @@
+//#  testprotocol.prot: Protocol definition to test the base functions
+//#
+//#  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$
+
+autogen definitions protocol;
+
+description = "Protocol for testing the prtocol-programs";
+prefix = "TEST_PTC"; // for the signal names
+id = "63";
+
+// specify extra include files
+
+prelude = << PRELUDE_END
+
+// The following messages are defined in the servicebroker protocol
+//
+// TEST_IN   (uint16 seqnr, string question);
+// TEST_OUT  (uint16 seqnr, string answer);
+//
+
+PRELUDE_END;
+
+//
+// An "event" has a "signal" and a "dir" (direction)
+// and zero or more "param"s.
+// "dir" can be one of "IN" or "OUT".
+// A "param" has a "name" and a "type".
+//
+event = {
+	signal = TEST_IN;
+	dir = IN;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "question";
+		type = "string";
+	};
+};
+
+event = {
+	signal = TEST_OUT;
+	dir = OUT;
+	param = {
+		name = "seqnr";
+		type = "uint16";
+	};
+	param = {
+		name = "answer";
+		type = "string";
+	};
+};
+
+error = {
+	id = NO;
+	msg = "No errors";
+};
+error = {
+	id = RANGE;
+	msg = "Illegal range specified";
+};
+error = {
+	id = WINDOWS;
+	msg = "You are using Windows";
+};
+