diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f768f7909ca84a190cd6d52a1522bf55d0a7e55d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+.pydevproject
+.project
+.cproject
+.settings
+obj
+bin
+core*
+*~
+*.pyc
+*.so
+*.so*
+.pylintrc
+.metadata
+.idea
+.cvsignore
+.nse_depinfo
+software
+oldsrc
+CVS
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c10fe7ddf53b1e66233abd358c10551e573bc2be
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+NAME_SRV = ds-libera-srv
+CXXFLAGS = -I i-tech/server/include -I i-tech/cspi/include -I i-tech/driver/include/
+CXXFLAGS += -DEBPP
+LDFLAGS = -L i-tech/server/lib -lclient
+include ../makefiles/Make-9.3.3.in
diff --git a/README.md b/README.md
index 5d9891f53405e12315c42f37c5363263b36ba4a4..21f0f33ed0723178f78e1576eb5bcbd5169aa4e3 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
 # ds-libera
 
 Tango devicer server for i-tech-brillance
-orignal sources avilablle form SVN: http://svn.code.sf.net/p/tango-ds/code/DeviceClasses/BeamDiagnostics/i-tech-brillance
\ No newline at end of file
+original sources avilablle form SVN: http://svn.code.sf.net/p/tango-ds/code/DeviceClasses/BeamDiagnostics/i-tech-brillance
diff --git a/i-tech/README b/i-tech/README
new file mode 100644
index 0000000000000000000000000000000000000000..5c4917ffe54f0933a1000ae3d7313df44db25d52
--- /dev/null
+++ b/i-tech/README
@@ -0,0 +1,166 @@
+$Id: README,v 1.17 2007/12/03 09:59:21 tomazb Exp $
+
+CSPI -- Control System Programming Interface
+
+Copyright (C) 2004-2006 Instrumentation Technologies
+See the COPYING file for copying conditions.
+
+Control System Programming Interface (CSPI) is a high-level C library
+that allows you to implement a range of applications for the Libera
+family of processors in a consistent and documented way.
+
+CSPI separates control-system specific knowledge from low level
+details and logic related to a Libera processor. Using this model, the
+underlying software (i.e. the Libera GNU/Linux driver) or hardware can
+undergo a change without affecting the application.
+
+CSPI also allows for maximum interoperability -- an application can
+access data from different Libera data sources and even different
+members of the Libera family through a single interface.
+
+Directory listing:
+DOC	- documentation
+SRC	- source files
+
+1. BUILDING
+
+To build the CSPI library, you require headers for the GNU/Linux
+driver for Libera. Please review and, if necessary, edit the
+configuration section of the Makefile to match the location of the
+headers on your system. Next, type:
+
+  cd src
+  make
+
+When cross-compiling, either set the toolchain prefix (CROSS_COMPILE)
+in the configuration section of the Makefile or on the command line:
+
+  CROSS_COMPILE=arm-linux- make
+
+To install the library, type:
+
+  make install
+
+This will copy library files to the location specified in the
+Makefile.
+
+Libera Electron: CORDIC algorithm is used to calculate apmlitudes from
+I and Q values. CORDIC is an iterative algorithm. In the process, the
+amplitude is multiplied by a CORDIC Gain (cumulative magnitude) of
+about 1.647. The actual CORDIC gain depends on the number of
+iterations.
+
+For positions X and Y alone, the CORDIC gain is irrelevant and the
+processing speed can be somewhat improved by building the library with
+CORDIC_IGNORE_GAIN defined.
+
+2. USING
+
+First, you should include the driver and library header files in your
+application:
+
+#include "libera.h"
+#include "cspi.h"
+
+Next, when passing options to GNU C compiler, you should use -lcspi to
+link the application against the library.
+
+To find out more about the library, see CSPI User's Guide in the
+documentation directory.  To learn how to use the library functions,
+see CSPI Reference in the documentation directory.
+
+Libera Electron: The src/test directory includes two sample data
+acquisition utilities called 'libera' and 'acquire'. The later is
+deprecated and may be removed in the future. Consider using 'libera'
+instead. To learn more about usage, run libera with option --help:
+
+  libera --help
+
+When run with option --acquire, the utility outputs one sample per
+line to standard output. The ordering and meaning of the values depend
+on the selected data source.
+
+With option --using-dd or --using-pm specified, each sample consists
+of eight whitespace separated integer values:
+
+  Va, Vb, Vc, Vd, X, Y, Sum, Q
+  or, with option --raw specified,
+  cosVa, sinVa, cosVb, sinVb, cosVc, sinVc, cosVd, sinVd
+
+With option --using-sa specified, each sample consists of ten
+whitespace separated integer values. Units (where applicable) are
+nanometers:
+
+  Va, Vb, Vc, Vd, X, Y, Sum, Q, Cx, Cy
+
+With option --using-adc specified, each sample consists of four
+whitespace separated integer values:
+
+  chA, chB, chC, chD
+
+With option --binary, data is not formatted as text and is instead
+output as a binary stream of samples, or more precisely, as a stream
+of 32-bit integer values (16-bit for ADC-rate data). This allows for
+faster acquisition and off-line processing (i.e. integration into an
+application such as Matlab).
+
+When run with option --set-environment, the utility reads Libera
+environment parameters from standard input. In this way, to set the
+Libera environment, use:
+
+  libera --set-environment < my_conf_file
+
+Sample environment and gain configuration files are included with the
+program. The later allows one to set analog board attenuators based on
+input power, using a predefined gain scheme.
+
+A configuration file should consist of parameters of a form:
+NAME VALUE
+
+The configuration file is line-based - that is, each
+newline-terminated line represents either a comment, or a
+parameter. Parameter names are case sensitive. Leading and trailing
+whitespace in parameter names and values is irrelevant and
+discarded. Any line beginning with a hash ('#') character is ignored,
+as are lines containing only whitespace.
+
+  libera --set-environment < env.conf
+This will set Libera environment parameters listed in the
+configuration file. See sample configuration file env.conf
+included with the utility for more information.
+
+  libera --acquire --on-trigger --using-dd 1000 > some_file
+This will acquire 1000 data-on-demand samples on trigger into
+some_file. The operation will time out after 30 seconds if no
+trigger is received.
+
+  libera --acquire --on-trigger --using-dd --with-timestamp \
+         --loop --raw 1000 > /dev/null
+This will acquire data-on-demand on trigger in a loop,
+discarding the data and printing a timestamp only on each
+iteration.
+
+  libera --set-time :200602091223.00
+This will set the system time (ST) at next trigger to Feb 09
+12:23:00 2006. Machine time (MT) will not change.
+
+Libera Bunch-by-Bunch: A sample data acquisition utility called
+'libera-bbfp' is included in the src/test directory. To learn more
+about usage, run libera-bbfp with option -h:
+
+  libera -h
+
+The utility outputs four samples per line to standard output.
+
+
+3. LIMITATIONS
+
+Libera Electron: The variable 'sum' of the CSPI_DD_ATOM structure
+returned by the cspi_read or cspi_read_ex has two least significant
+bits truncated to prevent an overflow.
+
+
+This version of CSPI has been developed and tested using:
+- gcc 3.4
+- Libera driver 1.80
+- FPGA design 1.80
diff --git a/i-tech/cspi/include/bbfp.h b/i-tech/cspi/include/bbfp.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd9c489c2f9755a91eb47f741b752fe48bdad55f
--- /dev/null
+++ b/i-tech/cspi/include/bbfp.h
@@ -0,0 +1,66 @@
+// $Id: bbfp.h,v 1.8 2006/12/07 08:33:45 ales Exp $
+
+//! \file bbfp.h
+//! Bunch-by-Bunch Feedback Processor (BBFP) specific definitions.
+
+#if !defined(_BBFP_H)
+#define _BBFP_H
+
+/** Libera BBFP Data on Demand (DD) raw sample. */
+typedef libera_sample_t CSPI_DD_RAWATOM;
+
+/** Libera BBFP Data on Demand (DD) sample. */
+typedef CSPI_DD_RAWATOM CSPI_DD_ATOM;
+
+/** Placeholder for CSPI types not used by the BBFP. */
+typedef void*  CSPI_NOTUSED;
+
+/** Not used. Declared for compatibility with CSPI only. */
+typedef CSPI_NOTUSED CSPI_SA_ATOM;
+
+/** Not used. Declared for compatibility with CSPI only. */
+typedef CSPI_NOTUSED CSPI_ADC_ATOM;
+
+//--------------------------------------------------------------------------
+
+/** Environment parameters or attributes. */
+struct tagCSPI_ENVPARAMS
+{
+	CSPI_ENVPARAMS_BASE;
+
+	// No BBFP specific parameters.
+};
+
+/*
+ * typedef enum
+ * {
+ * 	CSPI_ENV_			= CUSTOM_ENV_BIT(0),
+ * }
+ * CSPI_ENVFLAGS_BBFP;
+ */
+
+//--------------------------------------------------------------------------
+
+/** Derived from CSPI_CONPARAMS to handle DD specific
+ *  parameters or attributes for BBFP.
+ */
+typedef struct {
+	/** Common connection parameters. */
+	CSPI_CONPARAMS_BASE;
+
+	/** The number of bunches per turn. */
+	size_t step;
+}
+CSPI_CONPARAMS_DD;
+
+//--------------------------------------------------------------------------
+
+/** Bit flags corresponding to the CSPI_CONPARAMS_DD structure.
+ *  See CSPI_CONPARAMS_DD structure for descriptions.
+ */
+typedef enum {
+	CSPI_CON_STEP = CUSTOM_CON_BIT(0),
+}
+CSPI_CONFLAGS_DD;
+
+#endif	// _BBFP_H
diff --git a/i-tech/cspi/include/cordic.h b/i-tech/cspi/include/cordic.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0699a8b63b1ad71f8042a4ad1b30a46ea53ebbf
--- /dev/null
+++ b/i-tech/cspi/include/cordic.h
@@ -0,0 +1,18 @@
+// $Id: cordic.h,v 1.2 2005/10/28 10:06:29 miha Exp $
+
+//! \file cordic.h
+//! Public CORDIC declarations.
+
+#if !defined(_CORDIC_H)
+#define _CORDIC_H
+
+/** Private.
+ *  Calculates the amplitude from I and Q (sin and cos) value.
+ *  Returns amplitude.
+ *
+ *  @param I I (sin) component of the amplitude.
+ *  @param Q Q (cos) component of the amplitude.
+ */
+int cordic_amp( int I, int Q );
+
+#endif	// _CORDIC_H
diff --git a/i-tech/cspi/include/cspi.h b/i-tech/cspi/include/cspi.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7379400745dd712d22fd3f573235c75ed728192
--- /dev/null
+++ b/i-tech/cspi/include/cspi.h
@@ -0,0 +1,849 @@
+// $Id: cspi.h,v 1.40 2007/11/09 09:34:37 tomazb Exp $
+
+//! \file cspi.h
+//! Public CSPI header file.
+
+#if !defined(_CSPI_H)
+#define _CSPI_H
+
+#include <sys/types.h>	// size_t definition
+#include <unistd.h>		// SEEK_* definitions
+
+#include "libera.h"		// public driver interface
+
+#if !defined(CSPI_VER)
+/** CSPI version. */
+#define CSPI_VER 0x0010
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------------
+// Error handling.
+
+/** Warning codes returned by the CSPI functions.
+ *  See warn_list[] for a list of coresponding descriptions.
+ */
+enum {
+	/** Success (not a warning). */
+	CSPI_OK = 0,
+
+	/** Partially completed request. */
+	CSPI_W_INCOMPLETE,
+};
+
+/** Error codes returned by the CSPI functions.
+ *  See err_list[] for a list of coresponding descriptions.
+ *
+ *  Note: CSPI_E_SYSTEM error is returned when a system-level call
+ *  inside a CSPI function fails. Additional information about the
+ *  error can be obtained by inspecting the errno value immediately
+ *  after the call that returned CSPI_E_SYSTEM.
+ */
+enum {
+	/** Unknown error. */
+	CSPI_E_UNKNOWN = -1,
+
+	/** Invalid handle. */
+	CSPI_E_INVALID_HANDLE = -2,
+
+	/** Invalid function call sequence. */
+	CSPI_E_SEQUENCE = -3,
+
+	/** Invalid function parameter. */
+	CSPI_E_INVALID_PARAM = -4,
+
+	/** System-level call failed. */
+	CSPI_E_SYSTEM = -5,
+
+	/** Invalid mode of operation or mode not set. */
+	CSPI_E_INVALID_MODE = -6,
+
+	/** Illegal CSPI call. */
+	CSPI_E_ILLEGAL_CALL = -7,
+
+	/** Failed to allocate memory. */
+	CSPI_E_MALLOC = -8,
+
+	/** Driver version mismatch. */
+	CSPI_E_VERSION = -9,
+
+	/** DSC server protocol error. */
+	CSPI_E_DSCPROTO = -10,
+};
+
+/** Maximum length of the error description string. */
+#define CSPI_MAX_MSG_LEN 256
+
+/** \brief Returns string describing error code.
+ *
+ *  The function returns the appropriate error description string,
+ *  or the unknown error message if the error code is unknown.
+ *  \param errnum Error code.
+ */
+const char* cspi_strerror(int errnum);
+
+//--------------------------------------------------------------------------
+// Async. event section.
+
+/** Libera asynchronous events. */
+typedef enum {
+	/** User defined event. */
+	CSPI_EVENT_USER			= LIBERA_EVENT_USER,
+
+	/** Low-level fifo overflow. */
+	CSPI_EVENT_OVERFLOW		= LIBERA_EVENT_OVERFLOW,
+
+	/** Configuration change. */
+	CSPI_EVENT_CFG			= LIBERA_EVENT_CFG,
+
+	/** Slow Acq. (SA) sample available. */
+	CSPI_EVENT_SA			= LIBERA_EVENT_SA,
+
+	/** Interlock fired. */
+	CSPI_EVENT_INTERLOCK	= LIBERA_EVENT_INTERLOCK,
+
+	/** Post Mortem trigger. */
+	CSPI_EVENT_PM			= LIBERA_EVENT_PM,
+
+	/** Fast Application trigger. */
+	CSPI_EVENT_FA			= LIBERA_EVENT_FA,
+
+	/** GET Trigger trigger. */
+	CSPI_EVENT_TRIGGET		= LIBERA_EVENT_TRIGGET,
+
+	/** SET Trigger trigger. */
+	CSPI_EVENT_TRIGSET		= LIBERA_EVENT_TRIGSET,
+}
+CSPI_EVENTMASK;
+
+/** Event specific values for CSPI_EVENT_OVERFLOW. */
+enum {
+	/** Data on Demand (DD) fifo overflow in FPGA. */
+	CSPI_OVERFLOW_DD_FPGA = LIBERA_OVERFLOW_DD_FPGA,
+
+	/** Slow Acq. (SA) fifo overflow in FPGA. */
+	CSPI_OVERFLOW_SA_FPGA = LIBERA_OVERFLOW_SA_FPGA,
+
+	/** Slow Acq. (SA) fifo overflow in driver. */
+	CSPI_OVERFLOW_SA_DRV  = LIBERA_OVERFLOW_SA_DRV,
+};
+
+/** Event specific values for event CSPI_EVENT_FA. */
+enum {
+	/** Fast Acq. (FA) MC trigger #0. */
+	CSPI_TRIG_FA_MC0 = LIBERA_TRIG_FA_MC0,
+
+	/** Fast Acq. (FA) MC trigger #1. */
+	CSPI_TRIG_FA_MC1 = LIBERA_TRIG_FA_MC1,
+
+	/** Fast Acq. (FA) SC trigger #0. */
+	CSPI_TRIG_FA_SC0 = LIBERA_TRIG_FA_SC0,
+
+	/** Fast. Acq. (FA) SC trigger #1. */
+	CSPI_TRIG_FA_SC1 = LIBERA_TRIG_FA_SC1,
+};
+
+/** Groups all async. notification events. */
+#define CSPI_NOTICEMASK		(CSPI_EVENT_SA|CSPI_EVENT_INTERLOCK)
+
+/** Groups all async. error events. */
+#define CSPI_ERRORMASK		(CSPI_EVENT_OVERFLOW)
+
+/** Groups all async. trigger events. */
+#define CSPI_TRIGGERMASK	(CSPI_EVENT_PM|CSPI_EVENT_FA|CSPI_EVENT_TRIGGET|\
+	                         CSPI_EVENT_TRIGSET)
+
+/** Represents async. event header.
+ *  CSPI_EVENTHDR is simply a synonim for the type employed in the Libera
+ *  driver to represent async. event. 
+ *
+ *  This structure is used to pass information about an asynchronous event
+ *  signaled by the driver, such as event id and event specific value or
+ *  code. CSPI provides this information as part of the larger CSPI_EVENT
+ *  structure.
+ *
+ *  See libera.h for more information on member variables and a list of
+ *  possible values.
+ */
+typedef libera_event_t CSPI_EVENTHDR;
+
+/** Represents async. event.
+ *  This structure expands the CSPI_EVENTHDR with a pointer to arbitrary
+ *  data to pass to the event handler each time it is called. This parameter
+ *  is not interpreted in any way by the CSPI.
+ */
+typedef struct {
+	/** Event header. */
+	CSPI_EVENTHDR hdr;
+	/** Pointer to user data set with the cspi_setconparam. */
+	void *user_data;
+} CSPI_EVENT;
+
+/** Type definition for event handler.
+ *  To inform application about an async. event in the underlying
+ *  layers, an event handler for each connection is called.
+ *
+ *  To dispatch event to the next connection in row, the handler
+ *  should return a non-zero value. To stop dispatching the event,
+ *  the handler should return 0.
+ *
+ *  @param msg Pointer to event structure.
+ */
+typedef int (*CSPI_EVENTHANDLER)( CSPI_EVENT *msg );
+
+//--------------------------------------------------------------------------
+// Handle related section.
+
+/** Generic handle type. */
+typedef void *		CSPIHANDLE;
+
+/** Environment handle type.
+ *  Environment handle represents a global context for all Libera
+ *  operations. An environment handle is implemented in a thread-safe manner.
+ *  Each connection on the environment can thus run in its own thread.
+ */
+typedef CSPIHANDLE	CSPIHENV;
+
+/** Connection handle type.
+ *  Connection handle represents a connection to a particular data
+ *  source in the Libera. A connection handle is not thread safe and should
+ *  not be shared among threads.
+ */
+typedef CSPIHANDLE	CSPIHCON;
+
+//! Handle type identifiers.
+enum {
+	CSPI_HANDLE_ENV = 1,	//!< Environment handle.
+	CSPI_HANDLE_CON,		//!< Connection handle.
+};
+
+/** Used to represent a bitmask. */
+typedef size_t CSPI_BITMASK;
+
+/** \brief Allocate an environment or connection handle.
+ *
+ *  This function is a generic function for allocating handles.
+ *  Returns CSPI_OK on success or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param type Type of handle to allocate. Must be one of the
+ *              following values: CSPI_HANDLE_ENV or CSPI_HANDLE_CON.
+ *  \param h    Input handle as a context for the new handle to
+ *              allocate. Set to 0 if 'type' is CSPI_HANDLE_ENV.
+ *              Must be an environment handle, if 'type' is CSPI_HANDLE_CON.
+ *  \param p    Pointer to a buffer in which to return the handle to the
+ *              newly allocated data structure.
+ */
+int cspi_allochandle( int type, CSPIHANDLE h, CSPIHANDLE* p );
+
+/** \brief Free an environment or connection handle.
+ *
+ *  This function is a generic function for freeing handles. It frees the
+ *  resources associated with a specific environment or connection handle.
+ *
+ *  Prior to calling cspi_freehandle with a handle type of CSPI_HANDLE_ENV,
+ *  an application must free all connections allocated on the environment.
+ *  Otherwise, the function returns CSPI_E_SEQUENCE and the environment and
+ *  any active connection remain valid.
+ *
+ *  Prior to calling cspi_freehandle with a handle type of CSPI_HANDLE_CON,
+ *  an application must disconnect from data source with cspi_disconnect (if
+ *  there is a connection on this handle). Otherwise, the function returns
+ *  SQL_E_SEQUENCE and the connection remains valid.
+ *
+ *  Returns CSPI_OK on success or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param type Type of handle to free. Must be one of the following
+ *              values: CSPI_HANDLE_ENV or CSPI_HANDLE_CON.
+ *  \param h    The handle to be freed.
+ */
+int cspi_freehandle( int type, CSPIHANDLE h );
+
+//--------------------------------------------------------------------------
+// Library related section.
+
+/** CSPI library parameters or attributes. */
+typedef struct {
+	/** CSPI version the application confirms to (R/W). NOT USED! */
+	int version;
+	/** Superuser flag: 0 (the default) or 1 (R/W). */
+	int superuser;
+}
+CSPI_LIBPARAMS;
+
+/** Helper macro for bitmasks. */
+#define BIT(n)	(1 << (n))
+
+/** Bitmasks corresponding to the CSPI_LIBPARAMS structure.
+ *  See also CSPI_LIBPARAMS structure for descriptions.
+ */
+typedef enum {
+	CSPI_LIB_VERSION	= BIT(0),	//!< CSPI version flag.
+	CSPI_LIB_SUPERUSER	= BIT(1),	//!< CSPI superuser flag.
+}
+CSPI_LIBFLAGS;
+
+/** \brief Set the CSPI module parameters.
+ *
+ *  For a list of parameters, see CSPI_LIBPARAMS. To request exclusive
+ *  write access to Libera environment and common (global) parameters,
+ *  the superuser field of the CSPI_LIBPARAMS structure should be set
+ *  to 1.
+ *
+ *  The superuser value is stored but does not step in effect until
+ *  an environment handle (a global context for Libera operations) is
+ *  actually allocated.
+ *
+ *  The version must be set to CSPI_VER.
+ *
+ *  All successfully set parameters persist until the environment handle
+ *  is released.
+ *
+ *  Returns CSPI_OK on success or CSPI_E_INVALID_PARAM if an error occurred.
+ *
+ *  @param p      Pointer to the CSPI_LIBPARAMS structure with values
+ *                to set.
+ *  @param flags  Bitmask specifying which parameters to set. This can be
+ *                any combination of the CSPI_LIBFLAGS, for instance
+ *                CSPI_LIB_VERSION | CSPI_LIB_SUPERSUER.
+ */
+int cspi_setlibparam( const CSPI_LIBPARAMS *p, CSPI_BITMASK flags );
+
+/** \brief Retrieve the CSPI module parameters.
+ *
+ *  For a list of parameters, see CSPI_LIBPARAMS. Note that parameter
+ *  values returned are those that are stored by the CSPI library and
+ *  may not be in effect. See cspi_setlibparam for more information.
+ *
+ *  Returns CSPI_OK.
+ *
+ *  @param p     Pointer to the CSPI_LIBPARAMS structure in which to return
+ *               results.
+ *  @param flags Bitmask specifying which parameters to retrieve. This can
+ *               be any combination of the CSPI_LIBFLAGS, for instance
+ *               CSPI_LIB_VERSION | CSPI_LIB_SUPERSUER.
+ */
+int cspi_getlibparam( CSPI_LIBPARAMS *p, CSPI_BITMASK flags );
+
+//--------------------------------------------------------------------------
+// Configuration section.
+
+/** Available TRIGGER trigger modes. */
+typedef enum {
+	/** Trigger mode not set. */
+	CSPI_TRIGMODE_UNKNOWN	= LIBERA_TRIGMODE_UNKNOWN,
+	/** GET Trigger trigger. */
+	CSPI_TRIGMODE_GET		= LIBERA_TRIGMODE_GET,
+	/** 'SET Trigger trigger. */
+	CSPI_TRIGMODE_SET		= LIBERA_TRIGMODE_SET,
+}
+CSPI_TRIGMODE;
+
+// fwd decl -- reqr'd to declare pub. CSPI func. cspi_set/getenvparam
+struct tagCSPI_ENVPARAMS;
+
+/** Represents environment parameters.
+ *  The actual tagCSPI_ENVPARAMS structure is Libera family member specific
+ *  and defined in a corresponding member-specific header.
+ */
+typedef struct tagCSPI_ENVPARAMS CSPI_ENVPARAMS;
+
+/** Represents CSPI health environment parameters.
+ *  Temperature, fans & PS voltages.
+ */
+typedef struct {
+    int temp;
+    int fan[2];
+    int voltage[8];
+}
+cspi_health_t;
+
+/** Represents CSPI PLL status environment parameters. */
+typedef struct {
+    unsigned long sc;
+    unsigned long mc;
+}
+cspi_pll_t;
+
+/** Represents features implemented in FPGA design. */
+typedef struct {
+    unsigned long customer;
+    unsigned long itech;
+}
+cspi_feature_t;
+
+/** Declares environment parameters common to all members of the Libera
+ *  family. Derived structures use this macro to declare 'base' members.
+ */
+#define CSPI_ENVPARAMS_BASE \
+	/** Health info. Temperature, fans & PS voltages. */ \
+	cspi_health_t health; \
+	/** PLL status. */ \
+	cspi_pll_t pll; \
+	/** Trigger mode. See enum CSPI_TRIGGER (R/W). */ \
+	int trig_mode; \
+    /** Feature registers stored in FGA design (RO). */ \
+    cspi_feature_t feature;
+
+/** Bitmasks corresponding to the common environment parameters.
+ *  See CSPI_ENVPARAMS structure and CSPI_ENVPARAMS_BASE macro for more 
+ *  information.
+ */
+typedef enum {
+	CSPI_ENV_HEALTH 	= BIT(0),
+	CSPI_ENV_TRIGMODE	= BIT(1),
+	CSPI_ENV_PLL    	= BIT(2),
+    CSPI_ENV_FEATURE    = BIT(3),
+}
+CSPI_ENVFLAGS;
+
+/** Helper macro to define custom environment bitmasks. */
+#define CUSTOM_ENV_BIT(n)	BIT(4 + n)
+
+
+/** \brief Set environment parameters.
+ *
+ *  For a list of parameters, see CSPI_ENVPARAMS. Note that parameters such
+ *  as X and Y interlock are read-only and their value cannot be set.
+ *  All successfully set environment parameters persist until the
+ *  cspi_freehandle is called on the environment.
+ *
+ *  Returns CSPI_OK on success or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param h     Environment handle.
+ *  \param p     Pointer to CSPI_ENVPARAMS structure with values to set.
+ *  \param flags Bitmask specifying which parameters to set. This can be any
+ *               combination of the CSPI_ENVFLAGS and Libera family member
+ *               specific environment flags, for instance
+ *               CSPI_ENV_TRIGMODE | CSPI_ENV_KX | CSPI_ENV_KY.
+ */
+int cspi_setenvparam( CSPIHENV h, const CSPI_ENVPARAMS *p, CSPI_BITMASK flags );
+
+/** \brief Retrieve current environment settings.
+ *
+ *  For a list of parameters, see CSPI_ENVPARAMS. Cspi_getenvparam can be
+ *  called at any time between the time an environment handle is allocated
+ *  and freed. All successfully set environment parameters persist until
+ *  cspi_freehandle is called on the environment.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param h     Environment handle.
+ *  \param p     Pointer to CSPI_ENVPARAMS structure in which to return
+ *               results.
+ *  \param flags Bitmask specifying which parameters to retrieve. This can
+ *               be any combination of the CSPI_ENVFLAGS and Libera family
+ *               member specific environment flags, for instance
+ *               CSPI_ENV_TRIGMODE | CSPI_ENV_XINTERLOCK.
+ */
+int cspi_getenvparam( CSPIHENV h, CSPI_ENVPARAMS *p, CSPI_BITMASK flags );
+
+/** \brief Set Fast Application (FA) parameters.
+ *
+ *  Writes 'count' elements of data, each 'size' bytes long, to the 
+ *  configuration block of the FA interface. Note that data is not
+ *  interpreted in any way by the CSPI. Cspi_setenvparams_fa merely
+ *  provides a configuration channel for the fast application embedded
+ *  in the FPGA.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *  
+ *  Size of element must be aligned on a 4-byte boundary!
+ *
+ * @param h      Environment handle.
+ * @param offset Offset from the beginning of the FA config. block.
+ * @param pbuf   Pointer to data to write..
+ * @param size   Size of a data element.
+ * @param count  Number of data elements.
+ */
+int cspi_setenvparam_fa( CSPIHENV h, size_t offset,
+                         const void *pbuf, size_t size, size_t count );
+
+/** \brief Retrieve current Fast Application (FA) parameters.
+ *
+ *  Reads 'count' elements of data, each 'size' bytes long, from the
+ *  configuration block of the FA interface.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  Size of element must be aligned on a 4-byte boundary!
+ *
+ * @param h      Environment handle.
+ * @param offset Offset from the beginning of the FA config. block.
+ * @param pbuf   Pointer to destination to retrieve the data to.
+ * @param size   Size of a data element.
+ * @param count  Number of data elements.
+ */
+int cspi_getenvparam_fa( CSPIHENV h, size_t offset,
+                         void *pbuf, size_t size, size_t count );
+
+/** Available Libera modes of operation.
+ *  Note: only a subset may apply to a Libera family member.
+ */
+typedef enum {
+	/** Mode of operation not set. */
+	CSPI_MODE_UNKNOWN = LIBERA_MODE_UNKNOWN,
+
+	/** Data-on-Demand (DD) mode. */
+	CSPI_MODE_DD = LIBERA_MODE_DD,
+
+	/** Slow Acquisition (SA) mode. */
+	CSPI_MODE_SA = LIBERA_MODE_SA,
+
+	/** Post-Mortem (PM) mode. */
+	CSPI_MODE_PM = LIBERA_MODE_PM,
+
+	/** ADC-rate data (ADCRD) mode. */
+	CSPI_MODE_ADC = LIBERA_MODE_ADC,
+}
+CSPI_MODE;
+
+/** Declares connection parameters common to all members of the Libera
+ *  family. Derived structures use this macro to declare 'base' members.
+ */
+#define CSPI_CONPARAMS_BASE \
+	/** Mode of operation. See CSPI_MODE for a list of available modes. */ \
+	int mode; \
+	/** Event handler. */ \
+	CSPI_EVENTHANDLER handler; \
+	/** User data passed to the handler on each call. */ \
+	void *user_data; \
+	/** Event mask. */ \
+	CSPI_BITMASK event_mask
+
+/** Common connection parameters or attibutes.
+ *  Derived, connection-specific structures add additional members.
+ */
+typedef struct {
+	CSPI_CONPARAMS_BASE;
+}
+CSPI_CONPARAMS;
+
+/** Bitmasks corresponding to the CSPI_CONPARAMS structure.
+ *  See CSPI_CONPARAMS structure and CSPI_CONPARAMS_BASE macro for
+ *  descriptions.
+ */
+typedef enum {
+	CSPI_CON_MODE		= BIT(0),
+	CSPI_CON_HANDLER	= BIT(1),
+	CSPI_CON_USERDATA	= BIT(2),
+	CSPI_CON_EVENTMASK	= BIT(3),
+/*	CSPI_CON_reserved	= BIT(4) - BIT(7), */
+}
+CSPI_CONFLAGS;
+
+/** Helper macro to define custom connection bitmasks. */
+#define CUSTOM_CON_BIT(n)	BIT(8 + n)
+
+/** \brief Set connection parameters.
+ *
+ *  For a list of parameters, see CSPI_CONPARAMS and derived structures.
+ *
+ *  CSPI_CONPARAMS structure represents parameters common to all types
+ *  of connections. Depending on the mode of operation and Libera family
+ *  member, additional connection parameters may be available.
+ *  In this case, an application should call cspi_setconparam with a pointer
+ *  to the appropriate CSPI_CONPARAMS-derived structure instead.
+ *
+ *  See the Libera family member specific header file for information on
+ *  available connection parameters.
+ *
+ *  All CSPI_CONPARAMS-derived structures begin with CSPI_CONPARAMS and
+ *  then add connection specific parameters.
+ *
+ *  An application can call cspi_setconparam at any time between the time
+ *  a connection is opened and closed with cspi_connect and cspi_disconnect,
+ *  respectively. All successfully set CSPI_CONPARAMS parameters persist until
+ *  cspi_freehandle is called on the connection. All other successfully set
+ *  connection parameters related to the undelying hardware persist even after
+ *  an application terminates.
+ *
+ *  Note: event mask can be set at any time, but will only be activated when
+ *        the event handler is set!
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param h     Connection handle.
+ *  \param p     Pointer to the CSPI_CONPARAMS or CSPI_CONPARAMS-derived
+ *               structure with values to set.
+ *  \param flags Bitmask specifying which parameters to set. This can be any
+ *               combination of CSPI_CONFLAGS and flags for the
+ *               CSPI_CONPARAMS-derived structure.
+ *               Example: CSPI_CON_MODE | CSPI_CON_HANDLER.
+ *
+ */
+int cspi_setconparam( CSPIHCON h, const CSPI_CONPARAMS *p, CSPI_BITMASK flags );
+
+/** \brief Retrieve connection parameters.
+ *
+ *  See cspi_setconparam for more information.
+ *
+ *  Returns CSPI_OK on success, CSPI_W_REPEAT on partial success,
+ *  or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_E_SYSTEM.
+ *
+ *  \param h     Connection handle.
+ *  \param p     Pointer to the CSPI_CONPARAMS or CSPI_CONPARAMS-derived
+ *               structure to fill in.
+ *  \param flags Bitmask specifying which parameters to retrieve. This can
+ *               be any combination of CSPI_CONFLAGS and flags for the
+ *               CSPI_CONPARAMS-derived structure.
+ *               CSPI_CONFLAGS_FF if p points to CSPI_CONPARAMS_FF,
+ *               CSPI_CONFLAGS_BN if p points to CSPI_CONPARAMS_BN.
+ *               Example: CSPI_CON_MODE | CSPI_CON_HANDLER.
+ */
+int cspi_getconparam( CSPIHCON h, CSPI_CONPARAMS *p, CSPI_BITMASK flags );
+
+//--------------------------------------------------------------------------
+// Data retrieval section.
+
+/** \brief Connect to a Libera data source.
+ *
+ *  This function opens a Libera device file for reading and associates
+ *  it with given connection handle.
+ *  Note: device file to open is determined based on mode of operation.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_MODE,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_E_SYSTEM.
+ *
+ * \param h  Connection handle.
+ */
+int cspi_connect( CSPIHCON h );
+
+/** \brief Disconnect from a Libera data source.
+ *
+ *  This function disconnects from and closes the device file associated
+ *  with given connection handle.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_SYSTEM.
+ *
+ * \param h Connection handle.
+ */
+int cspi_disconnect( CSPIHCON h );
+
+/** Defines available time formats for cspi_seek. */
+typedef enum {
+	CSPI_SEEK_MT = SEEK_CUR,	//!< Machine time.
+	CSPI_SEEK_ST = SEEK_SET,	//!< System time.
+	CSPI_SEEK_TR = SEEK_END,	//!< Trigger time.
+} CSPI_SEEK;
+
+/** \brief Reposition read offset.
+ *
+ *  This function sets current data retrieval point (offset) in the History
+ *  Buffer for Data on Demand (DD) and Post Mortem (PM) modes of operation.
+ *  Cannot be used with a streaming data source such as Slow Acq. (SA).
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_INVALID_PARAM,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_E_SYSTEM.
+ *
+ *  Note: for diagnostic purposes, if origin is CSPI_SEEK_ST and offset
+ *  is set to 0, current system time is used instead.
+ *
+ *  @param h      Connection handle.
+ *  @param offset Pointer to a 64-bit integer representing the data 
+ *                retrieval point to seek. The function should be passed 
+ *                a pointer to struct timespec or a pointer to 64-bit 
+ *                integer value, depending on whether origin is CSPI_SEEK_ST 
+ *                or CSPI_SEEK_MT, respectively.
+ *  @param origin Time format used in specifying the data retrieval point.
+ *                Must be of type CSPI_SEEK. If set to CSPI_SEEK_TR, the
+ *                offset parameter is ignored and current retrieval point
+ *                is set to the time of last trigger instead.
+ */
+int cspi_seek( CSPIHCON h, unsigned long long *offset, int origin );
+
+/** Calls cspi_read_ex with a predefined, default auxiliary function to
+ *  transform a Data On Demand (DD) sample from raw (CSPI_DD_RAWATOM) to
+ *  synthetic (CSPI_DD_ATOM) format.
+ *
+ *  See cspi_read_ex and structures CSPI_DD_RAWATOM, CSPI_DD_ATOM for
+ *  more information about parameters and return values.
+ *  Example for EBPP:
+ *
+ *  Mode of operation | Default action
+ *  ---------------------------------------------------------------
+ *  DD, PM              convert I,Q vals to amplitudes and position
+ *  SA, ADC             do nothing
+ *
+ *  @param h     Connection handle.
+ *  @param dest  Pointer to destination buffer to receive data.
+ *               The buffer must be large enough to accomodate the 
+ *               requested number of samples.
+ *  @param count Number of samples to copy.
+ *  @param nread Pointer to size_t to recieve the number of samples
+ *               actually copied.
+ */
+int cspi_read( CSPIHCON h, void *dest, size_t count, size_t *nread );
+
+/** Represents auxiliary fuction to pass to the cspi_read_ex. */
+typedef int (*CSPI_AUX_FNC)( const void *in, void *out );
+
+/** \brief Read from Data on Demand (DD) device.
+ *
+ *  Attempts to read a specified number of samples from a non-
+ *  streaming data device such as History Buffer (DD mode), PM Buffer
+ *  (PM mode) or ADC-rate Data Buffer (ADC mode).
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_E_MALLOC,
+ *  CSPI_E_SYSTEM,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_W_INCOMPLETE (warning, not an error).
+ *
+ *  Cspi_read_ex is an extension of the cspi_read function.
+ *  An application can call cspi_read_ex any time between the time a
+ *  connection is opened and closed with cspi_connect ans cspi_disconnect,
+ *  respectively.
+ *
+ *  @param h     Connection handle.
+ *  @param dest  Pointer to destination buffer to receive data.
+ *               The buffer must be large enough to accomodate the 
+ *               requested number of samples.
+ *  @param count Number of samples to copy.
+ *  @param nread Pointer to size_t to recieve the number of samples
+ *               actually copied.
+ *  @param op    Auxiliary function to apply to each sample before copying
+ *               it to the destination buffer. Can be used to perform
+ *               a custom transformation on each sample. The function
+ *               should return 0 on success or a non-zero value to stop
+ *               the processing. If 0 is passed instead of a function, no
+ *               transformation takes place and raw samples are read into
+ *               the destination buffer.
+ *
+ */
+int cspi_read_ex( CSPIHCON h, void *dest, size_t count, size_t *nread,
+                  CSPI_AUX_FNC op  );
+
+/** Represents a timestamp -- a (System Time, Machine Time) pair. */
+typedef libera_timestamp_t CSPI_TIMESTAMP;
+
+/** Represents a high resolution (set)timestamp -- System Time, Machine Time + offset. */
+typedef libera_HRtimestamp_t CSPI_SETTIMESTAMP;
+
+/** \brief Retrieve a timestamp.
+ *
+ *  Retrieves a timestamp associated with the last successfull cspi_read
+ *  or cspi_read_ex call.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_E_SEQUENCE.
+ *
+ *  @param h  Connection handle.
+ *  @param ts Pointer to the CSPI_TIMESTAMP structure to receive the
+ *            timestamp of the first sample in a vector of samples
+ *            returned by the last successfull cspi_read or cspi_read_ex
+ *            call.
+ */
+int cspi_gettimestamp( CSPIHCON h, CSPI_TIMESTAMP *ts );
+
+/** \brief Read from Slow Acquisition (SA) device.
+ *
+ *  Attempts to read a single SA sample into a user specified buffer.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_E_ILLEGAL_CALL,
+ *  CSPI_E_SEQUENCE,
+ *  CSPI_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  An application can call cspi_get any time between the time a
+ *  connection is opened and closed with cspi_connect and cspi_disconnect,
+ *  respectively.
+ *
+ *  @param h     Connection handle.
+ *  @param atom  Pointer to the destination buffer to fill in.
+ */
+int cspi_get( CSPIHCON h, void *atom );
+
+//--------------------------------------------------------------------------
+// Sync. event section.
+
+/** Available time formats. */
+typedef enum {
+	CSPI_TIME_MT = BIT(0),	//!< Machine time.
+	CSPI_TIME_ST = BIT(1),	//!< System time.
+}
+CSPI_TIMEFLAGS;
+
+/** \brief Synchronize time on Libera.
+ *
+ *  Sets the machine time and/or system time on Libera at next 'SET'
+ *  TRIGGER trigger.
+ *
+ *  Note: 'SET' TRIGGER trigger is a one-shot trigger. That is, after
+ *        the TRIGGER trigger, the old trigger mode is restored again.
+ *
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_HANDLE,
+ *  CSPI_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  @param h     Environment handle.
+ *  @param ts    Pointer to CSPI_TIMESTAMP structure with time to set.
+ *  @param flags Bitmask specifying which time to set. This can be
+ *               any combination of CSPI_TIMEFLAGS flags.
+ */
+int cspi_settime( CSPIHENV h, CSPI_SETTIMESTAMP *ts, CSPI_BITMASK flags );
+
+#if defined(EBPP)
+#include "ebpp.h"		// EBPP-specific declarations
+#elif defined(BBFP)
+#include "bbfp.h"		// BBFP-specific declarations
+#elif defined(HBPP)
+#include "hbpp.h"		// HBPP-specific declarations
+#else
+#error Must define Libera family member!
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	// _CSPI_H
diff --git a/i-tech/cspi/include/cspi_impl.h b/i-tech/cspi/include/cspi_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..50f71a79f370132504fdd39e0dd99e795d6cecf3
--- /dev/null
+++ b/i-tech/cspi/include/cspi_impl.h
@@ -0,0 +1,559 @@
+// $Id: cspi_impl.h,v 1.11 2007/10/09 15:25:26 tomazb Exp $
+
+//! \file cspi_impl.h
+//! Private (implementation specific) CSPI structs and functions.
+
+#if !defined(_CSPI_IMPL_H)
+#define _CSPI_IMPL_H
+
+#include <signal.h>
+#include <pthread.h>
+
+#include "debug.h"
+
+#if !defined(_CSPI_H)
+#error ERROR: Include cspi.h first!
+#endif	// _CSPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Typedef representing a byte. */
+typedef unsigned char byte;
+
+//--------------------------------------------------------------------------
+// Notification section.
+
+/** Private.
+ *  Signal handler type definition.
+ *  Assumption: the signal and accompanying information is sent
+ *  using the sigqueue function.
+ */
+typedef void (*SIGACTION)(int, siginfo_t *, void *);
+
+/** Private.
+ *  One and only signal handler.
+ *  Handles LIBERA_SIGNAL and dispatches event to all
+ *  connections with a registered event handler.
+ *
+ *  @param signum  See sigaction man page or glibc documentation.
+ *  @param si      See sigaction man page or glibc documentation.
+ *  @param notused See sigaction man page or glibc documentation.
+ */
+void signal_handler( int signum, siginfo_t *si, void *notused );
+
+/** Private.
+ *  Allows member-specific code to hook into the signal handler.
+ *
+ *  @param p Pointer to CSPI_EVENTHDR structure.
+ */
+void signal_handler_hook( const CSPI_EVENTHDR *p );
+
+/** Private.
+ *  Resets LIBERA_SIGNAL action to system default action.
+ *  See glibc sigaction for information on return values.
+ */
+int reset_sighandler();
+
+//--------------------------------------------------------------------------
+// Internal environment and connection related section.
+
+/** Private. Represents global CSPI library parameters. */
+typedef struct tagLibrary {
+	/** CSPI version the application confirms to (R/W). */
+	int version;
+	/** Super user flag: 0 or 1 (R/W). */
+	int superuser;
+} Library;
+
+/** Private. Magic numbers. */
+typedef enum {
+	MAGIC_ENV = 230799,	//!< Environment magic.
+	MAGIC_CON = 230271,	//!< Connection magic.
+} MAGIC;
+
+/** Typedef. See struct tagConnection for more information. */
+typedef struct tagConnection Connection;	// forward decl
+
+/** Private.
+ *  Environment represents a global context in which to retrieve data.
+ *  With the environment is associated data that is global in nature or
+ *  common to all connections on that environment.
+ *
+ *  Changes to the environment are implemented in a thread-safe manner.
+ *  Thus, each connection on the environment can run in its own thread.
+ */
+typedef struct tagEnvironment {
+	MAGIC type_id;				//!< Magic number.
+	size_t usage_count;			//!< Usage (reference) count.
+	pthread_mutex_t mutex;		//!< Protects from concurrent modifications.
+	SIGACTION sigaction;		//!< Signal handler.
+	size_t connection_count;	//!< Number of connections on the environment.
+	Connection *head;			//!< Connection list.
+	int fd;						//!< Configuration device file descriptor.
+	int trig_mode;				//!< Trigger mode.
+	Library module;				//!< Global CSPI module parameters.
+} Environment;
+
+/** Private.
+ *  Declares one and only environment instance. Shared by all connections.
+ */
+extern Environment environment;
+
+/** Private.
+ *  Connection structure represents a connection to the specific Libera
+ *  data source, for instance Data On Demand (DD).
+ *  Assumption: a connection is not shared between threads!
+ */
+struct tagConnection {
+	MAGIC type_id;				//!< Magic number.
+	int connection_id;			//!< Unique connection id.
+	int mode;					//!< Mode of operation (see CSPI_MODE).
+	int fd;						//!< Device file descriptor.
+	int pid;					//!< Pid to register with the event daemon.
+	CSPI_BITMASK event_mask;	//!< Event mask to register with the evet daemon.
+	CSPI_EVENTHANDLER handler; 	//!< Notification message handler.
+	void *user_data;			//!< User data passed to handler on each call.
+	CSPI_TIMESTAMP timestamp;	//!< Time stamp of the last DD read.
+	Environment *environment;	//!< Environment that owns the connection.
+	Connection *next;			//!< Next object in the connection list.
+	Connection *prev;			//!< Previous object in the connection list.
+};
+
+//--------------------------------------------------------------------------
+// Validation section.
+
+/** Private.
+ *  Validates environment handle.
+ *  Returns 1 if h points to an environment structure, 0 otherwise.
+ *  @param h Handle to test.
+ */
+static inline int is_henv( CSPIHANDLE h )
+{
+	ASSERT( h == &environment );
+	return h && ( MAGIC_ENV == ((Environment*) h)->type_id );
+}
+
+/** Private.
+ *  Validates connection handle.
+ *  Returns 1 if h points to a connection structure, 0 otherwise.
+ *  @param h Handle to test.
+ */
+static inline int is_hcon( CSPIHANDLE h )
+{
+	return h && ( MAGIC_CON == ((Connection*) h)->type_id );
+}
+
+/** Private.
+ *  Returns 1 if mode represents a streaming data source,
+ *  for instance Slow Acq. (SA).
+ *  @param mode Mode to test.
+ */
+static inline int is_streamingmode( const int mode )
+{
+	return CSPI_MODE_SA  == mode;
+}
+
+//--------------------------------------------------------------------------
+// Validation section -- cont'd:
+// Used by address and thus not declared inline.
+
+/** Private.
+ *  Validates mode of operation.
+ *  Returns 1 on success, or 0 if p represents invalid or unknown
+ *  (CSPI_MODE_UNKNOWN) mode of operation.
+ *  @param p Pointer to mode to validate.
+ */
+int is_validmode( const void *p );
+
+/** Private.
+ *  Validates trigger mode.
+ *  Returns 1 on success, or 0 if p represents invalid or unknown
+ *  (CSPI_TRIGMODE_UNKNOWN) mode of operation.
+ *  @param p Pointer to trigger mode to validate.
+ */
+int is_validtrigmode( const void *p );
+
+/** Private.
+ *  Validates CSPI version.
+ *  Returns 1 on success, or 0 otherwise.
+ *  @param p Pointer to version number to validate.
+ */
+int is_validversion( const void *p );
+
+//--------------------------------------------------------------------------
+// Internal environment and connection related section.
+
+/** Private.
+ *  Allocates environment handle.
+ *  Returns CSPI_OK on success, or one of the values returned
+ *  by custom_initenv otherwise.
+ *  @param p Pointer to environment handle to allocate.
+ */
+int alloc_env(CSPIHANDLE *p);
+
+/** Private.
+*   Deallocates environment handle.
+ *  @param h Environment handle to free.
+ */
+void free_env( CSPIHANDLE h );
+
+/** Private.
+ *  Initializes base-part of an allocated environment structure.
+ *  Returns CSPI_OK on success, or CSPI_E_SYSTEM or value returned
+ *  by the test_drvmismatch,
+ *
+ *  @param h Environment handle to initialize.
+ */
+int base_initenv( CSPIHANDLE h );
+
+/** Private.
+ *  Asserts driver version.
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_SYSTEM
+ *  CSPI_E_VERSION.
+ */
+int test_drvmismatch(int fd);
+
+/** Private.
+ *  Initializes custom (derived) part of an allocated environment
+ *  structure. Overriden by each member of the Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param h Environment handle to initialize.
+ */
+int custom_initenv( CSPIHANDLE h );
+
+/** Private.
+ *  Proceeds in the reverse order as init_env.
+ *  Returns CSPI_OK on success or one of the following errors:
+ *  CSPI_E_SYSTEM,
+ *  CSPI_E_SEQUENCE.
+ *
+ *  @param h Environment handle to destroy.
+ */
+int destroy_env( CSPIHANDLE h );
+
+/** Private.
+ *  Allocates and initializes a new connection structure.
+ *  On success, p is set to point to a newly allocated connection,
+ *  or to 0 otherwise.
+ *  Returns CSPI_OK on success, or one of the values returned by
+ *  custom_initcon otherwise.
+ *
+ *  @param h Environment handle.
+ *  @param p Connection handle to allocate.
+ */
+int alloc_con( CSPIHANDLE h, CSPIHANDLE *p );
+
+/** Private.
+ *  Deallocates (frees) a memory block occupied by the connection.
+ *  @param h Connection handle to free.
+ */
+void free_con( CSPIHANDLE h );
+
+/** Private.
+ *  Initializes base connection members to suitable defaults.
+ *  Assigns connection p to the environment h.
+ *  Returns CSPI_OK.
+ *
+ *  @param h Environment handle.
+ *  @param p Connection handle to initialize.
+ */
+int base_initcon( CSPIHANDLE h, CSPIHANDLE p );
+
+/** Private.
+ *  Called by alloc_con to initialize custom (derived) connection
+ *  members to suitable defaults. Overriden by each member of the
+ *  Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param h Environment handle.
+ *  @param p Connection handle to initialize.
+ */
+int custom_initcon( CSPIHANDLE h, CSPIHANDLE p );
+
+/** Private.
+ *  Proceeds in the reverse order as base_initcon.
+ *  Returns CSPI_OK on success, or CSPI_E_SYSTEM otherwise.
+ *
+ *  @param h Connection handle to destroy.
+ */
+int destroy_con( CSPIHANDLE h );
+
+/** Private.
+ *  Inserts connection into the environment's connection list.
+ *  @param h Connection handle to insert.
+ */
+void insert_con( CSPIHANDLE h );
+
+/** Private.
+ *  Removes connection from the environment's connection list.
+ *  @param h Connection handle to remove.
+ */
+void remove_con( CSPIHANDLE h );
+
+/** Private.
+ *  Control Libera events.
+ *  Issues a request to the Libera event daemon to start or stop
+ *  receiving events.
+ *  Returns 0 on success, or -1  otherwise (the errno is set in this case).
+ *
+ *  @param pid  Process id (pid) to register with the event daemon.
+ *  @param mask Event mask. Disables events if 0.
+ */
+int event_ctl( int pid, size_t mask );
+
+/** Private.
+ *  Called by cspi_setlibparam to handle CSPI parameters
+ *  in a thread safe way.
+ *
+ *  @param module Pointer to Library structure.
+ *  @param p      Pointer to CSPI_LIBPARAMS structure with values to set.
+ *  @param flags  Bitmask specifying which values to set.
+ */
+int set_libparam( Library *module, const CSPI_LIBPARAMS *p, size_t flags );
+
+/** Private.
+ *  Called by cspi_getlibparam to handle CSPI parameters
+ *  in a thread safe way.
+ *
+ *  @param module Pointer to Library structure.
+ *  @param p      Pointer to CSPI_LIBPARAMS structure to fill.
+ *  @param flags  Bitmask specifying which values to fill.
+ */
+int get_libparam( Library *module, CSPI_LIBPARAMS *p, size_t flags );
+
+//--------------------------------------------------------------------------
+
+/** Private.
+ *  Represents a validation function to assert the values of
+ *  environment and connection parameters.
+ *  The function should return non-zero (true) if p is pointing 
+ *  to a valid content, or 0 otherwise.
+ *
+ *  @param p Pointer to value to vallidate.
+ */
+typedef int (* VALIDATOR)( const void *p );
+
+/** Private.
+ *  Represents parameter traits.
+ */
+typedef struct tagParam_traits {
+	size_t mask;		//!< Parameter bit mask.
+	int code;			//!< Request code.
+	VALIDATOR validate;		//!< Validation function.
+}
+Param_traits;
+
+/** Private.
+ *  Maps a library or environment parameter to
+ *  the corresponding Param_traits.
+ */
+typedef	struct tagParam_map {
+	const void *field;		//!< Pointer to parameter value.
+	Param_traits traits;	//!< Parameter traits.
+}
+Param_map;
+
+/** Private.
+ *  Macro to create a Param_traits entry.
+ */
+#define PARAM_TRAITS( NAME, FNC ) \
+        {CSPI_ENV_ ## NAME, LIBERA_CFG_ ## NAME, FNC}
+
+/** Private.
+ *  Macro to create a Param_map entry.
+ */
+#define PARAM( NAME, FIELD, FNC ) {FIELD, PARAM_TRAITS(NAME,FNC)}
+
+//--------------------------------------------------------------------------
+
+/** Private.
+ *  Called to assign values to the base-part of the Environment structure.
+ *  Returns CSPI_OK on success, or one of the errors returned by set_param.
+ *  
+ *  @param e     Pointer to environment structure.
+ *  @param p     Pointer to CSPI_ENVPARAMS structure with values to set.
+ *  @param flags Bitmask specifying which values to set.
+ */
+int base_setenvparam( Environment *e, const CSPI_ENVPARAMS *p, CSPI_BITMASK flags );
+
+/** Private.
+ *  Called to retrieve values from the base-part of the Environment
+ *  structure. Returns CSPI_OK on success, or one of the errors
+ *  returned by handle_params.
+ *  
+ *  @param e     Pointer to environment.
+ *  @param p     Pointer to CSPI_ENVPARAMS structure to fill.
+ *  @param flags Bitmask specifying which values to fill.
+ */
+int base_getenvparam( Environment *e, CSPI_ENVPARAMS *p, CSPI_BITMASK flags );
+
+/** Private.
+ *  Called by cspi_setenvparam to assign values to the custom (derived)
+ *  part of the environment structure. Overriden by each member of the
+ *  Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param e     Pointer to environment.
+ *  @param p     Pointer to CSPI_ENVPARAMS structure with values to set.
+ *  @param flags Bitmask specifying which values to set.
+ */
+int custom_setenvparam( Environment *e, const CSPI_ENVPARAMS *p,
+                        CSPI_BITMASK flags );
+
+/** Private.
+ *  Called by cspi_getenvparam to retrieve values from the custom (derived)
+ *  part of the environment structure. Overriden by each member of the
+ *  Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param e     Pointer to environment.
+ *  @param p     Pointer to CSPI_ENVPARAMS structure to fill.
+ *  @param flags Bitmask specifying which values to fill.
+ */
+int custom_getenvparam( Environment *e, CSPI_ENVPARAMS *p, CSPI_BITMASK flags );
+
+enum { GET=0, SET };
+
+/** Private.
+ *  Handle parameter input/output.
+ *  Returns CSPI_OK on success, or one of the errors returned by set_param
+ *  or get_param.
+ *
+ *  @param fd    Device file descriptor.
+ *  @param p     Pointer to null-terminated Param_map vector.
+ *  @param flags Bitmask specifying which values to get/set.
+ *  @param op    Operation type (GET or SET).
+ */
+int handle_params( int fd, Param_map *p, CSPI_BITMASK flags, int op );
+
+/** Private.
+ *  Set the value of a single parameter.
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *
+ *  @param fd     Device file descriptor.
+ *  @param p      Pointer to parameter value.
+ *  @param traits Pointer to parameter traits.
+ */
+int set_param( int fd, int *p, const Param_traits *traits );
+
+/** Private.
+ *  Get the value of a single parameter.
+ *  Returns CSPI_OK on success, or CSPI_E_SYSTEM otherwise.
+ *
+ *  @param fd     Device file descriptor.
+ *  @param p      Pointer to parameter value.
+ *  @param traits Pointer to parameter traits.
+ */
+int get_param( int fd, int *p, const Param_traits *traits );
+
+/** Private.
+ *  Returns device filename, based on mode of operation.
+ *  @param mode Mode of operation.
+ */
+const char* get_devicename(int mode);
+
+/** Private.
+ *  Called by cspi_setconparam to assign values to the custom (derived)
+ *  part of the connection structure. Overriden by each member of the
+ *  Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param con   Pointer to connection.
+ *  @param p     Pointer to CSPI_CONPARAMS structure with values to set.
+ *  @param flags Bitmask specifying which values to set.
+ */
+int custom_setconparam( Connection *con, const CSPI_CONPARAMS *p,
+                        CSPI_BITMASK flags );
+
+/** Private.
+ *  Called to assign values to the base-part of the Connection structure.
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_INVALID_PARAM,
+ *  CSPI_E_SYSTEM.
+ *  
+ *  @param con   Pointer to connection structure.
+ *  @param p     Pointer to CSPI_CONPARAMS structure with values to set.
+ *  @param flags Bitmask specifying which values to set.
+ */
+int base_setconparam( Connection *con, const CSPI_CONPARAMS *p, CSPI_BITMASK flags );
+
+/** Private.
+ *  Called by cspi_getconparam to retrieve values from the custom (derived)
+ *  part of the connection structure. Overriden by each member of the
+ *  Libera family.
+ *  Returns CSPI_OK on success, or an implementation-specific error.
+ *
+ *  @param con   Pointer to environment.
+ *  @param p     Pointer to CSPI_CONPARAMS structure to fill.
+ *  @param flags Bitmask specifying which values to fill.
+ */
+int custom_getconparam( Connection *con, CSPI_CONPARAMS *p, CSPI_BITMASK flags );
+
+/** Private.
+ *  Called to retrive values of the base-part of the Connection structure.
+ *  Returns CSPI_OK.
+ *  
+ *  @param con   Pointer to connection structure.
+ *  @param p     Pointer to CSPI_CONPARAMS structure to fill.
+ *  @param flags Bitmask specifying which values to fill.
+ */
+int base_getconparam( Connection *con, CSPI_CONPARAMS *p, CSPI_BITMASK flags );
+
+//--------------------------------------------------------------------------
+// Data transformation and conversion routines.
+
+/** Private.
+ *  Returns default aux. DD operator for given connection.
+ *  Overriden by each member of the Libera family.
+ *
+ *  @param p Connection pointer.
+ */
+CSPI_AUX_FNC custom_getdefaultop( const Connection *p );
+
+int custom_initop();
+
+/** Private.
+ *  Read from DD (or PM) data source.
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_MALLOC,
+ *  CSPI_E_SYSTEM,
+ *  CSPI_W_INCOMPLETE (warning, not an error).
+ *
+ *  @param p     Connection pointer.
+ *  @param dest  Pointer to destination buffer.
+ *  @param count Number of samples to read.
+ *  @param nread Number of samples actually read.
+ *  @param op    Aux. operator to apply to each sample.
+ */
+int read_dd( Connection *p,
+             void *dest, size_t count,
+             size_t *nread,
+             CSPI_AUX_FNC op );
+
+/** Private.
+ *  Read from ADC data source.
+ *  Returns CSPI_OK on success, or one of the following errors:
+ *  CSPI_E_SYSTEM,
+ *  CSPI_W_INCOMPLETE (warning, not an error).
+ *
+ *  @param p     Connection pointer.
+ *  @param dest  Pointer to destination buffer.
+ *  @param count Number of samples to read.
+ *  @param nread Number of samples actually read.
+ *  @param op    Aux. operator to apply to each sample.
+ */
+int read_adc( Connection *p,
+              void *dest, size_t count,
+              size_t *nread,
+              CSPI_AUX_FNC op );
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// _CSPI_IMPL_H
diff --git a/i-tech/cspi/include/debug.h b/i-tech/cspi/include/debug.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9b651a7b03b9a04d18a4105e31cd4504db79558
--- /dev/null
+++ b/i-tech/cspi/include/debug.h
@@ -0,0 +1,120 @@
+// $Id: debug.h,v 1.2 2005/08/31 09:14:30 miha Exp $
+
+//! \file debug.h
+//! Debugging macros and declarations.
+
+#if !defined(_DEBUG_H)
+#define _DEBUG_H
+
+#include <syslog.h>
+
+#if defined( DEBUG )
+#include <assert.h>
+#endif  // DEBUG
+
+//--------------------------------------------------------------------------
+// Debugging.
+
+#if !defined(DEBUG)
+#define DEBUG 0
+#endif
+
+#if DEBUG	// defined(DEBUG) && DEBUG>0
+
+#define ASSERT(f)		assert(f)
+#define VERIFY(f)		ASSERT(f)
+#define DEBUG_ONLY(f)	(f)
+
+#else	// DEBUG
+
+#define ASSERT(f)		((void)0)
+#define VERIFY(f)		((void)(f))
+#define DEBUG_ONLY(f)	((void)0)
+
+#endif	// !DEBUG
+
+#if DEBUG < 3
+#define DEBUG_ONLY_3(f)	((void)0)
+#else
+#define DEBUG_ONLY_3(f)	(f)
+#endif
+
+#if DEBUG < 2
+#define DEBUG_ONLY_2(f)	((void)0)
+#else
+#define DEBUG_ONLY_2(f)	(f)
+#endif
+
+#if DEBUG < 1
+#define DEBUG_ONLY_1(f)	((void)0)
+#else
+#define DEBUG_ONLY_1(f)	(f)
+#endif
+
+#define DEBUG_ONLY_0(f)	(f)
+
+// The `##' token paste operator has a special meaning when placed between
+// a comma and a variable argument. If you write
+// #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
+// and the variable argument is left out when the eprintf macro is used,
+// then the comma before the `##' will be deleted.
+// This does not happen if you pass an empty argument, nor does it happen
+// if the token preceding `##' is anything other than a comma.
+
+/** Send crtitical message to the system logger. */
+#define _LOG_CRIT( format, ... ) \
+        DEBUG_ONLY_0( syslog( LOG_ERR, format, ##__VA_ARGS__ ) )
+
+/** Send error message to the system logger. */
+#define _LOG_ERR( format, ... ) \
+        DEBUG_ONLY_1( syslog( LOG_ERR, format, ##__VA_ARGS__ ) )
+
+/** Send warning message to the system logger. */
+#define _LOG_WARNING( format, ... ) \
+        DEBUG_ONLY_1( syslog( LOG_WARNING, format, ##__VA_ARGS__ ) )
+
+/** Send normal, but significant message to the system logger. */
+#define _LOG_NOTICE( format, ... ) \
+        DEBUG_ONLY_2( syslog( LOG_NOTICE, format, ##__VA_ARGS__ ) )
+
+/** Send informational message to the system logger. */
+#define _LOG_INFO( format, ... ) \
+        DEBUG_ONLY_2( syslog( LOG_INFO, format, ##__VA_ARGS__ ) )
+
+/** Send debug-level message to the system logger. */
+#define _LOG_DEBUG( format, ... ) \
+        DEBUG_ONLY_3( syslog( LOG_DEBUG, format, ##__VA_ARGS__ ) )
+
+/** Dumps expression to STDERR.
+ *  This macro is only available in DEBUG build.
+ *  Takes a format string as used in the run-time function printf.
+ */
+#define TRACE( f ) DEBUG_ONLY( fprintf( stderr, f ) )
+
+/** Same as TRACE, but takes a format string plus one argument
+ *  (one variable that is dumped to STDERR).
+ */
+#define TRACE1( f, p ) DEBUG_ONLY( fprintf( stderr, f, p ) )
+
+/** Same as TRACE, but takes a format string plus two arguments
+ *  (two variables that are dumped to STDERR).
+ */
+#define TRACE2( f, p, q ) DEBUG_ONLY( fprintf( stderr, f, p, q ) )
+
+/** Same as TRACE, but takes a format string plus three arguments
+ *  (three variables that are dumped to STDERR).
+ */
+#define TRACE3( f, p, q, r ) DEBUG_ONLY( fprintf( stderr, f, p, q, r ) )
+
+//--------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//...
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// DEBUG_H
diff --git a/i-tech/cspi/include/dscd.h b/i-tech/cspi/include/dscd.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ad5d880f68af8369f46c14ddf6e52f18b9372d5
--- /dev/null
+++ b/i-tech/cspi/include/dscd.h
@@ -0,0 +1,67 @@
+// $Id: dscd.h,v 1.4 2007/05/16 12:56:11 janko Exp $
+
+//! \file dscd.h
+//! Declares interface for the DSC Daemon.
+
+#if !defined(_DSC_H)
+#define _DSC_H
+
+#include <sys/types.h>		// defines pid_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Idle period in seconds between two iterations.
+#define DSCD_ITER_PERIOD	3
+
+// Process identifier (PID) pathname.
+#define DSCD_PID_PATHNAME		"/var/run/ldscd.pid"
+
+// Request FIFO (named pipe) pathname.
+#define DSCD_FIFO_PATHNAME	"/tmp/ldscd.fifo"
+
+// Libera dsc device filename
+#define LIBERA_DSC_DEVICE_FILE	"/dev/libera.dsc"
+
+//--------------------------------------------------------------------------
+// Interface.
+
+// server magic numbers
+enum {
+	DSCD_MAGIC = 90205,
+};
+
+// list of server message types
+enum {
+	DSCD_FIRST = 0,
+	DSCD_SET_AGC,
+	DSCD_GET_AGC,
+	DSCD_SET_DSC,
+	DSCD_GET_DSC,
+	DSCD_SET_GAIN,
+	DSCD_GET_GAIN,
+	DSCD_SET_SWITCH,
+	DSCD_GET_SWITCH,
+	DSCD_LAST
+};
+
+// server message
+typedef struct {
+	// magic number
+	size_t magic;
+	// request type
+	size_t type;
+	// request-specific value
+	int val;
+	// PID of a process sending the request
+	pid_t pid;
+	// reply status
+	int  status;
+}
+message;
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// _DSC_H
diff --git a/i-tech/cspi/include/ebpp.h b/i-tech/cspi/include/ebpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ba70c13f91f67b3b396b1c15789686be25f7218
--- /dev/null
+++ b/i-tech/cspi/include/ebpp.h
@@ -0,0 +1,271 @@
+// $Id: ebpp.h,v 1.43.2.4 2008/02/20 08:54:27 primozb Exp $
+
+//! \file ebpp.h
+//! Electron Beam Position Processor specific definitions.
+
+#if !defined(_EBPP_H)
+#define _EBPP_H
+
+// Get defines for interfacing with LPLLD.
+#include "lplld.h"
+
+/** Libera EBPP Slow Acquisition (SA) sample. */
+typedef struct {
+	// Amplitudes
+	int Va, Vb, Vc, Vd;
+	// Sum Va + Vb + Vc + Vd
+	int Sum;
+	// Quadropole signal
+	int Q;
+	// Horizontal beam position
+	int X;
+	// Vertical beam position
+	int Y;
+	// Horiz. and vert. correction factors from the FA Application
+	int Cx, Cy;
+	// 6 values reserved for future use
+	int reserved[6];
+}
+CSPI_SA_ATOM;
+
+/** Libera EBPP Data on Demand (DD) raw sample. */
+typedef struct {
+	int cosVa, sinVa;
+	int cosVb, sinVb;
+	int cosVc, sinVc;
+	int cosVd, sinVd;
+}
+CSPI_DD_RAWATOM;
+
+/** Libera EBPP Data on Demand (DD) sample. */
+typedef struct {
+	// Amplitudes
+	int Va, Vb, Vc, Vd;
+	// Horiz. and vert. beam position
+	int X, Y;
+	// Quadropole signal
+	int Q;
+	// Sum Va + Vb + Vc + Vd
+	int Sum;
+}
+CSPI_DD_ATOM;
+
+typedef struct {
+    short chD;
+    short chC;
+    short chB;
+    short chA;
+}
+CSPI_ADC_ATOM;
+
+//--------------------------------------------------------------------------
+
+/** DSC Compensation parameters. */
+struct DSC_COMPPARAMS
+{
+        float ampl[16][4];
+        float phase[16][4];
+        int status;
+};
+
+/** Environment parameters or attributes. */
+struct tagCSPI_ENVPARAMS
+{
+	CSPI_ENVPARAMS_BASE;
+
+	int Kx, Ky;
+	int Xoffset, Yoffset, Qoffset;
+
+	int switches;	// Analog board switch mode. See CSPI_SWITCHMODE.
+	int gain;		// Analog board gain (dBm).
+
+	int agc;		// AGC mode. See CSPI_AGCMODE.
+	int dsc;		// DSC mode. See CSPI_DSCMODE.
+
+	// Interlock parameters.
+	struct {
+		// Interlock mode. See CSPI_INTERLOCKMODE.
+		int mode;
+		// Interlock limits.
+		int Xlow, Xhigh, Ylow, Yhigh;
+		// Interlock overflow limit (ADC count).
+		int overflow_limit;
+		// Interlock overflow duration (ADC clock periods).
+		int overflow_dur;
+		// Gain limit (dBm) for gain-dependant interlock.
+		int gain_limit;
+	} ilk;
+
+    int ilk_status;  // Interlock status. Write this value will reset status.
+    int PMoffset;    // Post mortem buffer offset (+/-).
+
+    int trig_delay;        // Hardware Trigger Delay
+
+    int external_switching; // Switching source.
+    int switching_delay;   // Switching delay.
+
+    int ddc_maflength;     // Moving Average Filter Length
+    int ddc_mafdelay;      // Moving Average Filter Delay
+
+    int notch1[LIBERA_CFG_NOTCH_MAX];
+    int notch2[LIBERA_CFG_NOTCH_MAX];
+    int polyphase_fir[LIBERA_CFG_FIR_MAX];
+
+    // LPLLD runtime parameters. Write only.
+    int mtvcxoffs; // RF-VCXO detuning offset (*40 Hz). Environment configuration : OffsetTune
+    int mtncoshft; // NCO frequency shift flag. Environment configuration : CompTune
+    int mtphsoffs; // VCXO phase offset. Environment configuration : PhaseOffs
+    int mtunlcktr; // MT unlock threshold.  Environment configuration : MTUnlock
+    int mtsyncin; // Synchronization input. Environment configuration : SyncIn
+    int stunlcktr; // ST unlock threshold.  Environment configuration : STUnlock
+
+    // LPLLD status. Read only.
+    pll_status_t pll_status; // PLL MT (mt_stat) and ST (st_stat) status structures. 
+};
+
+/** Libera EBPP specific environment bitflags. */
+typedef enum
+{
+	CSPI_ENV_KX			= CUSTOM_ENV_BIT(0),
+	CSPI_ENV_KY			= CUSTOM_ENV_BIT(1),
+	CSPI_ENV_XOFFSET	= CUSTOM_ENV_BIT(2),
+	CSPI_ENV_YOFFSET	= CUSTOM_ENV_BIT(3),
+	CSPI_ENV_QOFFSET	= CUSTOM_ENV_BIT(4),
+	CSPI_ENV_SWITCH		= CUSTOM_ENV_BIT(5),
+	CSPI_ENV_GAIN		= CUSTOM_ENV_BIT(6),
+	CSPI_ENV_AGC		= CUSTOM_ENV_BIT(7),
+	CSPI_ENV_DSC		= CUSTOM_ENV_BIT(8),
+	CSPI_ENV_ILK		= CUSTOM_ENV_BIT(9),
+    CSPI_ENV_ILKSTATUS  = CUSTOM_ENV_BIT(10),
+    CSPI_ENV_PMOFFSET   = CUSTOM_ENV_BIT(11),
+    CSPI_ENV_TRIGDELAY  = CUSTOM_ENV_BIT(12),
+    CSPI_ENV_EXTSWITCH  = CUSTOM_ENV_BIT(13),
+    CSPI_ENV_SWDELAY    = CUSTOM_ENV_BIT(14),
+    CSPI_ENV_NOTCH1     = CUSTOM_ENV_BIT(15),
+    CSPI_ENV_NOTCH2     = CUSTOM_ENV_BIT(16),
+    CSPI_ENV_POLYPHASE_FIR = CUSTOM_ENV_BIT(17),
+    CSPI_ENV_DDC_MAFLENGTH = CUSTOM_ENV_BIT(18),
+    CSPI_ENV_DDC_MAFDELAY  = CUSTOM_ENV_BIT(19),
+    CSPI_ENV_MTVCXOFFS     = CUSTOM_ENV_BIT(20),
+    CSPI_ENV_MTNCOSHFT     = CUSTOM_ENV_BIT(21),
+    CSPI_ENV_MTPHSOFFS     = CUSTOM_ENV_BIT(22),
+    CSPI_ENV_MTUNLCKTR     = CUSTOM_ENV_BIT(23),
+    CSPI_ENV_MTSYNCIN      = CUSTOM_ENV_BIT(24),
+    CSPI_ENV_STUNLCKTR     = CUSTOM_ENV_BIT(25),
+    CSPI_ENV_LPLLDSTAT     = CUSTOM_ENV_BIT(26),
+//    CSPI_ENV_BCDOFFSET     = CUSTOM_ENV_BIT(27),
+}
+CSPI_ENVFLAGS_EBPP;
+
+/** Available switch modes. */
+typedef enum {
+    /** Enable switching. */
+    CSPI_SWITCH_AUTO	= 0xff,
+    
+    /** Enable direct connection (no crossover). 
+        Final value for DSC depends on HW type. 
+        Brilliance = 15, Electron = 3. */
+    CSPI_SWITCH_DIRECT	= 0x100,
+    
+    /** DIRECT switch position value for Brillinace */
+    CSPI_SWITCH_DIRECT_BRILLIANCE = 0x0F,
+    
+    /** DIRECT switch position value for NOT Brillinace, e.g. Electron */
+    CSPI_SWITCH_DIRECT_NOTBRILLIANCE = 0x03,
+    
+    /** Minimal switch position value  */
+    CSPI_SWITCH_MIN         = 0x00,
+    
+    /** Maximal switch position value  */
+    CSPI_SWITCH_MAX         = 0x0f,
+}
+CSPI_SWITCHMODE;
+
+/** Available AGC modes. */
+typedef enum {
+	/** Manual gain control. */
+	CSPI_AGC_MANUAL = 0,
+	/** Enable AGC. */
+	CSPI_AGC_AUTO,
+}
+CSPI_AGCMODE;
+
+/** Available DSC modes. */
+typedef enum {
+	/** Disable DSC. Keep current DSC coefficients. */
+	CSPI_DSC_OFF = 0,
+	/** Disable DSC. Apply unitiy DSC coefficients. */
+	CSPI_DSC_UNITY,
+	/** Enable signal conditioning with DSC daemon in AUTO mode. */	
+	CSPI_DSC_AUTO,
+	/** Save current DSC coefficients onto FLASH /opt/dsc/lastgood.dat. */
+	CSPI_DSC_SAVE_LASTGOOD,
+	/** Reset currently learned coefficients to unity value. */
+	CSPI_DSC_RESET_COEFF,
+}
+CSPI_DSCMODE;
+
+/** Available interlock modes. */
+typedef enum {
+	/** Disable interlock. */
+	CSPI_ILK_DISABLE = 0,
+	/** Enable interlock. */
+	CSPI_ILK_ENABLE = 1,
+	/** Enable gain-dependant interlock. */
+	CSPI_ILK_ENABLE_GAINDEP = 3,
+}
+CSPI_ILKMODE;
+
+
+/** Event specific values for event CSPI_EVENT_INTERLOCK. */
+typedef enum {
+        /** IL: position X out of limit. */
+        CSPI_INTERLOCK_X    = LIBERA_INTERLOCK_X,
+
+        /** IL: position Y out of limit. */
+        CSPI_INTERLOCK_Y    = LIBERA_INTERLOCK_Y,
+
+        /** IL: Attenuators set higher than predefined value. */
+        CSPI_INTERLOCK_ATTN = LIBERA_INTERLOCK_ATTN,
+
+        /** IL: ADC Overflow  (filtered). */
+        CSPI_INTERLOCK_ADCF = LIBERA_INTERLOCK_ADCF,
+
+        /** IL: ADC Overflow  (not filtered). */
+        CSPI_INTERLOCK_ADC = LIBERA_INTERLOCK_ADC,
+} CSPI_ILKCAUSE;
+
+//--------------------------------------------------------------------------
+
+/** Derived from CSPI_CONPARAMS to handle EBPP specific
+ *  parameters or attributes.
+ */
+typedef struct {
+	/** Common connection parameters. */
+	CSPI_CONPARAMS_BASE;
+
+	/** DD decimation factor. */
+	size_t dec;
+
+	/** SA non-blocking mode. */
+	size_t nonblock;
+}
+CSPI_CONPARAMS_EBPP;
+
+//--------------------------------------------------------------------------
+
+/** Bit flags corresponding to the CSPI_CONPARAMS_EBPP structure.
+ *  See CSPI_CONPARAMS_EBPP structure for descriptions.
+ */
+typedef enum {
+	CSPI_CON_DEC        = CUSTOM_CON_BIT(0),
+	CSPI_CON_SANONBLOCK = CUSTOM_CON_BIT(1),
+}
+CSPI_CONFLAGS_EBPP;
+
+/** Backward compatibility */
+typedef CSPI_CONFLAGS_EBPP  CSPI_CONFLAGS_DD;
+/** Backward compatibility */
+typedef CSPI_CONPARAMS_EBPP  CSPI_CONPARAMS_DD;
+
+#endif	// _EBPP_H
diff --git a/i-tech/cspi/include/eventd.h b/i-tech/cspi/include/eventd.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8076e9f79530eb98df424a8bbc4fb49f2f5798f
--- /dev/null
+++ b/i-tech/cspi/include/eventd.h
@@ -0,0 +1,50 @@
+// $Id: eventd.h,v 1.5 2005/10/24 11:15:11 miha Exp $
+
+//! \file eventd.h
+//! Declares interface for CSPI Event Daemon.
+
+#if !defined(_EVENTD_H)
+#define _EVENTD_H
+
+#include <sys/types.h>	// defines pid_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Event signal. */
+#define LIBERA_SIGNAL SIGUSR1
+
+/** Process identifier (PID) pathname. */
+#define EVENTD_PID_PATHNAME		"/var/run/leventd.pid"
+
+/** Request FIFO (named pipe) pathname. */
+#define EVENTD_REQ_FIFO_PATHNAME	"/tmp/leventd.fifo"
+
+/** Libera event device. */
+#define LIBERA_EVENT_FIFO_PATHNAME	"/dev/libera.event"
+
+//--------------------------------------------------------------------------
+// Interface.
+
+/** Represents event daemon request. */
+typedef struct {
+	pid_t pid;
+	size_t mask;
+}
+Request;
+
+/** Typedef. See struct tagListener for more information. */
+typedef struct tagListener Listener;	// forward decl
+
+/** Represents a member of the listener list. */
+struct tagListener {
+	pid_t pid;
+	size_t mask;
+	Listener *prev, *next;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// _EVENTD_H
diff --git a/i-tech/cspi/include/hbpp.h b/i-tech/cspi/include/hbpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1881ed777b7ff4e81924f9d6e71dccd89f68de3
--- /dev/null
+++ b/i-tech/cspi/include/hbpp.h
@@ -0,0 +1,66 @@
+// $Id: hbpp.h,v 1.2 2006/05/16 06:47:39 miha Exp $
+
+//! \file hbpp.h
+//! Hadron Beam Position Processor (HBPP) specific definitions.
+
+#if !defined(_HBPP_H)
+#define _HBPP_H
+
+/** Libera HBPP Data on Demand (DD) raw sample. */
+typedef libera_sample_t CSPI_DD_RAWATOM;
+
+/** Libera HBPP Data on Demand (DD) sample. */
+typedef CSPI_DD_RAWATOM CSPI_DD_ATOM;
+
+/** Placeholder for CSPI types not used by the HBPP. */
+typedef struct {} CSPI_NOTUSED;
+
+/** Not used. Declared for compatibility with CSPI only. */
+typedef CSPI_NOTUSED CSPI_SA_ATOM;
+
+/** Not used. Declared for compatibility with CSPI only. */
+typedef CSPI_NOTUSED CSPI_ADC_ATOM;
+
+//--------------------------------------------------------------------------
+
+/** Environment parameters or attributes. */
+struct tagCSPI_ENVPARAMS
+{
+	CSPI_ENVPARAMS_BASE;
+
+	// No HBPP specific parameters.
+};
+
+/*
+ * typedef enum
+ * {
+ * 	CSPI_ENV_			= CUSTOM_ENV_BIT(0),
+ * }
+ * CSPI_ENVFLAGS_HBPP;
+ */
+
+//--------------------------------------------------------------------------
+
+/** Derived from CSPI_CONPARAMS to handle DD specific
+ *  parameters or attributes for HBPP.
+ */
+typedef struct {
+	/** Common connection parameters. */
+	CSPI_CONPARAMS_BASE;
+
+	// TODO: add HBPP-specific parameters.
+}
+CSPI_CONPARAMS_DD;
+
+//--------------------------------------------------------------------------
+
+/** Bit flags corresponding to the CSPI_CONPARAMS_DD structure.
+ *  See CSPI_CONPARAMS_DD structure for descriptions.
+ */
+//typedef enum {
+	// TODO: add bit flags for HBPP-specific parameters.
+	//CSPI_CON_xxx = CUSTOM_CON_BIT(0),
+//}
+//CSPI_CONFLAGS_DD;
+
+#endif	// _HBPP_H
diff --git a/i-tech/cspi/include/lplld.h b/i-tech/cspi/include/lplld.h
new file mode 100644
index 0000000000000000000000000000000000000000..9bae56f04b5db991eeeaa4ddbe54d9b0e996ee80
--- /dev/null
+++ b/i-tech/cspi/include/lplld.h
@@ -0,0 +1,150 @@
+/* $Id: lplld.h,v 1.3.2.1 2008/02/13 14:46:47 primozb Exp $ */
+
+//! \file libera_lplld.h
+//! Declares interface for Libera PLL daemon.
+
+/*
+LIBERA PLL DAEMONS - Libera GNU/Linux PLL daemons
+Copyright (C) 2004 Instrumentation Technologies
+Copyright (C) 2006-2007 Michael Abbott, Diamond Light Source Ltd.
+
+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
+or visit http://www.gnu.org
+
+TAB = 4 spaces.
+*/
+
+#if !defined(_LIBERA_LPLLD_H)
+#define _LIBERA_LPLLD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+/** LPLLD process identifier (PID) pathname. */
+#define LPLLD_PID_PATHNAME_d        "/var/run/lplld.pid"
+
+/** Command FIFO for receiving LPLLD commands. */
+#define LPLLD_COMMAND_FIFO_d        "/tmp/lplld.command"
+
+/** Status FIFO for reporting LPLLD status. */
+#define LPLLD_STATUS_FIFO_d         "/tmp/lplld.status"
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/** Structure with flags indicating change of particular MT runtime parameter. */
+typedef struct _mt_has_changed_tag
+{
+    char vcxo_offset : 1; ///< RF-VCXO detuning offset has changed.
+    char nco_shift : 1; ///< NCO frequency shift flag has changed.
+    char phase_offset : 1; ///< VCXO Phase offset has changed.
+    char unlock_threshold : 1; ///< Unlock threshold has changed.
+    char sync_in : 1; ///< Synchronization input has changed.
+} mt_has_changed_t;
+
+/** Structure with MT controller parameters. */
+typedef struct _mt_parameters_tag
+{
+    unsigned long mc_prescale; ///< MC prescaler. Default=MT_DEFAULT_MCPRESC.
+    unsigned long u_nominal; ///< DAC nominal offset. Default=MT_DEFAULT_UNOMINAL.
+    long vcxo_offset; ///< RF-VCXO detuning offset (*40Hz). Default=MT_DEFAULT_VCXOFF.
+    int nco_shift; ///< NCO frequency shift flag (Y=1, N=0). Default=MT_DEFAULT_NCOSHIFT.
+    long phase_offset; ///< VCXO phase offset. Default=MT_DEFAULT_PHOFFSET.
+    unsigned long harmonic; ///< Harmonic number. Default MT_DEFAULT_HARMONIC.
+    unsigned long unlock_threshold; ///< Unlock threshold. Default=MT_DEFAULT_UNLOCK.
+    int sync_in; ///< Synchronization input.
+    char *plldebug; ///< Pointer to filename path for debug data. Default=NULL.
+    mt_has_changed_t has_chngd; ///< Bitset with flags indicating change of particular parameter.
+} mt_parameters_t, *mt_parameters_ptr;
+
+/** Structure with current MT status. */
+typedef struct _mt_status_tag
+{
+    unsigned long seqno; ///< Update status sequence counter;
+    unsigned long dac; ///< DAC output value.
+    long long phase_error; ///< Phase error.
+    unsigned long frequency; ///< Frequency in dHz.
+    int locked_status; ///< Locked flag (0=unlocked, 1=locked).
+    int sync_state; ///< Synchronization state. Default=0.
+    long vcxo_offset; ///< RF-VCXO detuning offset (*40Hz).
+    int nco_shift; ///< NCO frequency shift flag (Y=1, N=0).
+    long phase_offset; ///< VCXO phase offset.
+    unsigned long unlock_threshold; ///< Unlock threshold.
+    int sync_in; ///< Synchronization input.
+    int status; ///< Controller internal status. Libera utility "MT controller RtmSts".
+} mt_status_t, *mt_status_ptr;
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/** Structure with flags indicating change of particular ST runtime parameter. */
+typedef struct _st_has_changed_tag
+{
+    char unlock_threshold : 1; ///< Unlock threshold has changed.
+} st_has_changed_t;
+
+/** Structure with ST controller parameters. */
+typedef struct _st_parameters_tag
+{
+    unsigned long u_nominal; ///< DAC nominal offset. Default=ST_DEFAULT_UNOMINAL.
+    unsigned long unlock_threshold; ///< Unlock threshold. Default=ST_DEFAULT_UNLOCK.
+    char *plldebug; ///< Pointer to filename path for debug data. Default=NULL.
+    st_has_changed_t has_chngd; ///< Bitset with flags indicating change of particular parameter.
+} st_parameters_t, *st_parameters_ptr;
+
+/** Structure with current ST status. */
+typedef struct _st_status_tag
+{
+    unsigned long seqno; ///< Update status sequence counter;
+    unsigned long dac; ///< DAC output value.
+    long long phase_error; ///< Phase error.
+    unsigned long frequency; ///< Frequency in dHz.
+    int locked_status; ///< Locked flag (0=unlocked, 1=locked).
+    int status; ///< Controller internal status. Libera utility "ST controller RtmSts".
+    unsigned long unlock_threshold; ///< Unlock threshold.
+} st_status_t, *st_status_ptr;
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/** Structure with PLL status. This stucture is raw byte stream copied to 
+ *  status pipe. The read side of pipe should instantiate this structure directly
+ *  from recived raw byte stream.
+ *  @note This approach was chosen, because the assumption is that both sides 
+ *  of the pipe (write and read) will allways be on the same machine (no machine 
+ *  boundaries crossing).
+ */
+typedef struct _pll_status_tag
+{
+    unsigned long report_stseqn; ///< Reported status sequence counter;
+    mt_status_t mt_stat; ///< MT status;
+    st_status_t st_stat; ///< ST status.
+} pll_status_t, *pll_status_ptr;
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/** Enumerator values used to define internal status of controller.
+ */
+typedef enum {
+    CTRL_OK = 0, ///< Controller status running and OK.
+    CTRL_NOT_INITIALIZED, ///< Controller not yet initialized.
+    CTRL_NO_CLOCK, ///< No external clock signal.
+    CTRL_DEF_UNLOCK, ///< Phase error too big.
+    CTRL_TERMINATED, ///< Controller loop terminated.
+} controller_status_enum;
+
+#ifdef __cplusplus
+}
+#endif
+#endif    // _LIBERA_LPLLD_H
diff --git a/i-tech/cspi/include/pool.h b/i-tech/cspi/include/pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..42e1afdbec8717a5bb3cdb2abff481a9a9ae7c45
--- /dev/null
+++ b/i-tech/cspi/include/pool.h
@@ -0,0 +1,46 @@
+// $Id: pool.h,v 1.5 2005/11/13 21:33:19 miha Exp $
+
+//! \file pool.h
+//! Declares memory pool interface for Data On Demand requests.
+
+#if !defined(_POOL_H)
+#define _POOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The number of memory blocks (objects) to allocate in advance.
+ *  Memory will be allocated to accomodate OBJECT_COUNT requests
+ *  with a single malloc call.
+ */
+#define OBJECT_COUNT	4
+
+/** The size of a block in the memory pool.
+ *  This is also the largest block that can be allocated on the pool.
+ *  Requests of 'wrong' size are sent to standard malloc.
+ */
+#define CHUNK_SIZE	( 10240 * 8 * 4 )	// 10K samples, 32 bytes each
+
+//--------------------------------------------------------------------------
+// Public interface.
+
+/** Private.
+ *  Allocates from a memory pool. Requests of size larger than CHUNK_SIZE
+ *  are routed to standard malloc.
+ *  Returns a pointer to allocated memory or 0 if request fails.
+ *  @param size The Number of bytes to allocate.
+ */
+void* pool_malloc( size_t size );
+
+/** Private.
+ *  Frees memory allocated with pool_malloc.
+ *  @param p    A pointer to memory block allocated with pool_malloc.
+ *  @param size The size of memory block in bytes.
+ */
+void pool_free( void *p, size_t size );
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// _POOL_H
diff --git a/i-tech/cspi/lib/README b/i-tech/cspi/lib/README
new file mode 100644
index 0000000000000000000000000000000000000000..1b428402f1ae498d790b3b534444280ea1cd6aef
--- /dev/null
+++ b/i-tech/cspi/lib/README
@@ -0,0 +1 @@
+libcspi.a : i-tech cspi lib for ARM
diff --git a/i-tech/driver/include/bbfp.h b/i-tech/driver/include/bbfp.h
new file mode 100644
index 0000000000000000000000000000000000000000..24e66bd433948bc273d720b9960dd5015c289310
--- /dev/null
+++ b/i-tech/driver/include/bbfp.h
@@ -0,0 +1,99 @@
+/* $Id: bbfp.h,v 1.12 2007/09/04 07:23:55 ales Exp $ */
+
+/** \file bbfp.h */
+/** Public include file for Libera Bunch by Bunch Feedback Processor (BBFP). */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _BBFP_H_
+#define _BBFP_H_
+
+/** Libera magic number */
+#define LIBERA_MAGIC 0xbbf0
+
+
+/** BBFP specific CFG parameters. */
+typedef enum {
+    LIBERA_CFG_NONE = LIBERA_CFG_CUSTOM_FIRST, //!< Default.
+} LIBERA_CFG_BBFP_GENERIC;
+
+
+/** Libera BBFP Bunch sample */
+typedef short libera_sample_t;
+
+/* Atom vs. sample vs. longwords & bytes constants */
+#define LIBERA_DD_CIRCBUF_ATOMS  (32*1024*1024) //<! No. of atoms in HB.
+#define LIBERA_DD_MT_SAMPLES           4        //<! No. of samples in 1 MT.
+#define LIBERA_DD_ATOM_MTS             1        //<! No. of MTs in 1 atom.
+#define LIBERA_DD_ATOM_SAMPLES   (LIBERA_DD_ATOM_MTS*LIBERA_DD_MT_SAMPLES) //<! No. of samples in 1 ATOM.
+/** No. of DD atoms in one DMA block */
+#define LIBERA_DMA_BLOCK_ATOMS  512
+/* DMA buffer size = PAGE_SIZE << LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_PAGE_ORDER     5
+/** No. of DD atoms in DMA fifo  - Must be power of 2 and sync
+ *  with LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_FIFO_ATOMS  16384
+#define LIBERA_DMA_FIFO_MASK (LIBERA_DMA_FIFO_ATOMS - 1)
+/** Maximal No. of samples in read(request) */
+#define BBFP_MAX_SAMPLES   (64*1024*1024)
+
+/** Libera BBFP Data on Demand (DD) atom */
+/*  NOTE: The size of libera_atom_dd_t structure is important. 
+ *        The minimal lenght of libera_atom_dd_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    libera_sample_t sample[LIBERA_DD_ATOM_SAMPLES];
+} libera_atom_dd_t;
+
+
+/* Libera BBFP ADC-rate Data (ADC) atom */
+/* NOTE: The size of libera_atom_adc_t structure is important. 
+ *       The minimal lenght of libera_atom_adc_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef void* libera_atom_adc_t;  // Unused
+
+
+/** Libera BBFP Slow Acquisition (SA) atom */
+/*  NOTE: The size of libera_atom_sa_t structure is important. 
+ *        PAGE_SIZE MUST be a multiple of sizeof(libera_atom_sa_t) for proper 
+ *        buffer wrapping. Pad this structure to the nearest common 
+ *        denominator of PAGE_SIZE and sizeof(libera_atom_sa_t).
+ *        The minimal lenght of libera_atom_sa_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    /* 4 amplitudes */
+    libera_S32_t Va, Vb, Vc, Vd;
+    /* 4 synthetic values -> X, Y, Q & Sum */
+    libera_S32_t X, Y, Q, Sum;
+    /* Cx and Cy for FF */
+    libera_S32_t Cx, Cy;
+    /* 6 values reserved for future use */
+    libera_S32_t reserved[6];
+} libera_atom_sa_t;
+
+#define SA_FIFO_DEPTH    32 /* Top/botoom half SA buffer length in atoms. */
+#define SA_SIZE_WIDTH     1
+#define SA_LOG           64 // SA terminal pipe buffer depth. Must be 2^n.
+
+#endif // _BBFP_H_
diff --git a/i-tech/driver/include/dpp.h b/i-tech/driver/include/dpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1c53265f7309fc281730d9cc9afde8e72f6e215
--- /dev/null
+++ b/i-tech/driver/include/dpp.h
@@ -0,0 +1,94 @@
+/* $Id: dpp.h,v 1.5 2007/09/04 07:23:55 ales Exp $ */
+
+/** \file dpp.h */
+/** Public include file for Libera Digital Pulse Processor (DPP). */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _DPP_H_
+#define _DPP_H_
+
+/** Libera magic number */
+#define LIBERA_MAGIC 0xdd00
+
+
+/** DPP specific CFG parameters. */
+typedef enum {
+    LIBERA_CFG_NONE = LIBERA_CFG_CUSTOM_FIRST, //!< Default.
+} LIBERA_CFG_DPP_GENERIC;
+
+
+/** Libera DPP  sample */
+typedef struct {
+    unsigned long sample; // Should be short, but... minimal size = 4!
+} libera_sample_t;
+
+/* Atom vs. sample vs. longwords & bytes constants */
+#define LIBERA_DD_CIRCBUF_ATOMS  (32*1024*1024) //<! No. of atoms in HB.
+#define LIBERA_DD_MT_SAMPLES           1        //<! No. of samples in 1 MT.
+#define LIBERA_DD_ATOM_MTS             1        //<! No. of MTs in 1 atom.
+#define LIBERA_DD_ATOM_SAMPLES   (LIBERA_DD_ATOM_MTS*LIBERA_DD_MT_SAMPLES) //<! No. of samples in 1 ATOM.
+/** No. of DD atoms in one DMA block */
+#define LIBERA_DMA_BLOCK_ATOMS  512
+/* DMA buffer size = PAGE_SIZE << LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_PAGE_ORDER     5
+/** No. of DD atoms in DMA fifo  - Must be power of 2 and sync
+ *  with LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_FIFO_ATOMS  16384
+#define LIBERA_DMA_FIFO_MASK (LIBERA_DMA_FIFO_ATOMS - 1)
+/** Maximal No. of samples in read(request) */
+#define DPP_MAX_SAMPLES   (2*1024*1024)
+
+/** Libera DPP  Data on Demand (DD) atom */
+/*  NOTE: The size of libera_atom_dd_t structure is important. 
+ *        The minimal lenght of libera_atom_dd_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    unsigned long sample; // Should be short, but... minimal size = 4!
+} libera_atom_dd_t;
+
+
+/* Libera DPP ADC-rate Data (ADC) atom */
+/* NOTE: The size of libera_atom_adc_t structure is important. 
+ *       The minimal lenght of libera_atom_adc_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef void* libera_atom_adc_t;  // Unused
+
+
+/** Libera DPP Slow Acquisition (SA) atom */
+/*  NOTE: The size of libera_atom_sa_t structure is important. 
+ *        PAGE_SIZE MUST be a multiple of sizeof(libera_atom_sa_t) for proper 
+ *        buffer wrapping. Pad this structure to the nearest common 
+ *        denominator of PAGE_SIZE and sizeof(libera_atom_sa_t).
+ *        The minimal lenght of libera_atom_sa_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    unsigned long sample; // Should be short, but... minimal size = 4!
+} libera_atom_sa_t;
+
+#define SA_FIFO_DEPTH  (16*1024) // Top/botoom half SA buffer length in atoms.
+#define SA_SIZE_WIDTH  13
+#define SA_LOG         (16*1024) // SA terminal pipe buffer depth. Must be 2^n.
+
+#endif // _DPP_H_
diff --git a/i-tech/driver/include/ebpp.h b/i-tech/driver/include/ebpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..19439b7154fe4cca9d383db9d18740cb468d68e6
--- /dev/null
+++ b/i-tech/driver/include/ebpp.h
@@ -0,0 +1,136 @@
+/* $Id: ebpp.h,v 1.34.2.2 2008/01/11 10:12:08 tomazb Exp $ */
+
+/** \file ebpp.h */
+/** Public include file for Libera Electron Beam Position Processor (EBPP). */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _EBPP_H_
+#define _EBPP_H_
+
+/** Libera magic number */
+#define LIBERA_MAGIC 0xeb00
+
+/** EBPP specific CFG parameters. */
+typedef enum {
+    LIBERA_CFG_XOFFSET = LIBERA_CFG_CUSTOM_FIRST,        //!< Horizontal electrical/magnetic offset.
+    LIBERA_CFG_YOFFSET,        //!< Vertical electrical/magnetic offset.
+    LIBERA_CFG_QOFFSET,        //!< Electrical offset.
+    LIBERA_CFG_KX,             //!< Horizontal calibration coefficient.
+    LIBERA_CFG_KY,             //!< Vertical calibration coefficient.
+    LIBERA_CFG_ILK_XLOW,           //!< Horizontal interlock threshold (LOW).
+    LIBERA_CFG_ILK_XHIGH,          //!< Horizontal interlock threshold (HIGH).
+    LIBERA_CFG_ILK_YLOW,           //!< Vertical interlock threshold (LOW).
+    LIBERA_CFG_ILK_YHIGH,          //!< Vertical interlock threshold (HIGH).
+    LIBERA_CFG_ILK_MODE,       //!< Interlock  mode
+    LIBERA_CFG_ILK_OVERFLOW_LIMIT,     //!< Interlock overflow limit (ADC count)
+    LIBERA_CFG_ILK_OVERFLOW_DUR,  //!< Interlock overflow duration (ADC clock periods)
+    LIBERA_CFG_ILK_GAIN_LIMIT, //!< Gain limit (dBm) for gain-dependant interlock
+    LIBERA_CFG_CUSTOM_LAST,    // used in init_specific for FPGA initialization
+    // TODO: Check with CSPI regarding FIRST/LAST
+    LIBERA_CFG_SW,
+    LIBERA_CFG_LEVEL,
+    LIBERA_CFG_AGC,
+    LIBERA_CFG_DSC,
+    LIBERA_CFG_ILKSTATUS,
+    LIBERA_CFG_PMOFFSET,
+    LIBERA_CFG_EXTSWITCH,
+    LIBERA_CFG_SWDELAY,
+    LIBERA_CFG_DFA,
+    LIBERA_CFG_DEC_DDC,
+    LIBERA_CFG_DDC_MAFLENGTH,
+    LIBERA_CFG_DDC_MAFDELAY,
+    LIBERA_CFG_TRIGDELAY,
+    LIBERA_CFG_BCD_XOFFSET,
+    LIBERA_CFG_BCD_YOFFSET,
+    // Add new parameters before this line.
+#define LIBERA_CFG_COEFF   256 // position of coefficients in the param array
+#define LIBERA_CFG_NOTCH_MAX 5 // hardcoded number of coefficients
+    LIBERA_CFG_NOTCH1 = LIBERA_CFG_COEFF,  // start of FIR coefficients
+    LIBERA_CFG_NOTCH2 = LIBERA_CFG_NOTCH1 + LIBERA_CFG_NOTCH_MAX,
+    LIBERA_CFG_POLYPHASE_FIR = LIBERA_CFG_NOTCH2 + LIBERA_CFG_NOTCH_MAX,
+#define LIBERA_CFG_FIR_MAX 192 // max polyphase FIR = 3 * max decimation
+} LIBERA_CFG_EBPP_GENERIC;
+
+#define LIBERA_DD_CIRCBUF_ATOMS   2097152
+/** No. of DD atoms in one DMA block */
+#define LIBERA_DMA_BLOCK_ATOMS  128
+/* DMA buffer size = PAGE_SIZE << LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_PAGE_ORDER     5
+/** No. of DD atoms in DMA fifo  - Must be power of 2 and sync
+ *  with LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_FIFO_ATOMS  4096
+#define LIBERA_DMA_FIFO_MASK (LIBERA_DMA_FIFO_ATOMS - 1)
+/* Libera EBPP Data on Demand (DD) atom */
+/* NOTE: The size of libera_atom_dd_t structure is important. 
+ *       The minimal lenght of libera_atom_dd_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef struct {
+    libera_S32_t cosVa;
+    libera_S32_t sinVa;
+    libera_S32_t cosVb;
+    libera_S32_t sinVb;
+    libera_S32_t cosVc;
+    libera_S32_t sinVc;
+    libera_S32_t cosVd;
+    libera_S32_t sinVd;
+} libera_atom_dd_t;
+
+
+/* Libera EBPP ADC-rate Data (ADC) atom */
+/* NOTE: The size of libera_atom_adc_t structure is important. 
+ *       The minimal lenght of libera_atom_adc_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef struct {
+    short ChD;
+    short ChC;
+    short ChB;
+    short ChA;
+} libera_atom_adc_t;
+
+
+/* Libera EBPP Slow Acquisition (SA) atom */
+/* NOTE: The size of libera_atom_sa_t structure is important. 
+ *       PAGE_SIZE MUST be a multiple of sizeof(libera_atom_sa_t) for proper 
+ *       buffer wrapping. Pad this structure to the nearest common denominator 
+ *       of PAGE_SIZE and sizeof(libera_atom_sa_t).
+ *       The minimal lenght of libera_atom_sa_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef struct {
+    /* 4 amplitudes */
+    libera_S32_t Va, Vb, Vc, Vd;
+    /* 4 synthetic values -> Sum, Q, X, Y */
+    libera_S32_t Sum, Q, X, Y;
+    /* Cx and Cy for FF */
+    libera_S32_t Cx, Cy;
+    /* 6 values reserved for future use */
+    libera_S32_t reserved[6];
+} libera_atom_sa_t;
+
+#define SA_FIFO_DEPTH    32 /* Top/botoom half SA buffer length in atoms. */
+#define SA_SIZE_WIDTH     1
+#define SA_LOG           64 // SA terminal pipe buffer depth. Must be 2^n.
+
+
+#endif // _EBPP_H_
diff --git a/i-tech/driver/include/hbpp.h b/i-tech/driver/include/hbpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..91c1ea917d20684005e3b2906f49ab1a7be230e4
--- /dev/null
+++ b/i-tech/driver/include/hbpp.h
@@ -0,0 +1,101 @@
+/* $Id: hbpp.h,v 1.5 2007/09/04 07:23:55 ales Exp $ */
+
+/** \file hbpp.h */
+/** Public include file for Libera Hadron (HBPP). */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _HBPP_H_
+#define _HBPP_H_
+
+/** Libera magic number */
+#define LIBERA_MAGIC 0xad00
+
+
+/** Hadron specific CFG parameters. */
+typedef enum {
+    LIBERA_CFG_NONE = LIBERA_CFG_CUSTOM_FIRST, //!< Default.
+} LIBERA_CFG_BBFP_GENERIC;
+
+
+/** Libera Hadron sample */
+typedef struct {
+    short chan[4];
+} libera_sample_t;
+
+/* Atom vs. sample vs. longwords & bytes constants */
+#define LIBERA_DD_CIRCBUF_ATOMS  (32*1024*1024) //<! No. of atoms in HB.
+#define LIBERA_DD_MT_SAMPLES           1        //<! No. of samples in 1 MT.
+#define LIBERA_DD_ATOM_MTS             1        //<! No. of MTs in 1 atom.
+#define LIBERA_DD_ATOM_SAMPLES   (LIBERA_DD_ATOM_MTS*LIBERA_DD_MT_SAMPLES) //<! No. of samples in 1 ATOM.
+/** No. of DD atoms in one DMA block */
+#define LIBERA_DMA_BLOCK_ATOMS  512
+/* DMA buffer size = PAGE_SIZE << LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_PAGE_ORDER     5
+/** No. of DD atoms in DMA fifo  - Must be power of 2 and sync
+ *  with LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_FIFO_ATOMS  16384
+#define LIBERA_DMA_FIFO_MASK (LIBERA_DMA_FIFO_ATOMS - 1)
+/** Maximal No. of samples in read(request) */
+#define HBPP_MAX_SAMPLES   (2*1024*1024)
+
+/** Libera Hadron Data on Demand (DD) atom */
+/*  NOTE: The size of libera_atom_dd_t structure is important. 
+ *        The minimal lenght of libera_atom_dd_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    libera_sample_t sample[LIBERA_DD_ATOM_SAMPLES];
+} libera_atom_dd_t;
+
+
+/* Libera BBFP ADC-rate Data (ADC) atom */
+/* NOTE: The size of libera_atom_adc_t structure is important. 
+ *       The minimal lenght of libera_atom_adc_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef void* libera_atom_adc_t;  // Unused
+
+
+/** Libera Hadron Slow Acquisition (SA) atom */
+/*  NOTE: The size of libera_atom_sa_t structure is important. 
+ *        PAGE_SIZE MUST be a multiple of sizeof(libera_atom_sa_t) for proper 
+ *        buffer wrapping. Pad this structure to the nearest common 
+ *        denominator of PAGE_SIZE and sizeof(libera_atom_sa_t).
+ *        The minimal lenght of libera_atom_sa_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    /* 4 amplitudes */
+    libera_S32_t Va, Vb, Vc, Vd;
+    /* 4 synthetic values -> X, Y, Q & Sum */
+    libera_S32_t X, Y, Q, Sum;
+    /* Cx and Cy for FF */
+    libera_S32_t Cx, Cy;
+    /* 6 values reserved for future use */
+    libera_S32_t reserved[6];
+} libera_atom_sa_t;
+
+#define SA_FIFO_DEPTH    32 /* Top/botoom half SA buffer length in atoms. */
+#define SA_SIZE_WIDTH     1
+#define SA_LOG           64 // SA terminal pipe buffer depth. Must be 2^n.
+
+#endif // _HBPP_H_
diff --git a/i-tech/driver/include/libera.h b/i-tech/driver/include/libera.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a4235cded5893be8b00562342fa1ff8f8ff4e1c
--- /dev/null
+++ b/i-tech/driver/include/libera.h
@@ -0,0 +1,560 @@
+/* $Id: libera.h,v 1.88.2.2 2008/02/01 14:29:20 tomazb Exp $ */
+
+/** \file libera.h */
+/** Public include file for GNU/Linux Libera driver. */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_H_
+#define _LIBERA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/ioctl.h>
+#ifndef __KERNEL__
+#include <time.h>
+#include <limits.h>
+#endif
+
+
+
+/** Libera magic number for ioctl() calls */
+#define LIBERA_IOC_MAGIC    'l'
+#define LIBERA_EVENT_MAGIC  'e'
+#define LIBERA_DSC_MAGIC    'd'
+
+/** Libera description */
+typedef struct {
+    int magic;           //!< Magic number.
+    char name[32];       //!< Libera family member name.
+    char fpga[32];       //!< FPGA version.
+} libera_desc_t;
+
+
+/** Libera signed 32-bit */
+typedef int libera_S32_t;
+/** Libera unsigned 32-bit */
+typedef unsigned int libera_U32_t;
+/** Libera signed 64-bit */
+typedef long long libera_S64_t;
+/** Libera unsigned 64-bit */
+typedef unsigned long long libera_U64_t;
+/** Libera 64-bit time storage type. Used for (L)MT & (L)ST */
+typedef unsigned long long libera_hw_time_t; 
+/** Libera timing pair, LMT & LST */    
+typedef struct 
+{
+    libera_hw_time_t lst;  //!< Libera System Time
+    libera_hw_time_t lmt;  //!< Libera Machine Time
+} libera_Ltimestamp_t;
+/** Libera userland timing pair, MT & ST */
+typedef struct 
+{
+    struct timespec  st;   //!< System Time
+    libera_hw_time_t mt;   //!< Machine Time
+} libera_timestamp_t;
+/** Libera High resolution userland timing pair, MT + D & ST */
+typedef struct 
+{
+    struct timespec  st;    //!< System Time
+    libera_hw_time_t mt;    //!< Machine Time
+    unsigned long    phase; //!< LMT phase (0...D-1)
+} libera_HRtimestamp_t;
+
+
+/** Libera event structure */
+typedef struct 
+{
+    int id;                //!< Event ID
+    int param;             //!< Event specific parameter
+} libera_event_t;
+
+/** Helper macro for events & event masks */
+#define EVENT(n)  (1 << n)
+/** Event IDs to be used in libera_event_t.id */
+typedef enum
+{
+    LIBERA_EVENT_USER       = UINT_MAX/2, //!< User defined event
+    LIBERA_EVENT_OVERFLOW   = EVENT(0),   //!< Fifo overflow
+    LIBERA_EVENT_CFG        = EVENT(1),   //!< Configuration change
+    LIBERA_EVENT_SA         = EVENT(2),   //!< Slow Acq. sample available
+    LIBERA_EVENT_INTERLOCK  = EVENT(3),   //!< Interlock fired
+    LIBERA_EVENT_PM         = EVENT(4),   //!< Post Mortem trigger
+    LIBERA_EVENT_FA         = EVENT(5),   //!< Fast Application trigger
+    LIBERA_EVENT_TRIGGET    = EVENT(6),   //!< GET Trigger trigger
+    LIBERA_EVENT_TRIGSET    = EVENT(7),   //!< SET Trigger trigger
+} libera_event_id_t;
+
+/** Libera event specific parameter values. */
+typedef enum
+{
+    /* OVERFLOW */
+    LIBERA_OVERFLOW_DD_FPGA = 0, //!< Data on demand fifo overflow in FPGA
+    LIBERA_OVERFLOW_SA_FPGA,     //!< Slow Acq. fifo overflow in FPGA
+    LIBERA_OVERFLOW_SA_DRV,      //!< Slow Acq. fifo overflow in driver
+    /* FA */
+    LIBERA_TRIG_FA_MC0,          //!< FA MC trigger #0
+    LIBERA_TRIG_FA_MC1,          //!< FA MC trigger #1
+    LIBERA_TRIG_FA_SC0,          //!< FA SC trigger #0
+    LIBERA_TRIG_FA_SC1,          //!< FA SC trigger #1
+} libera_event_param_t;
+
+/** Libera interlock parameter values. */
+typedef enum
+{
+    LIBERA_INTERLOCK_X    = (1<<0), //!< IL position X out of limit
+    LIBERA_INTERLOCK_Y    = (1<<1), //!< IL position Y out of limit
+    LIBERA_INTERLOCK_ATTN = (1<<2), //!< Attenuators set higher than predefined value
+    LIBERA_INTERLOCK_ADCF = (1<<3), //!< ADC Overflow  (filtered)
+    LIBERA_INTERLOCK_ADC  = (1<<4), //!< ADC Overflow  (not filtered)
+} libera_interlock_param_t;
+
+/** Available modes of operation. */
+// TOOD: Possibly remove from the driver
+typedef enum {
+	LIBERA_MODE_UNKNOWN = 0,	//!< Libera mode unknown or not set.
+	LIBERA_MODE_DD,			//!< Data-on-demand mode.
+	LIBERA_MODE_SA,			//!< Slow Acquisition mode.
+	LIBERA_MODE_PM,			//!< Post-Mortem mode.
+	LIBERA_MODE_ADC,		//!< ADC-rate buffer mode.
+} LIBERA_MODE;
+
+/** Available trigger modes. */
+typedef enum {
+    	LIBERA_TRIGMODE_UNKNOWN = 0,	//!< Unknown trigger mode.
+	LIBERA_TRIGMODE_GET,	        //!< Get trigger mode.
+	LIBERA_TRIGMODE_SET,	        //!< Set trigger mode.
+} LIBERA_TRIGMODE;
+
+
+/* LIBERA ioctl() command identifiers */
+/* NOTE: The ordinal numbers (2nd paramter to _IO* IOCTL macros) 
+ *       are divided into subsets corresponding to each set/group of
+ *       LIBERA commands. The upper bit (MSB) is group/subset bit and 
+ *       the rest 7 bits are sequential number bits. This gives us room for
+ *       hosting 128 commands per group.
+ *       GET_ commands MUST use _IOR macro.
+ *       SET_ commands MUST use _IOW macro.
+ */
+#define LIBERA_IOC_IS_SET_METHOD(number) ((number) & 0x01)
+#define LIBERA_IOC_IS_GET_METHOD(number) (!((number) & 0x01))
+#define LIBERA_IOC_MASK  0xE0 /* 3 MSB bits                       */
+#define LIBERA_IOC_CFG      0 /* Common Configuration Parameters  */
+#define LIBERA_IOC_SA      32 /* Slow Acquisition Parameters      */
+#define LIBERA_IOC_FA      64 /* Fast Application Parameters      */
+#define LIBERA_IOC_DD      96 /* Data on Demand Parameters */
+#define LIBERA_IOC_PM     128 /* Post Mortem Parameters */
+#define LIBERA_IOC_DSC    160 /* DSC Parameters */
+
+
+/* Libera CFG device parameter IOC tags */
+typedef enum
+{
+    LIBERA_CFG_REQUEST = LIBERA_IOC_CFG,
+    LIBERA_CFG_MAGIC,
+    LIBERA_CFG_DESC,
+#ifdef DEBUG
+    LIBERA_CFG_MODULERESET,
+#endif
+} libera_cfg_tags_t;
+
+/* Libera SA device parameter IOC tags */
+typedef enum
+{
+    LIBERA_SA_NONE = LIBERA_IOC_SA,
+} libera_sa_tags_t;
+
+/* Libera FA device parameter IOC tags */
+typedef enum
+{
+    LIBERA_FA_NONE = LIBERA_IOC_FA,
+} libera_fa_tags_t;
+
+/* Libera DD device parameter IOC tags */
+typedef enum
+{
+    LIBERA_DD_DEC = LIBERA_IOC_DD,
+    LIBERA_DD_TSTAMP,
+} libera_dd_tags_t;
+
+/* Libera PM device parameter IOC tags */
+typedef enum
+{
+    LIBERA_PM_TSTAMP = LIBERA_IOC_PM,
+} libera_pm_tags_t;
+
+
+typedef struct
+{
+    unsigned int idx;
+    unsigned int val;
+} libera_cfg_request_t;
+
+
+/** Configuration Parameters, common to all Libera members */
+typedef enum {
+    /** Trigger mode (set, get, ...) */
+    LIBERA_CFG_TRIGMODE = 0,
+    /** MC PLL status */
+    LIBERA_CFG_MCPLL,
+    /** SC PLL status */
+    LIBERA_CFG_SCPLL,
+    /** Customer Feature Register */
+    LIBERA_CFG_FEATURE_CUSTOMER,
+    /** ITECH Feature Register */
+    LIBERA_CFG_FEATURE_ITECH,
+    /** First custom (Libera member specific) parameter */
+    LIBERA_CFG_CUSTOM_FIRST = 128,
+} LIBERA_CFG_COMMON;
+
+/** Feature detection using ioctl(CFG_GET, LIBERA_CFG_FEATURE_ITECH) */
+#define LIBERA_IS_BPM(_cfg)        ((_cfg & 0xf0000000) == 0)
+#define LIBERA_IS_BRILLIANCE(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 0x0f000000) == 0x01000000))
+#define LIBERA_IS_MAF(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 0x10) == 0x10))
+#define LIBERA_IS_GBETHERNET(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 8) == 8))
+#define LIBERA_IS_GBE_DEMO(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 4) == 4))
+#define LIBERA_IS_DESY_MOLEX(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 2) == 2))
+#define LIBERA_IS_GROUPING(_cfg) (LIBERA_IS_BPM(_cfg) && ((_cfg & 1) == 1))
+
+#ifdef _EMBEDDED_DEVICE_ //- nl-soleil-compil-workaround
+enum libera_ioc_ids_t
+{
+    /***********************************/
+    /* Common Configuration Parameters */
+    /***********************************/
+    /* GENERIC: Generic, nameless CFG parameters */
+    LIBERA_IOC_GET_CFG       = _IOWR(LIBERA_IOC_MAGIC,
+				     LIBERA_CFG_REQUEST,
+				     libera_cfg_request_t),
+    LIBERA_IOC_SET_CFG       = _IOW(LIBERA_IOC_MAGIC,
+				    LIBERA_CFG_REQUEST,
+				    libera_cfg_request_t),
+    /* MAGIC: Libera magic number */
+    LIBERA_IOC_GET_MAGIC     = _IOR(LIBERA_IOC_MAGIC,
+				    LIBERA_CFG_MAGIC, int),
+    /* DESC: Libera description */
+    LIBERA_IOC_GET_DESC      = _IOR(LIBERA_IOC_MAGIC,
+				    LIBERA_CFG_DESC, libera_desc_t),
+    
+    
+    /*******************************/
+    /* Slow Acquisition Parameters */
+    /*******************************/
+    /* NONE */
+    
+    /*******************************/
+    /* Fast Acquisition Parameters */
+    /*******************************/
+    /* NONE */    
+    
+    /*****************************/
+    /* Data on Demand Parameters */
+    /*****************************/
+    /* DEC: Decimation */
+    LIBERA_IOC_GET_DEC       = _IOR(LIBERA_IOC_MAGIC, 
+				    LIBERA_DD_DEC, libera_U32_t),
+    LIBERA_IOC_SET_DEC       = _IOW(LIBERA_IOC_MAGIC,
+				    LIBERA_DD_DEC, libera_U32_t),
+    /* DD_TSTAMP: DD data timestamp */
+    LIBERA_IOC_GET_DD_TSTAMP = _IOR(LIBERA_IOC_MAGIC, 
+				    LIBERA_DD_TSTAMP, 
+				    libera_timestamp_t),
+
+    /*****************************/
+    /* Post Mortem Parameters */
+    /*****************************/
+    /* PM_TSTAMP: PM data timestamp */
+    LIBERA_IOC_GET_PM_TSTAMP = _IOR(LIBERA_IOC_MAGIC, 
+				    LIBERA_PM_TSTAMP, 
+				    libera_timestamp_t),
+
+     /* All DEBUG IDs have to be declared at the bottom of enum! */
+    
+};
+#endif
+
+/**********************/
+/* Event device IOCTL */
+/**********************/
+typedef enum
+{
+    LIBERA_EVENT_DAC_A,
+    LIBERA_EVENT_DAC_B,
+    LIBERA_EVENT_SC_TRIG,
+    LIBERA_EVENT_MC_TRIG,
+    LIBERA_EVENT_ST,
+    LIBERA_EVENT_MT,
+    LIBERA_EVENT_SC_EVENT,
+    LIBERA_EVENT_SC_TRIGGER_19,
+    LIBERA_EVENT_SC_TRIGGER_10,
+    LIBERA_EVENT_SC_TRIGGER_9,
+    LIBERA_EVENT_MC_TRIGGER_19,
+    LIBERA_EVENT_MC_TRIGGER_10,
+    LIBERA_EVENT_FLMC,
+    LIBERA_EVENT_CTIME,
+    LIBERA_EVENT_TRIG_TRIGGER,
+    LIBERA_EVENT_TRIGGER_BLOCK,
+    LIBERA_EVENT_MASK,
+    LIBERA_EVENT_FLUSHING,
+    LIBERA_EVENT_PMBUF,
+    LIBERA_EVENT_MCPHI,
+    LIBERA_EVENT_SCPHI,
+    LIBERA_EVENT_MC_TRIGGER_1,
+    LIBERA_EVENT_MC_TRIGGER_0,
+    LIBERA_EVENT_NCO,
+    LIBERA_EVENT_MCPLL,
+    LIBERA_EVENT_SCPLL,
+    LIBERA_EVENT_FIFOLEN_SC,
+    LIBERA_EVENT_FIFOLEN_MC,
+
+    /* All DEBUG IDs have to be declared at the bottom of enum! */
+#ifdef DEBUG
+    LIBERA_EVENT_PEEK_POKE,
+    LIBERA_EVENT_EVENTSIM,
+    LIBERA_EVENT_OFFPLL,
+#endif
+} libera_event_tags_t;
+
+#ifdef DEBUG
+typedef struct 
+{
+    unsigned long offset;
+    unsigned long value;
+} libera_peek_poke_t;
+#endif
+
+#ifdef _EMBEDDED_DEVICE_ //- nl-soleil-compil-workaround
+enum libera_event_ids_t
+{    
+    LIBERA_EVENT_SET_DAC_A       =  _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_DAC_A,
+					 libera_S32_t),
+    
+    LIBERA_EVENT_SET_DAC_B       =  _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_DAC_B,
+					 libera_S32_t),
+    
+    LIBERA_EVENT_SET_SC_EVENT    =  _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_SC_EVENT,
+					 libera_S32_t),
+    
+    LIBERA_EVENT_ENABLE_SC_TRIG  =  _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_SC_TRIG,
+					 libera_S32_t),
+    
+    LIBERA_EVENT_ENABLE_MC_TRIG  =  _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_MC_TRIG,
+					 libera_S32_t),
+    
+    LIBERA_EVENT_GET_SC_TRIGGER_19= _IOR(LIBERA_EVENT_MAGIC, 
+					 LIBERA_EVENT_SC_TRIGGER_19,
+					 libera_hw_time_t),
+    
+    LIBERA_EVENT_GET_MC_TRIGGER_19= _IOR(LIBERA_EVENT_MAGIC, 
+					 LIBERA_EVENT_MC_TRIGGER_19,
+					 libera_hw_time_t),
+    
+    LIBERA_EVENT_GET_SC_TRIGGER_10= _IOR(LIBERA_EVENT_MAGIC, 
+					 LIBERA_EVENT_SC_TRIGGER_10,
+					 libera_hw_time_t),
+    
+    LIBERA_EVENT_GET_SC_TRIGGER_9=  _IOR(LIBERA_EVENT_MAGIC, 
+					 LIBERA_EVENT_SC_TRIGGER_9,
+					 libera_hw_time_t),
+    
+    LIBERA_EVENT_GET_MC_TRIGGER_10= _IOR(LIBERA_EVENT_MAGIC, 
+					 LIBERA_EVENT_MC_TRIGGER_10,
+					 libera_hw_time_t),
+
+    /* ST: System Time */
+    LIBERA_EVENT_GET_ST            = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_ST,
+					  struct timespec),
+    LIBERA_EVENT_SET_ST            = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_ST,
+					  libera_HRtimestamp_t),
+    
+    /* MT: Machine Time */
+    LIBERA_EVENT_GET_MT            = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_MT, 
+					  libera_hw_time_t),
+    LIBERA_EVENT_SET_MT            = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_MT,
+					  libera_HRtimestamp_t),
+    
+    /* Transfer of measured MC frequency f_MC */
+    LIBERA_EVENT_GET_FLMC          = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_FLMC,
+					  libera_U32_t),
+    LIBERA_EVENT_SET_FLMC          = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_FLMC,
+					  libera_U32_t),
+    
+    LIBERA_EVENT_GET_MCPHI         = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_MCPHI,
+					  libera_hw_time_t),
+
+    LIBERA_EVENT_SET_MCPHI        = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_MCPHI,
+					  libera_hw_time_t),
+
+    LIBERA_EVENT_GET_SCPHI         = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_SCPHI,
+					  libera_hw_time_t),
+
+    LIBERA_EVENT_SET_SCPHI        = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_SCPHI,
+					  libera_hw_time_t),
+
+    /* Current Libera time */
+    LIBERA_EVENT_GET_CTIME         = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_CTIME,
+					  libera_Ltimestamp_t),
+    
+    /* Libera time of the last TRIGGER trigger */
+    LIBERA_EVENT_GET_TRIG_TRIGGER  = _IOR(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_TRIG_TRIGGER, 
+					  libera_Ltimestamp_t),
+    
+    LIBERA_EVENT_GET_MASK          = _IOR(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_MASK, 
+					 libera_U32_t),
+    
+    LIBERA_EVENT_SET_MASK          = _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_MASK, 
+					 libera_U32_t),
+    
+    LIBERA_EVENT_FLUSH             = _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_FLUSHING,
+					 libera_U32_t),
+
+    LIBERA_EVENT_ACQ_PM            = _IOW(LIBERA_EVENT_MAGIC,
+					  LIBERA_EVENT_PMBUF,
+					  libera_U32_t),
+
+    LIBERA_EVENT_GET_MC_TRIGGER_1 = _IOR(LIBERA_EVENT_MAGIC,
+                                         LIBERA_EVENT_MC_TRIGGER_1,
+                                         libera_hw_time_t),
+
+    LIBERA_EVENT_GET_MC_TRIGGER_0 = _IOR(LIBERA_EVENT_MAGIC,
+                                         LIBERA_EVENT_MC_TRIGGER_0,
+                                         libera_hw_time_t),
+
+    LIBERA_EVENT_SET_NCO           = _IOW(LIBERA_EVENT_MAGIC,
+                                          LIBERA_EVENT_NCO,
+                                          libera_U32_t),
+
+    LIBERA_EVENT_SET_MCPLL         = _IOW(LIBERA_EVENT_MAGIC,
+                                          LIBERA_EVENT_MCPLL,
+                                          libera_U32_t),
+
+    LIBERA_EVENT_SET_SCPLL         = _IOW(LIBERA_EVENT_MAGIC,
+                                          LIBERA_EVENT_SCPLL,
+                                          libera_U32_t),
+
+    LIBERA_EVENT_GET_FIFOLEN_SC    = _IOWR(LIBERA_EVENT_MAGIC,
+                                           LIBERA_EVENT_FIFOLEN_SC,
+                                           libera_U32_t),
+
+    LIBERA_EVENT_GET_FIFOLEN_MC    = _IOWR(LIBERA_EVENT_MAGIC,
+                                           LIBERA_EVENT_FIFOLEN_MC,
+                                           libera_U32_t),
+    
+    /* All DEBUG IDs have to be declared at the bottom of enum! */
+#ifdef DEBUG
+    LIBERA_EVENT_GET_TRIGGER_BLOCKED = _IOR(LIBERA_EVENT_MAGIC,
+					    LIBERA_EVENT_TRIGGER_BLOCK, 
+					    libera_Ltimestamp_t),
+
+    LIBERA_EVENT_SET_OFFPLL          = _IOW(LIBERA_EVENT_MAGIC,
+					    LIBERA_EVENT_OFFPLL,
+					    libera_hw_time_t),
+    
+    LIBERA_EVENT_PEEK             = _IOR(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_PEEK_POKE,
+					 libera_peek_poke_t),
+    
+    
+    LIBERA_EVENT_POKE             = _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_PEEK_POKE,
+					 libera_peek_poke_t),
+    
+    LIBERA_EVENT_EVENT_SIM        = _IOW(LIBERA_EVENT_MAGIC,
+					 LIBERA_EVENT_EVENTSIM, 
+					 libera_U32_t),
+    
+#endif
+};
+#endif
+
+/**********************/
+/* DSC device IOCTL */
+/**********************/
+typedef enum
+{
+    LIBERA_DSC_SET = LIBERA_IOC_DSC,
+    LIBERA_DSC_BCD,
+} libera_dsc_tags_t;
+
+typedef struct
+{
+    int X;
+    int Y;
+} libera_offsets_t;
+
+#ifdef _EMBEDDED_DEVICE_ //- nl-soleil-compil-workaround
+enum libera_dsc_ids_t
+{    
+    LIBERA_DSC_SET_DSC       =  _IOW(LIBERA_DSC_MAGIC,
+                                     LIBERA_DSC_SET,
+                                     libera_U32_t),
+
+    LIBERA_DSC_BCD_OFFSETS   =  _IOW(LIBERA_DSC_MAGIC,
+                                     LIBERA_DSC_BCD,
+                                     libera_offsets_t),
+};
+#endif
+
+/* Include family member specifics */
+#ifdef EBPP
+#include "ebpp.h"
+#endif
+#ifdef BBFP
+#include "bbfp.h"
+#endif
+#ifdef HBPP
+#include "hbpp.h"
+#endif
+#ifdef DPP
+#include "dpp.h"
+#endif
+
+
+#define TRIGGER_BIT(x)     (1 << (x+22))
+	
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBERA_H
diff --git a/i-tech/driver/include/libera_adc.h b/i-tech/driver/include/libera_adc.h
new file mode 100644
index 0000000000000000000000000000000000000000..c35a9bbf94f4d5a5524d45257f9c29f9411083b3
--- /dev/null
+++ b/i-tech/driver/include/libera_adc.h
@@ -0,0 +1,31 @@
+/* $Id: libera_adc.h,v 1.2 2006/01/03 10:29:46 ales Exp $ */
+
+//! \file libera_adc.h
+//! Libera GNU/Linux driver ADC-rate Data (ADC) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_ADC_H_
+#define _LIBERA_ADC_H_
+
+
+#endif /* _LIBERA_ADC_H_ */
diff --git a/i-tech/driver/include/libera_cfg.h b/i-tech/driver/include/libera_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2db8df1f64889c2fb96d1561beae19a7fca3782
--- /dev/null
+++ b/i-tech/driver/include/libera_cfg.h
@@ -0,0 +1,35 @@
+/* $Id: libera_cfg.h,v 1.6 2006/01/03 10:29:46 ales Exp $ */
+
+//! \file libera_cfg.h
+//! Libera GNU/Linux driver Configuration (CFG) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_CFG_H_
+#define _LIBERA_CFG_H_
+
+int 
+libera_cfg_cmd(struct libera_cfg_device *dev,
+	       unsigned int cmd, unsigned long arg);
+
+
+#endif /* _LIBERA_CFG_H_ */
diff --git a/i-tech/driver/include/libera_dd.h b/i-tech/driver/include/libera_dd.h
new file mode 100644
index 0000000000000000000000000000000000000000..030e76893803cbf8977618fc577b918a7908ace3
--- /dev/null
+++ b/i-tech/driver/include/libera_dd.h
@@ -0,0 +1,230 @@
+/* $Id: libera_dd.h,v 1.20 2007/10/16 14:44:02 tomazb Exp $ */
+
+//! \file libera_dd.h
+//! Libera GNU/Linux driver Data on Demand (DD) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_DD_H_
+#define _LIBERA_DD_H_
+
+/** Convert System Time (ST) to Libera System Time (LST). */
+static inline void
+st2lst(const struct timespec *st, 
+       libera_hw_time_t *lst)
+{
+    /* NOTE: This conversion is safe regarding overflow in nsec part
+     *       and up to 1.47e11 seconds from UNIX 0 (@ LSC = 125 MHz).
+     */
+
+    *lst = (libera_hw_time_t)st->tv_sec * LSC_FREQ +
+	libera_do_div64u(((libera_hw_time_t)st->tv_nsec * LSC_FREQ),NS_IN_SECOND);
+
+}
+
+
+/** Convert Libera System Time (LST) to System Time (ST). */
+static inline void
+lst2st(const libera_hw_time_t *lst,
+       struct timespec *st)
+{
+	st->tv_sec = libera_do_div64u((*lst),LSC_FREQ);
+	st->tv_nsec = libera_do_mod64u((*lst),LSC_FREQ)*(NS_IN_SECOND / LSC_FREQ);
+
+}
+
+
+/** Convert Machine Time (MT) to Libera Machine Time (LMT). */
+static inline void
+mt2lmt(const libera_hw_time_t *mt,
+       libera_hw_time_t *lmt)
+{
+    *lmt = (*mt) * lgbl.d;
+}
+
+
+/** Convert Libera Machine Time (LMT) to Machine Time (MT). */
+static inline void
+lmt2mt(const libera_hw_time_t *lmt,
+       libera_hw_time_t *mt)
+{
+
+	*mt = libera_do_div64u((*lmt), lgbl.d);
+	
+  
+}
+
+
+/** LMT to Circular Buffer transformation
+ *
+ * Provides the Circular Buffer offset (position), based on LMT.
+ */
+static inline libera_U32_t
+get_circ_offset_lmt(libera_hw_time_t *lmt)
+{
+    struct libera_event_device  *event  = &libera_event;
+    
+
+
+
+	unsigned long long dummy_first_part, dummy_divisor   ;
+	unsigned long return_value;
+
+	dummy_first_part = (*lmt - (event->settime.lmt.off + event->HB_start_lmt) + lgbl.d/2);
+	dummy_divisor = libera_do_div64u(dummy_first_part, lgbl.d);
+
+	return_value =  libera_do_mod64u(dummy_divisor,LIBERA_DD_CIRCBUF_ATOMS);
+	
+	return return_value;
+    
+}
+
+
+/** MT to Circular Buffer transformation
+ *
+ * Provides the Circular Buffer offset (position), based on MT.
+ */
+static inline libera_U32_t
+get_circ_offset_mt(libera_hw_time_t *mt)
+{
+    struct libera_event_device  *event  = &libera_event;
+    
+
+	unsigned long long dummy_first_part, dummy_divisor ;
+	unsigned long return_value;
+
+	dummy_first_part =  (event->settime.lmt.off + event->HB_start_lmt);
+	dummy_divisor = libera_do_div64u(dummy_first_part, lgbl.d);
+
+	return_value = libera_do_mod64u((*mt - dummy_divisor),LIBERA_DD_CIRCBUF_ATOMS) ;
+
+	return return_value;
+
+
+};
+
+
+/** Convert Libera System Time (LST) to Libera Machine Time (LMT).
+ *  On success, 0 is returned.
+ *  On error, meaningful negative errno is returned.
+ */
+static inline int
+lst2lmt(const libera_hw_time_t *lst,
+        libera_hw_time_t *lmt,
+        const libera_Ltimestamp_t *stime)
+{
+  libera_hw_time_t deltaLST;
+  libera_hw_time_t deltaLMT;
+  int positive;
+
+  /* This is to avoid using signed 64-bit type for division
+   * (unresolved symbol __divdi3)
+   */
+  if (*lst > stime->lst)
+    {
+      deltaLST = *lst - stime->lst;
+      positive = TRUE;
+    }
+  else
+    {
+      deltaLST = stime->lst - *lst;
+      positive = FALSE;
+    }
+
+  /* NOTE: 64-bit unsigned data type used for deltaLMT allows for
+   *       correct transformation for times up to cca. 15.7e9 LST
+   *       away from the stime sync point in the worst case
+   *       scenario (LMC = f_lmc = 117.440 MHz -> Diamond storage).
+   *       Above these times, we will get overflow problems.
+   *       This roughly corresponds to 124 seconds (@ LSC = 125 MHz).
+   *       Be sure to adjust DELTA_LST_OVERFLOW according to the
+   *       worst case LMC.
+   */
+  if (deltaLST >  DELTA_LST_OVERFLOW)
+    {
+      ASSERT(TRUE);
+      return -ERANGE;
+    }
+ 
+  deltaLMT = libera_do_div64u((deltaLST * flmcdHz),(LSC_FREQ * FLMC_DECI_HZ));
+
+
+  if (positive)
+    *lmt = stime->lmt + deltaLMT;
+  else
+    *lmt = stime->lmt - deltaLMT;
+
+  return 0;
+}
+
+
+/** Convert Libera Machine Time (LMT) to Libera System Time (LST).
+ *  On success, 0 is returned.
+ *  On error, meaningful negative errno is returned.
+ */
+static inline int
+lmt2lst(const libera_hw_time_t *lmt,
+        libera_hw_time_t *lst,
+        const libera_Ltimestamp_t *stime)
+{
+  libera_hw_time_t deltaLST;
+  libera_hw_time_t deltaLMT;
+  int positive;
+
+  /* This is to avoid using signed 64-bit type for division
+   * (unresolved symbol __divdi3)
+   */
+  if (*lmt > stime->lmt)
+    {
+      deltaLMT = *lmt - stime->lmt;
+      positive = TRUE;
+    }
+  else
+    {
+      deltaLMT = stime->lmt - *lmt;
+      positive = FALSE;
+    }
+  /* NOTE: 64-bit unsigned data type used for deltaLST allows for
+   *       correct transformation for times up to cca. 14.7e9 LMT
+   *       away from the stime sync point (@ LSC = 125 MHz).
+   *       Above these times, we will get overflow problems.
+   *       This roughly corresponds to 124 seconds in the worst case
+   *       scenario (@ LMC = f_lmc = 117.440 MHz -> Diamond storage).
+   *       Be sure to adjust DELTA_LMT_OVERFLOW according to LSC.
+   */
+  if (deltaLMT >  DELTA_LMT_OVERFLOW)
+    {
+	    PDEBUG2("deltaLMT has value 0x%08lx%08lx in function %s \n",ULL(deltaLMT),__FUNCTION__);
+      ASSERT(TRUE);
+      return -ERANGE;
+    }
+
+  deltaLST = libera_do_div64u((deltaLMT * LSC_FREQ * FLMC_DECI_HZ),flmcdHz);
+  
+  if (positive)
+    *lst = stime->lst + deltaLST;
+  else
+    *lst = stime->lst - deltaLST;
+  return 0;
+}
+
+#endif /* _LIBERA_DD_H_ */
diff --git a/i-tech/driver/include/libera_dsc.h b/i-tech/driver/include/libera_dsc.h
new file mode 100644
index 0000000000000000000000000000000000000000..54146247f53d341aca812d58aac1e105e9025ebc
--- /dev/null
+++ b/i-tech/driver/include/libera_dsc.h
@@ -0,0 +1,31 @@
+/* $Id: libera_dsc.h,v 1.2 2007/05/16 12:59:18 janko Exp $ */
+
+//! \file libera_dsc.h
+//! Libera GNU/Linux driver Digital Signal Conditioning (DSC) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_DSC_H_
+#define _LIBERA_DSC_H_
+
+
+#endif /* _LIBERA_DSC_H_ */
diff --git a/i-tech/driver/include/libera_event.h b/i-tech/driver/include/libera_event.h
new file mode 100644
index 0000000000000000000000000000000000000000..e27c82d45d97a9d16ef77b170c6becf81b3a6b3f
--- /dev/null
+++ b/i-tech/driver/include/libera_event.h
@@ -0,0 +1,240 @@
+/* $Id: libera_event.h,v 1.5 2007/07/04 13:14:44 ales Exp $ */
+
+//! \file libera_event.h
+//! Libera GNU/Linux driver (A)synchronous Event device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+#include<asm/dma.h>
+
+#ifndef _LIBERA_EVENT_H_
+#define _LIBERA_EVENT_H_
+
+/*
+ FIFO libera_event miscellaneous functions
+*/
+
+static inline void flushFIFO(struct libera_fifo *q)
+{
+  q->put=q->get=0;
+}
+
+static inline int lenFIFO(struct libera_fifo *q)
+{
+  return ( (q->put + TRIG_LOG - q->get) & TRIG_LOG_MASK );
+}
+static inline int not_emptyFIFO(struct libera_fifo *q)
+{
+  return (q->put != q->get);
+}
+static inline int emptyFIFO(struct libera_fifo *q)
+{
+  return (q->put == q->get);
+}
+
+static inline int putToFIFO(struct libera_fifo *q, unsigned long long data)
+{
+  register int index;
+  if((index=((q->put + 1) & TRIG_LOG_MASK)) == q->get)
+    {
+      return -1;  /* fifo would overflow */
+    }
+  else
+    {
+      q->stamp[index] = data;
+      q->put = index;
+      return 0;
+    }
+}
+
+static inline unsigned long long* getFromFIFO(struct libera_fifo* const q)
+{
+  if(q->put == q->get)
+    {
+      return NULL; /* fifo empty */
+    }
+  else
+    {
+      q->get = (q->get + 1) & TRIG_LOG_MASK;
+      return & q->stamp[q->get];
+    }
+}
+
+
+/******************************/
+/* Paired Time CircBuf Queues */
+/******************************/
+static inline void flushCircBuf(struct libera_circbuf* const q)
+{
+    memset(q, 0, sizeof(struct libera_circbuf));
+}
+
+/* LST should always be put to CircBuf first! -> Check interrupt priority! */
+static inline void putLSTtoCircBuf(struct libera_circbuf* const q, 
+				   const libera_hw_time_t *lst)
+{
+    q->stamp[q->put].lst = *lst;    
+}
+
+/* LMT should always be put to CircBuf last! -> Check interrupt priority! */
+static inline void putLMTtoCircBuf(struct libera_circbuf* const q,
+				   const libera_hw_time_t *lmt)
+{
+    q->stamp[q->put].lmt = *lmt;
+    q->put = ((q->put + 1) & TRIG_LOG_MASK);
+}
+
+static inline void putToCircBuf(struct libera_circbuf* const q,
+				const libera_Ltimestamp_t *data)
+{
+    q->stamp[q->put] = *data;
+    q->put = ((q->put + 1) & TRIG_LOG_MASK);
+}
+
+static inline libera_Ltimestamp_t*
+getFromCircBuf(struct libera_circbuf* const q)
+{ 
+    register int index;
+    index = ((q->put - 1) & TRIG_LOG_MASK);
+    return & q->stamp[index];
+}
+
+
+/* DMA fifos */
+static inline void flushDMA_FIFO(libera_dma_t *q)
+{
+    q->put=q->get=0;
+}
+
+static inline int lenDMA_FIFO(libera_dma_t *q)
+{
+    int ret;
+
+    spin_lock(&dma_spin_lock);
+    ret = ( (q->put + LIBERA_DMA_FIFO_ATOMS - q->get) & LIBERA_DMA_FIFO_MASK );
+    spin_unlock(&dma_spin_lock);
+
+    return ret;
+}
+static inline int tailDMA_FIFO(libera_dma_t *q)
+{
+    int ret;
+
+    spin_lock(&dma_spin_lock);
+    ret = ( LIBERA_DMA_FIFO_ATOMS - q->put );
+    spin_unlock(&dma_spin_lock);
+
+    return ret;
+}
+static inline int not_emptyDMA_FIFO(libera_dma_t *q)
+{
+    int ret;
+    
+    spin_lock(&dma_spin_lock);
+    ret = (q->put != q->get);
+    spin_unlock(&dma_spin_lock);
+
+    return ret;
+}
+static inline int emptyDMA_FIFO(libera_dma_t *q)
+{
+    int ret;
+
+    spin_lock(&dma_spin_lock);
+    ret = (q->put == q->get);
+    spin_unlock(&dma_spin_lock);
+
+    return ret;
+}
+
+static inline int putToDMA_FIFO(libera_dma_t *q, unsigned int size_atoms)
+{
+    register int index;
+    if((index=((q->put + size_atoms) & LIBERA_DMA_FIFO_MASK)) == q->get)
+	{
+	    return -1;  /* fifo would overflow */
+	}
+    else
+	{
+	    /* Only change the index as DMA copies the data */
+	    q->put = index;
+	    return 0;
+	}
+}
+
+
+
+
+/*
+ FIFO libera_event miscellaneous functions
+*/
+
+static inline void flush_eventFIFO(struct libera_event_fifo *q)
+{
+  q->put=q->get=0;
+}
+
+static inline int len_eventFIFO(struct libera_event_fifo *q)
+{
+  return ( (q->put + TRIG_LOG - q->get) & TRIG_LOG_MASK );
+}
+static inline int not_empty_eventFIFO(struct libera_event_fifo *q)
+{
+  return (q->put != q->get);
+}
+static inline int empty_eventFIFO(struct libera_event_fifo *q)
+{
+  return (q->put == q->get);
+}
+
+static inline int putTo_eventFIFO(struct libera_event_fifo *q, libera_event_t *data)
+{
+  register int index;
+  if((index=((q->put + 1) & TRIG_LOG_MASK)) == q->get)
+    {
+      return -1;  /* fifo would overflow */
+    }
+  else
+    {
+      q->data[index] = *data;
+      q->put = index;
+      return 0;
+    }
+}
+
+static inline libera_event_t* getFrom_eventFIFO(struct libera_event_fifo* const q)
+{
+  if(q->put == q->get)
+    {
+      return NULL; /* fifo empty */
+    }
+  else
+    {
+      q->get = (q->get + 1) & TRIG_LOG_MASK;
+      return & q->data[q->get];
+    }
+}
+
+#define T_FIFO_SIZE(X) (X & 0x1FF)
+#define TRIG_VECTOR TRIG_ALL_MASK /* 9 bit TRIGGER vector */
+#define TRIG_ZERO 0x1 << 22
+#define SELF_INC_TRIGGER 0x200 << 22 /* free running trigger (9) */
+
+#endif /* _LIBERA_EVENT_H_ */
diff --git a/i-tech/driver/include/libera_fa.h b/i-tech/driver/include/libera_fa.h
new file mode 100644
index 0000000000000000000000000000000000000000..95050fff12f98762fa453b4a959fa99c739a78d3
--- /dev/null
+++ b/i-tech/driver/include/libera_fa.h
@@ -0,0 +1,31 @@
+/* $Id: libera_fa.h,v 1.2 2006/01/03 10:29:46 ales Exp $ */
+
+//! \file libera_fa.h
+//! Libera GNU/Linux driver Fast Application (FA) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_FA_H_
+#define _LIBERA_FA_H_
+
+
+#endif /* _LIBERA_FA_H_ */
diff --git a/i-tech/driver/include/libera_kernel.h b/i-tech/driver/include/libera_kernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b5ba14a3d0289f47a92373ed252a9fb2109999b
--- /dev/null
+++ b/i-tech/driver/include/libera_kernel.h
@@ -0,0 +1,975 @@
+/* $Id: libera_kernel.h,v 1.124.2.1 2008/01/09 14:04:11 tomazb Exp $ */
+
+/** \file libera_kernel.h */
+/** Driver kernel interface for GNU/Linux Libera driver. */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _LIBERA_KERNEL_H_
+#define _LIBERA_KERNEL_H_
+
+/* This should only be included in kernel space */
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+
+#include "libera.h"
+
+
+/** Libera GNU/Linux driver version */
+#ifndef RELEASE_VERSION
+#define RELEASE_VERSION unknown
+#endif
+
+/* Default module parameters */
+#define LIBERA_IOBASE           0x14000000
+#define LIBERA_IORANGE          0x00040000 /* 16 x 16k = 256k */
+#define LIBERA_IRQ_GPIO_NR      1
+#define LIBERA_FLMC_INITIAL     1080000000UL  /* dHz = 10^-1 Hz */
+#define LIBERA_D_INITIAL        128    /* Decimation */
+#define LIBERA_DFA_INITIAL      0      /* FA Decimation */
+#define LIBERA_KADC_INITIAL     1000   /* ADC interlock scaling factor x1000 */
+#define LIBERA_ILKDUR_INITIAL   1000   /* ILK overflow duration limit */
+#define LIBERA_PMSIZE_INITIAL   16384  /* Post Mortem buffer size (DD atoms) */
+#define LIBERA_PMSIZE_MAX       262144 /* Post Mortem buffer limit (DD atoms) */
+
+/* Libera SA device structures */
+#define LIBERA_SA_MAX_READERS  16
+
+/**********************/
+/* Register addresses */
+/**********************/
+/* General SBC interface offset from LIBERA_IOBASE */
+#define SBC_OFFSET   0x00000000
+/* Timing (CLK) interface offset from LIBERA_IOBASE */
+#define CLK_OFFSET   0x00004000
+/* ADC-rate buffer offset from LIBERA_IOBASE */
+#define ADC_OFFSET   0x00008000
+/* Digital signal conditioning (DSC) offset from LIBERA_IOBASE */
+#define DSC_OFFSET   0x0000c000
+/* Digital Down Converter (DDC) offset from LIBERA_IOBASE */
+#define DDC_OFFSET   0x00014000
+/* Storage and Circular Buffer offset from LIBERA_IOBASE */
+#define HB_OFFSET    0x00018000
+/* Fast Acquisition offset from LIBERA_IOBASE */
+#define FA_OFFSET    0x0001c000
+/* Slow Acquisition offset from LIBERA_IOBASE */
+#define SA_OFFSET    0x00020000
+/* Interlock offset from LIBERA_IOBASE */
+#define ILK_OFFSET   0x00024000
+/* Fast Application Interface offset from LIBERA_IOBASE */
+#define FAI_OFFSET   0x00028000
+
+/* Signal conditioning offset from LIBERA_IOBASE */
+#define SIGNAL_OFFSET 0x0001c000
+/* Housekeeping components (msp430,fan, diagnostics &.) offset from LIBERA_IOBASE */
+#define HOUSEKEEP_OFFSET 0x00008000
+/* SDRAM controller offset from LIBERA_IOBASE */
+#define SDRAM_OFFSET 0x00004000
+
+
+/* Transform operator prototypes */
+typedef int (*libera_operator_t)( const void *in, void *out );
+
+/* Mirroring of Write-Only registers */
+struct wom_timing_t
+{
+    libera_U32_t swTrigger;
+    libera_U32_t triggerMask;
+};
+struct wom_fa_t
+{
+    libera_U32_t BlockSizeW;
+    libera_U32_t BlockSizeR;
+    libera_U32_t StartAddressW;
+    libera_U32_t StartAddressR;
+    libera_U32_t DataToFPGA[511];
+};
+struct wom_sbc_t
+{
+    libera_U32_t irqMask;
+};
+struct wo_mirror_t
+{
+    struct wom_timing_t timing;
+    struct wom_fa_t fa;
+    struct wom_sbc_t sbc;
+};
+
+
+/* DD pages defines */
+#define DD_HB_PAGE     32  /* HB page size = 1024 bytes = 32 atoms (atom = 8*4 bytes) */
+#define DD_MAX_NOATOMS 0x400000 /* Max. No. of requested Atoms from HB */
+
+/** Libera Quad timestamp MT, ST, LMT & LST */
+typedef struct 
+{
+    libera_timestamp_t  U;
+    libera_Ltimestamp_t L;
+    int request;
+    loff_t relative;
+    libera_Ltimestamp_t lasttrig;
+    loff_t trigoffset;
+} libera_Qtimestamp_t;
+
+
+/* All addresses must be defined as offsets from LIBERA_IOBASE */
+/* DDC register map */
+#define DDC_NCO           0x4 + DDC_OFFSET
+/* DDC Moving Average Filter parameters */
+#define DDC_MAF_LENGTH    0xc  + DDC_OFFSET
+#define DDC_MAF_DELAY     0x10 + DDC_OFFSET
+
+/* SC timing module register map */
+#define T_SC_STATUSL      0x0  + CLK_OFFSET
+#define T_SC_STATUSH      0x4  + CLK_OFFSET
+#define T_SC_EVENTGENL    0x0  + CLK_OFFSET
+#define T_SC_EVENTGENH    0x4  + CLK_OFFSET
+#define T_SC_EVENTGEN     0x8  + CLK_OFFSET
+#define T_SC_FIFOADV      0x8  + CLK_OFFSET
+#define T_SC_TRIGGER_MASK 0x18 + CLK_OFFSET
+
+/* MC timing module register map */
+#define T_MC_STATUSL      0xc  + CLK_OFFSET
+#define T_MC_STATUSH      0x10 + CLK_OFFSET
+#define T_MC_EVENTGENL    0xc  + CLK_OFFSET
+#define T_MC_EVENTGENH    0x10 + CLK_OFFSET
+
+#define T_MC_FIFOADV      0x14 + CLK_OFFSET
+#define T_MC_EVENTGEN     0x14 + CLK_OFFSET
+#define T_MC_TRIGGER_MASK 0x1c + CLK_OFFSET
+
+#define T_TRIG_DELAY      0x38 + CLK_OFFSET
+
+/* Trigger numbers */
+#define T_TRIG_TIME_64_EXT   9
+#define T_TRIG_TRIGGER       8
+#define T_TRIG_POST_MORTEM   7
+#define T_TRIG_MC_PRESCALER  6
+#define T_TRIG_SC_PRESCALER  5
+#define T_TRIG_CTIME         4
+#define T_TRIG_FA3           3
+#define T_TRIG_FA2           2
+#define T_TRIG_FA1           1
+#define T_TRIG_FA0           0
+
+/* Event generation bits */
+#define T_EG_DDC              31
+#define T_EG_HB               30
+#define T_EG_FA               29
+#define T_EG_SA               28
+#define T_EG_FAI              25
+
+/* SPI DAC */
+#define EVENT_SC_DAC      0x20 + CLK_OFFSET
+#define EVENT_MC_DAC      0x24 + CLK_OFFSET
+
+/* FA defines */
+#define FA_POLYPHASE_FIR 0x14   + FA_OFFSET
+#define FA_NOTCH1        0x18   + FA_OFFSET
+#define FA_NOTCH2        0x1c   + FA_OFFSET
+#define FA_FIFO_RESET    0x20   + FA_OFFSET
+
+/* SA defines */
+#define SA_CONTROL       0      + SA_OFFSET
+#define SA_ENABLE        0x0
+#define SA_STOP          0x1
+#define SA_STATUS        0x4    + SA_OFFSET
+#define SA_FIFO_BASE     0x1000 + SA_OFFSET
+
+#define SA_INOVR_LSB    31
+#define SA_SIZE_LSB      0
+#define SA_INOVR_WIDTH   1
+#define SA_INOVR(status) ( (status >> SA_INOVR_LSB) & ((1 << SA_INOVR_WIDTH)-1) )
+#define SA_SIZE(status)  ( (status >> SA_SIZE_LSB)  & ((1 << SA_SIZE_WIDTH)-1)  )
+
+
+/* Interlock defines */
+#define ILK_CONTROL          0x0  + ILK_OFFSET
+#define ILK_XLOW             0x8  + ILK_OFFSET
+#define ILK_XHIGH            0xc  + ILK_OFFSET
+#define ILK_YLOW             0x10 + ILK_OFFSET
+#define ILK_YHIGH            0x14 + ILK_OFFSET
+#define ILK_STATUS           0x18 + ILK_OFFSET
+
+
+/* FAI defines */
+#define FAI_BLOCK            0x0  + FAI_OFFSET
+#define FAI_BLOCKSIZE        0x14000
+#define FAI_CORR_BASE        0x14000    + FAI_OFFSET
+#define FAI_SW_STATUS        0x14024    + FAI_OFFSET
+#define FAI_COUNTER_RESET    0x14028    + FAI_OFFSET
+
+
+/* DSC defines */
+#define DSC_BLOCK            0x0  + ADC_OFFSET
+#define DSC_BLOCKSIZE        0xc000
+
+
+/* DD defines */
+#if defined BBFP
+#define DD_CB_FIFO_POSTFILT   0x0  + HB_OFFSET
+#define DD_CB_FIFO_STARTADDR  0x4  + HB_OFFSET
+#define DD_CB_FIFO_ADDRSTEP   0x8  + HB_OFFSET
+#define DD_CB_FIFO_SNGLSIZE   0xc  + HB_OFFSET
+#define DD_CB_FIFO_NOTRANS    0x10 + HB_OFFSET
+#elif defined HBPP
+#define DD_CB_FIFO_POSTFILT   0x0  + HB_OFFSET
+#define DD_CB_FIFO_STARTADDR  0x4  + HB_OFFSET
+#define DD_CB_FIFO_ADDRSTEP   0x8  + HB_OFFSET
+#define DD_CB_FIFO_SNGLSIZE   0xc  + HB_OFFSET
+#define DD_CB_FIFO_NOTRANS    0x10 + HB_OFFSET
+#else
+#define DD_CB_FIFO_L        0x0  + HB_OFFSET
+#define DD_CB_FIFO_H        0x4  + HB_OFFSET
+#endif
+
+#define DD_CB_FIFO_RESET    0x20 + HB_OFFSET
+
+#define DD_CBH_FDEC_LSB      30
+#define DD_CBH_SADDR_LSB      0
+#define DD_CBH_FDEC_WIDTH     2
+#define DD_CBH_SADDR_WIDTH   21
+
+#define DD_CBL_NOAT_LSB     0
+#define DD_CBL_EADDR_LSB    0
+#define DD_CBL_NOAT_WIDTH  22
+#define DD_CBL_EADDR_WIDTH  8
+
+#define DD_CBH_DEC_64       1
+#define DD_CBH_DEC_1        0
+
+#if defined BBFP
+#define DD_OB_STATUS        0x14   + HB_OFFSET
+#define DD_OB_FIFOBASE      0x1000 + HB_OFFSET
+#elif defined HBPP
+#define DD_OB_STATUS        0x14   + HB_OFFSET
+#define DD_OB_FIFOBASE      0x1000 + HB_OFFSET
+//#define DD_OB_STATUS        0x27800
+//#define DD_OB_FIFOBASE      0x24000
+#else
+#define DD_OB_STATUS        0x8    + HB_OFFSET
+#define DD_OB_FIFOBASE      0x1000 + HB_OFFSET
+#endif
+
+#define DD_OB_BUSY_LSB     31
+#define DD_OB_OVERRUN_LSB  30
+#define DD_OB_SIZE_LSB      0
+#define DD_OB_BUSY_WIDTH    1
+#define DD_OB_OVERRUN_WIDTH 1
+#if defined BBFP
+#define DD_OB_SIZE_WIDTH    11
+#elif defined HBPP
+#define DD_OB_SIZE_WIDTH    11
+//#define DD_OB_SIZE_WIDTH    9
+#else
+#define DD_OB_SIZE_WIDTH    8
+#endif
+
+// TODO: Consider BUSY & OVERRUN without shifting
+#define DD_OB_BUSY(status)   ( (status >> DD_OB_BUSY_LSB)   & ((1 << DD_OB_BUSY_WIDTH)-1)  )
+#define DD_OB_OVERRUN(status)   ( (status >> DD_OB_OVERRUN_LSB)   & ((1 << DD_OB_OVERRUN_WIDTH)-1)  )
+#define DD_OB_SIZE(status)   ( (status >> DD_OB_SIZE_LSB)   & ((1 << DD_OB_SIZE_WIDTH)-1)  )
+
+
+/* IRQ defines */
+#define SBC_IRQ_MASK     0 + SBC_OFFSET //write
+#define SBC_IRQ          0 + SBC_OFFSET
+#define SBC_IRQ2         0x28 + CLK_OFFSET
+
+/* FPGA info defines */ 
+#define FPGA_INFO_COMPILE_TIME  0x4  + SBC_OFFSET
+#define FPGA_INFO_BUILDNO       0x8  + SBC_OFFSET
+
+#define FPGA_INFO_ID            0xc  + SBC_OFFSET
+#define FPGA_ID_BRILLIANCE      0x10
+#define FPGA_ID_ELECTRON        0x1
+
+#define FPGA_INFO_DEC_DDC       0x10 + SBC_OFFSET
+#define FPGA_INFO_DEC_CIC_FIR   0x14 + SBC_OFFSET
+#define FPGA_FEATURE_CUSTOMER   0x18 + SBC_OFFSET
+#define FPGA_FEATURE_ITECH      0x1C + SBC_OFFSET
+
+/* Attenuation */
+#define ATTN_VAL_SIZE    5
+#define ATTN_VAL_MASK    ((1 << ATTN_VAL_SIZE) - 1)
+
+/* M3 DSC */
+#define DSC_MODE                   0x0  + DSC_OFFSET
+#define DSC_ANALOG_SW              0x4  + DSC_OFFSET
+#define DSC_DIGITAL_SW             0x10 + DSC_OFFSET
+#define DSC_ATTN_L                 0x8  + DSC_OFFSET
+#define DSC_ATTN_H                 0xc  + DSC_OFFSET
+#define DSC_ILK_GAIN_LIMIT         0x18 + DSC_OFFSET
+#define DSC_ILK_OVERFLOW_LIMIT     0x1c + DSC_OFFSET
+#define DSC_ILK_OVERFLOW_DUR       0x20 + DSC_OFFSET
+#define DSC_SW_SOURCE              0x38 + DSC_OFFSET
+#define DSC_SW_DELAY               0x3c + DSC_OFFSET
+#define DSC_SW_EXTERNAL            (1 << 31)
+
+#define ATTN7_LSB        24
+#define ATTN6_LSB        16
+#define ATTN5_LSB         8
+#define ATTN4_LSB         0
+#define ATTN3_LSB        24
+#define ATTN2_LSB        16
+#define ATTN1_LSB         8
+#define ATTN0_LSB         0
+#define DSC_MODE_DIGITAL  (1<<1)
+#define DSC_MODE_ATTN     (1<<2)
+#define DSC_MODE_ANALOG   (1<<3)
+#define DSC_MODE_MANUAL   0
+#define DSC_MODE_AUTO     1
+
+/* ADC-rate buffer */
+#define ADC_IRQ_STATUS    0x0    + ADC_OFFSET
+#define ADC_CHAN_AB       0x2000 + ADC_OFFSET
+#define ADC_CHAN_CD       0x3000 + ADC_OFFSET
+#define ADC_OVERFLOW      0x4000 + ADC_OFFSET
+#define ADC_HW_LENGTH     1024
+
+/* Switches */
+#define SWITCH_VAL_SIZE    4
+#define SWITCH_VAL_LSB    19
+#define SWITCH_VAL_MASK    ((1 << SWITCH_VAL_SIZE) - 1)
+#define ATTN_SWITCH_MASK   (SWITCH_VAL_MASK << SWITCH_VAL_LSB)
+
+#define ATTN_NUM(i)  ((ATTN_CHANNELS - i - 1) << ATTN_NUM_LSB)
+
+/* The module name. Used for logging. */
+#define LIBERA_NAME "libera"
+
+
+/* Major and minor numbers for device files */
+/* NOTE: Major numbers in ranges 60-63, 120-127 and 240-254 
+   are reserved for experimental use.
+   For the inclusion in the official linux kernel one has to
+   apply for the assignment of a unique major number. 
+*/
+#define LIBERA_MAJOR      240
+#define LIBERA_MINOR_CFG    0
+#define LIBERA_MINOR_DD     1
+#define LIBERA_MINOR_FA     2
+#define LIBERA_MINOR_PM     3
+#define LIBERA_MINOR_SA     4
+#define LIBERA_MINOR_EVENT  5
+#define LIBERA_MINOR_ADC    6
+#define LIBERA_MINOR_DSC    7
+
+#define LIBERA_MAX_MINOR    7
+
+
+/* Libera CFG device parameters */
+#define LIBERA_CFG_PARAMS_MAX     512
+
+
+/* Libera interrupt cause */
+#define LIBERA_INTERRUPT_ADC_MASK     (1 << 0)
+#define LIBERA_INTERRUPT_SC_MASK      (1 << 1)
+#define LIBERA_INTERRUPT_HELPSC_MASK  (1 << 2)
+#define LIBERA_INTERRUPT_MC_MASK      (1 << 3)
+#define LIBERA_INTERRUPT_HELPMC_MASK  (1 << 4)
+#define LIBERA_INTERRUPT_DD_MASK      (1 << 5)
+#define LIBERA_INTERRUPT_SA_MASK      (1 << 6)
+#define LIBERA_INTERRUPT_FA_MASK      (1 << 7)
+#define LIBERA_INTERRUPT_ILK_MASK     (1 << 8)
+
+/* Libera DD time definition mode */
+enum dd_time_t
+{
+    LIBERA_DD_TIME_IMPLICIT, /* MC & SC defined by external trigger */
+    LIBERA_DD_TIME_EXPLICIT_ST, /* Request given in ST */
+    LIBERA_DD_TIME_EXPLICIT_MT, /* Request given in MT */
+};
+#define NS_IN_SECOND        1000000000UL /* 1e9 nano seconds in 1 second */
+#define LSC_FREQ            125000000UL  /* Libera Machine clock frequency   */
+#define FLMC_DECI_HZ        10
+#define DELTA_LST_OVERFLOW  15707377440ULL
+#define DELTA_LMT_OVERFLOW  14757395240ULL
+
+
+/* Libera DMA */
+typedef struct
+{
+    int chan;
+    libera_atom_dd_t *buf;
+    long put, get;
+    long csize, remaining;
+    unsigned long obFIFOstatus;
+    unsigned long Overrun;
+    unsigned long DMAC_transfer;
+    unsigned long aborting;
+    size_t written;
+} libera_dma_t;
+
+
+/* Libera global parameters */
+struct libera_global
+{
+    libera_U32_t event_mask;
+    int irq;
+    libera_dma_t dma;
+    struct wo_mirror_t wom;
+    unsigned long feature;
+    unsigned long d;
+    unsigned long dfa;
+    unsigned long dcic;
+    unsigned long num_dfir;
+};
+
+
+/*
+ * Device structures for each libera device.
+ * Part of device structure is the same for all devices
+ * (LIBERA_COMMON_DEV) and the rest is specific for each device.
+ */
+
+/* Common items in libera device structures */
+#define LIBERA_COMMON_DEV             \
+    int minor;                        \
+    int open_count;                   \
+    unsigned int writers;             \
+    unsigned int readers;             \
+    struct file *master_filp;         \
+    spinlock_t spinlock;              \
+    struct mutex sem;             \
+    struct libera_global *global;
+
+
+/* Libera CFG device structure */
+struct libera_cfg_device
+{
+    LIBERA_COMMON_DEV
+    unsigned int param[LIBERA_CFG_PARAMS_MAX];
+};
+
+#define TRIG_ALL_MASK 0x1FF << 22  /* 9 bit TRIGGER vector */
+#define TRIG_EVENTS_MAX 11
+#define TRIG_LOG 4096              /* this must be a power of 2 */
+#define TRIG_LOG_MASK (TRIG_LOG - 1)
+#define SA_LOG_MASK (SA_LOG - 1)
+
+
+struct libera_fifo 
+{
+    unsigned long long stamp[TRIG_LOG];
+    long put, get;
+};
+
+
+struct libera_event_fifo 
+{
+    libera_event_t data[TRIG_LOG];
+    long put, get;
+};
+
+struct libera_sa_fifo 
+{
+    libera_atom_sa_t data[SA_LOG];
+    long put, get;
+};
+
+struct libera_circbuf
+{
+    libera_Ltimestamp_t stamp[TRIG_LOG];
+    unsigned int put;
+};
+
+
+#define GLITCH_HISTORY 8
+#define GLITCH_LOG_MASK (GLITCH_HISTORY - 1)
+#define GT_SC_JIFF_LOW   8
+#define GT_SC_JIFF_HIGH 20
+#define GT_MC_JIFF_LOW   8
+#define GT_MC_JIFF_HIGH 20
+#define GT_SC_TRIG10_LOW  10500000
+#define GT_SC_TRIG10_HIGH 12600000
+#define GT_MC_TRIG10_LOW  10500000
+#define GT_MC_TRIG10_HIGH 12500000
+
+typedef struct {
+    unsigned long long stamp;
+    unsigned long th;
+    unsigned long tl;
+    unsigned long jiff_time;
+} glitch_times_t;
+
+typedef struct {
+    glitch_times_t gt[GLITCH_HISTORY];
+    long put;
+} glitch_CB_t;
+
+
+/* Libera DD device structure */
+#define LIBERA_DD_MAX_INTERVAL   DD_MAX_NOATOMS /* Atoms, not bytes. */
+#define LIBERA_DD_CIRCBUF_BYTES  (LIBERA_CIRCBUF_ATOMS*sizeof(libera_atom_dd_t))
+
+/* How much time in advance can we request data, when explictly defining 
+ * the start interval. In atoms = MC cycles. */ 
+#define LIBERA_DD_MAX_INADVANCE  (5*LIBERA_DD_CIRCBUF_ATOMS)
+#define DD_WAIT_STEP             1  /* jiffies */
+#define DD_WAIT_TIMEOUT          2  /* No. of DD_WAIT_STEP cycles */
+#define LIBERA_DD_CIRCBUF_SAFE   ((LIBERA_DD_CIRCBUF_ATOMS * lgbl.d)/10)  /* CB 10% safety margin */
+#define LIBERA_DD_READSYNC_MARGIN 64 /* PUT - GET pointer margin in atoms */
+#define LIBERA_YIELD_INTERVAL     10 /* Yield interval - jiffies */
+
+typedef struct
+{
+    unsigned long dec;
+    libera_Qtimestamp_t Qts;
+    libera_timestamp_t tstamp;
+} libera_dd_local_t;
+
+struct libera_dd_device
+{
+    LIBERA_COMMON_DEV
+    libera_U32_t decimation;
+    wait_queue_head_t DD_queue;
+    struct libera_fifo dd_irqevents;
+    wait_queue_head_t DMA_queue;
+};
+
+/* Libera FA device structure */
+struct libera_fa_device
+{
+    LIBERA_COMMON_DEV
+    unsigned char buf[FAI_BLOCKSIZE];
+};
+
+/* Libera PM device structure */
+struct libera_pm_device
+{
+    LIBERA_COMMON_DEV
+    libera_atom_dd_t *buf;
+    libera_Ltimestamp_t PMevent;
+    libera_timestamp_t tstamp;
+};
+
+
+struct sa_local {
+	struct mutex sem;
+	wait_queue_head_t wait;
+	struct libera_sa_fifo pipe;
+};
+
+struct libera_registered_pipes
+{
+    struct sa_local *sa_pipe[LIBERA_SA_MAX_READERS];
+    int registered;
+    int next;
+};  
+
+struct libera_sa_device
+{
+    LIBERA_COMMON_DEV
+    struct libera_registered_pipes pipe;  
+    libera_atom_sa_t buf[SA_FIFO_DEPTH];    
+    volatile libera_atom_sa_t *buf_head;
+    volatile libera_atom_sa_t *buf_tail;
+    unsigned inputovr;
+};
+
+/* Libera EVENT device structures */
+struct libera_event_local
+{
+    unsigned long sc_trigVec;
+    unsigned long mc_trigVec;
+};
+
+#define LIBERA_SETTIME_ST  (1 << 0)
+#define LIBERA_SETTIME_MT  (1 << 1)
+#define FF_PERIOD             15000 // TODO
+typedef struct {
+    unsigned int update;
+    struct {
+	libera_hw_time_t ref;
+	libera_hw_time_t off;
+        libera_hw_time_t scphi;
+    } lst;
+    struct {
+	libera_hw_time_t ref;
+        libera_hw_time_t off_all;
+	libera_hw_time_t off;
+	libera_hw_time_t off_pll;
+	libera_hw_time_t mcphi;
+    } lmt;
+} libera_settime_t;
+
+typedef struct evgen {
+    libera_hw_time_t time;
+    unsigned long event;
+    struct evgen *prev;
+    struct evgen *next;
+} evgen_t;
+
+
+typedef struct {
+    evgen_t *head;
+} evgen_list_t;
+
+struct libera_event_device
+{
+    LIBERA_COMMON_DEV
+    struct mutex CTIME_sem;
+    wait_queue_head_t SC_queue;
+    wait_queue_head_t MC_queue;
+    wait_queue_head_t EVENT_queue;
+    struct libera_circbuf paired_timestamps[TRIG_EVENTS_MAX];
+    struct libera_fifo sc_timestamps[TRIG_EVENTS_MAX];
+    struct libera_fifo mc_timestamps[TRIG_EVENTS_MAX];
+    struct libera_event_fifo events;
+    unsigned long long sc_time;
+    unsigned long long mc_time;
+    unsigned long sc_trigVec;
+    unsigned long mc_trigVec;
+    glitch_CB_t sc_self_inc;
+    glitch_CB_t mc_self_inc;
+    glitch_CB_t sc_trig10;
+    glitch_CB_t mc_trig10;
+    libera_settime_t settime;
+    libera_hw_time_t HB_start_lmt;
+    libera_hw_time_t HB_offset_lmt;
+    int ValidTrigVector;
+    evgen_t evgen;
+    evgen_list_t list;
+};
+
+/* Libera ADC device structure */
+#define LIBERA_ADC_BUFFER_ATOMS 1024
+struct libera_adc_device
+{
+    LIBERA_COMMON_DEV
+    wait_queue_head_t ADC_queue;
+    atomic_t trig_lock;
+    libera_atom_adc_t buf[LIBERA_ADC_BUFFER_ATOMS];
+    libera_operator_t op;
+};
+
+/* Libera DSC device structure */
+struct libera_dsc_device
+{
+    LIBERA_COMMON_DEV
+    unsigned char buf[DSC_BLOCKSIZE];
+};
+
+
+/* File operations for all the minors */
+extern struct file_operations libera_cfg_fops;   /* minor 0 */
+extern struct file_operations libera_dd_fops;    /* minor 1 */
+extern struct file_operations libera_fa_fops;    /* minor 2 */
+extern struct file_operations libera_pm_fops;    /* minor 3 */
+extern struct file_operations libera_sa_fops;    /* minor 4 */
+extern struct file_operations libera_event_fops; /* minor 5 */
+extern struct file_operations libera_adc_fops;   /* minor 6 */
+extern struct file_operations libera_dsc_fops;   /* minor 7 */
+
+
+/* Prototypes for shared functions & globals */
+#ifdef __NO_VERSION__  // A trick to include these only where needed
+extern unsigned long iobase;
+extern unsigned long flmcdHz;
+extern unsigned long kadc;
+extern unsigned long ilkdur;
+extern unsigned long pmsize;
+
+extern struct libera_cfg_device   libera_cfg;
+extern struct libera_dd_device    libera_dd;
+extern struct libera_fa_device    libera_fa;
+extern struct libera_pm_device    libera_pm;
+extern struct libera_sa_device    libera_sa;
+extern struct libera_event_device libera_event;
+extern struct libera_adc_device   libera_adc;
+extern struct libera_dsc_device   libera_dsc;
+extern struct libera_global lgbl;
+
+extern loff_t
+libera_llseek(struct file *file, loff_t offset, int origin);
+
+extern ssize_t
+libera_read(struct file *file, char *buf, size_t count, loff_t *f_pos);
+
+extern ssize_t
+libera_write(struct file *file, const char *buf, size_t count, loff_t *f_pos);
+
+extern int
+libera_ioctl(struct inode *inode, struct file *file,
+	     unsigned int cmd, unsigned long arg);
+
+extern int 
+libera_send_event(int id, int param);
+
+extern int 
+libera_get_CTIME(libera_Ltimestamp_t* const ctime);
+
+
+/** irqMask get() method. Used for WO mirroring purposes. */
+static inline libera_U32_t 
+get_irqMask(void)
+{
+    return lgbl.wom.sbc.irqMask;
+}
+
+
+/** irqMask set() method. Used for WO mirroring purposes. */
+static inline void 
+set_irqMask(libera_U32_t newMask)
+{
+    lgbl.wom.sbc.irqMask = newMask;
+    writel(newMask, iobase + SBC_IRQ_MASK);
+}
+
+#endif /* __NO_VERSION__ */
+
+
+/* Common public exported inline functions */
+
+/** U32-word block read.
+ *
+ * Reads a block of U32-words into @param buf from @param address.
+ * Since all Libera R/W operations must be 32-bit to ensure proper operation,
+ * @param address must be a multiple of 4. The number of U32-words read from
+ * @param address is @param u32_size. The number of bytes read from
+ * @param address is 4 * @param u32_size.
+ */
+static inline void
+libera_readlBlock(const unsigned long *address, unsigned long *buf, size_t u32_size)
+{
+    register size_t i;
+    
+    for (i=0; i < u32_size; i++)
+	*(buf+i) = readl(address+i);
+}
+
+/** U32-word block write.
+ *
+ * Writes a block of U32-words from @param buf to @param address.
+ * Since all Libera R/W operations must be 32-bit to ensure proper operation,
+ * @param address must be a multiple of 4. The number of U32-words written to
+ * @param address is @param u32_size. The number of bytes written to
+ * @param address is 4 * @param u32_size.
+ */
+static inline void
+libera_writelBlock(const unsigned long *address, unsigned long *buf, size_t u32_size)
+{
+    register size_t i;
+    
+    for (i=0; i < u32_size; i++)
+	writel(*(buf+i), address + i);
+}
+
+
+/** Efficient (non-busy) delay in 10 miliseconds range */
+static inline void
+libera_ms_delay(int delay_ms)
+{
+    int delay_jiff;
+
+    delay_jiff = (delay_ms*HZ)/1000;
+    set_current_state(TASK_INTERRUPTIBLE);
+    schedule_timeout(delay_jiff);
+}
+
+
+/** Efficient (non-busy) interruptible delay in jiffies */
+static inline int
+libera_delay_jiffies_interruptible(int delay_jiff)
+{
+    set_current_state(TASK_INTERRUPTIBLE);
+    /*
+    if (signal_pending(current)) {
+	set_current_state(TASK_RUNNING);
+	return -ERESTARTSYS;
+    }
+    */
+    schedule_timeout(delay_jiff);
+    
+    return 0;
+}
+
+
+/** Efficient (non-busy) uninterruptible delay in jiffies */
+static inline int
+libera_delay_jiffies(int delay_jiff)
+{
+    set_current_state(TASK_INTERRUPTIBLE);
+    schedule_timeout(delay_jiff);
+    
+    return 0;
+}
+
+
+/* Needed in various places through Libera GNU/Linux driver */
+#define MIN(a,b)  ((a) < (b)) ? (a):(b)
+#define XSTR(s) STR(s)
+#define STR(s) #s
+#define ULL(stamp) (unsigned long)(stamp >> 32), (unsigned long)(stamp & (unsigned long long) 0x00000000FFFFFFFFULL)
+#ifndef FALSE
+#  define FALSE 0
+#endif
+#ifndef TRUE
+#  define TRUE  1
+#endif
+
+
+/* Macros to help debugging */
+//#define LIBERA_SYSLOG_LEVEL   KERN_DEBUG
+#define LIBERA_SYSLOG_LEVEL   KERN_CRIT
+#if DEBUG >= 1
+#  define ASSERT(f)  if ((f)) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": Error (file: %s, line: %d)\n",  __FILE__, __LINE__)
+#  define VERIFY(f)  ASSERT(f)
+#  define DEBUG_ONLY(f) f
+#  undef  PDEBUG
+#  define PDEBUG(fmt, args...) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": " fmt,  ## args) 
+#else
+#  define PDEBUG(fmt, args...) ((void)0)
+#  define ASSERT(f)  ((void)0)
+#  define VERIFY(f)  ((void)(0))
+#  define DEBUG_ONLY(f) ((void)0)
+#endif
+
+#if DEBUG >= 2
+#  define DEBUG2_ONLY(f) f
+#  undef  PDEBUG2
+#  define PDEBUG2(fmt, args...) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": " fmt,  ## args) 
+#else
+#  define DEBUG2_ONLY(f) ((void)0)
+#  define PDEBUG2(fmt, args...) ((void)0)
+#endif
+
+#if DEBUG >= 3
+#  define DEBUG3_ONLY(f) f
+#  undef  PDEBUG3
+#  define PDEBUG3(fmt, args...) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": " fmt,  ## args) 
+#else
+#  define DEBUG3_ONLY(f) ((void)0)
+#  define PDEBUG3(fmt, args...) ((void)0)
+#endif
+
+#define LIBERA_LOG(fmt, args...) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": " fmt,  ## args)
+
+
+static inline void
+logged_writel(unsigned long v, unsigned long c, unsigned long iobase)
+{
+    printk(LIBERA_SYSLOG_LEVEL "W(0x%lx) = 0x%lx\n", (c - iobase + 0x14000000), v);
+    __raw_writel(cpu_to_le32(v),__mem_pci(c));
+}
+
+static inline unsigned int
+logged_readl(unsigned long c, unsigned long iobase)
+{
+    unsigned int v = le32_to_cpu(__raw_readl(__mem_pci(c)));
+    printk(LIBERA_SYSLOG_LEVEL "R(0x%lx) = 0x%lx\n", 
+	   (c - iobase + 0x14000000),
+	   (unsigned long)v);
+    return v;
+}
+
+
+
+static inline unsigned long long
+libera_do_div64u (unsigned long long nominator, unsigned long denominator)
+{
+/*
+	This is a wrapper to the kernel do_div function. It returns integral part of 
+	integer number divison between 64 bit and 32 bit number. This wrapper function
+	avoids of side effect of original do_div function
+*/	
+
+
+	unsigned long long dummy_nominator;   // to avoid side effect
+
+
+	if (0==denominator) {
+		printk(KERN_ALERT "!!! Denominator is 0 in function libera_do_div64u !!!\n " );// just inform, do_div handles the rest 
+	}
+	
+	
+
+	dummy_nominator=nominator;
+
+	do_div(dummy_nominator,denominator);
+
+	return dummy_nominator;
+
+	
+}     // end of libera_do_div64u
+
+
+static inline unsigned long 
+libera_do_mod64u (unsigned long long nominator, unsigned long denominator)
+{
+/*
+	This is a wrapper to the kernel do_div function. It returns modulos of 
+	integer number divison between 64 bit and 32 bit number. This wrapper function
+	avoids of side effect of original do_div function
+*/	
+
+
+	unsigned long long dummy_nominator;   // to avoid side effect
+	unsigned long long reminder;
+	unsigned long return_value;
+
+
+
+	if (0==denominator)   printk(KERN_ALERT "!!! Denominator is 0 in function libera_do_mod64u !!!\n " );// just inform, do_div handles the rest 
+
+	dummy_nominator = nominator;
+
+	do_div(dummy_nominator,denominator);
+
+	reminder = nominator-dummy_nominator*denominator;
+	return_value = (unsigned long) reminder;
+
+	if (return_value >= denominator)  printk(KERN_ALERT "Reminder is greater than denominator in funciton libera_do_mod64u\nPerhaps divison by 0? \n " );// just inform  
+	
+	
+	return return_value;
+
+	
+}     // end of libera_do_mod64u
+
+
+
+#if DEBUG >= 4
+#  define DEBUG4_ONLY(f) f
+#  undef  PDEBUG4
+#  define PDEBUG4(fmt, args...) printk( LIBERA_SYSLOG_LEVEL LIBERA_NAME ": " fmt,  ## args)
+#  undef  writel
+#  define writel(v,c)  logged_writel(v,c,iobase)
+#  undef  readl
+#  define readl(c) ({ unsigned int __v = logged_readl(c, iobase); __v; })
+
+#else
+#  define DEBUG4_ONLY(f) ((void)0)
+#  define PDEBUG4(fmt, args...) ((void)0)
+#endif
+
+
+#endif /* __KERNEL__ */
+#endif /* _LIBERA_KERNEL_H_ */
diff --git a/i-tech/driver/include/libera_pipe.h b/i-tech/driver/include/libera_pipe.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a969cfe09b11220c86b219a71fc81230eb03f26
--- /dev/null
+++ b/i-tech/driver/include/libera_pipe.h
@@ -0,0 +1,63 @@
+/* $Id: libera_pipe.h,v 1.4 2006/01/03 10:29:46 ales Exp $ */
+
+//! \file libera_pipe.h 
+//! Libera GNU/Linux driver: Interface to pipes, mostly used in SA
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_PIPE_H_
+#define _LIBERA_PIPE_H_
+
+
+ssize_t
+libera_pipe_read(struct file *filp, char *buf, size_t count, loff_t *ppos);
+
+ssize_t
+libera_pipe_write(struct inode *inode, const char *buf, size_t count);
+
+int
+libera_pipe_release(struct inode *inode, int decr, int decw);
+
+int
+libera_pipe_read_release(struct inode *inode, struct file *filp);
+
+int
+libera_pipe_write_release(struct inode *inode, struct file *filp);
+
+int
+libera_pipe_rdwr_release(struct inode *inode, struct file *filp);
+
+int
+libera_pipe_read_open(struct inode *inode, struct file *filp);
+
+int
+libera_pipe_write_open(struct inode *inode, struct file *filp);
+
+int
+libera_pipe_rdwr_open(struct inode *inode, struct file *filp);
+
+struct inode* 
+libera_pipe_new(struct inode* inode);
+
+
+
+#endif 
diff --git a/i-tech/driver/include/libera_pm.h b/i-tech/driver/include/libera_pm.h
new file mode 100644
index 0000000000000000000000000000000000000000..fcb61ef575de7a32cb7fce03d132750f2fd7ef4f
--- /dev/null
+++ b/i-tech/driver/include/libera_pm.h
@@ -0,0 +1,31 @@
+/* $Id: libera_pm.h,v 1.4 2006/01/03 10:29:46 ales Exp $ */
+
+//! \file libera_pm.h
+//! Libera GNU/Linux driver Post Mortem (PM)device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_PM_H_
+#define _LIBERA_PM_H_
+
+
+#endif /* _LIBERA_PM_H_ */
diff --git a/i-tech/driver/include/libera_sa.h b/i-tech/driver/include/libera_sa.h
new file mode 100644
index 0000000000000000000000000000000000000000..b33335709baf6f1839038c7d961c9ce56431217c
--- /dev/null
+++ b/i-tech/driver/include/libera_sa.h
@@ -0,0 +1,141 @@
+/* $Id: libera_sa.h,v 1.7 2007/05/10 06:53:10 janko Exp $ */
+
+//! \file libera_sa.h
+//! Libera GNU/Linux driver Slow Acquisition (SA) device interface.
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+
+#ifndef _LIBERA_SA_H_
+#define _LIBERA_SA_H_
+
+/*
+ FIFO libera_sa_sa miscellaneous functions
+*/
+
+static inline void flush_saFIFO(struct libera_sa_fifo *q)
+{
+	q->put=q->get=0;
+}
+
+static inline int len_saFIFO(struct libera_sa_fifo *q)
+{
+	return ( (q->put + SA_LOG - q->get) & SA_LOG_MASK );
+}
+
+static inline int not_empty_saFIFO(struct libera_sa_fifo *q)
+{
+	return (q->put != q->get);
+}
+
+static inline int empty_saFIFO(struct libera_sa_fifo *q)
+{
+	return (q->put == q->get);
+}
+
+static inline int free_saFIFO(struct libera_sa_fifo *q)
+{
+	int len;
+	len = len_saFIFO(q);
+	return ( SA_LOG-len); 
+}
+
+static inline int putTo_saFIFO(struct libera_sa_fifo *q, libera_atom_sa_t *data)
+{
+  register int index;
+  if((index=((q->put + 1) & SA_LOG_MASK)) == q->get)
+    {
+      return -1;  /* fifo would overflow */
+    }
+  else
+    {
+      q->data[index] = *data;
+      q->put = index;
+      return 0;
+    }
+}
+
+static inline libera_atom_sa_t* getFrom_saFIFO(struct libera_sa_fifo* const q)
+{
+  if(q->put == q->get)
+    {
+      return NULL; /* fifo empty */
+    }
+  else
+    {
+      q->get = (q->get + 1) & SA_LOG_MASK;
+      return & q->data[q->get];
+    }
+}
+
+static inline  ssize_t libera_pipe_write (struct sa_local *sa_pipe, const char *buf, size_t count)
+{
+	ssize_t ret, written=0;
+	size_t sa_count,i;
+
+
+	/* Null write succeeds */
+	ret=0;
+	if (0==count) goto out;
+
+	/* Filter out non-divisable count values */
+	if (count%sizeof(libera_atom_sa_t)){
+	
+		PDEBUG("SA:libera_pipe_write(): Inappropriate count size. \n");
+		ret=-EINVAL;
+		goto out;
+	}
+
+	
+	sa_count = count/sizeof(libera_atom_sa_t);
+
+
+	/* check if there is enough free space in pipe */
+
+	if (free_saFIFO(&sa_pipe->pipe) < sa_count) {
+		ret=-EFAULT;
+		goto out;
+	}
+	
+
+	/* write must be atomic  */
+	for(i=0;i<sa_count;i++){
+
+		libera_atom_sa_t data;
+
+		memcpy(&data,buf,sizeof(libera_atom_sa_t));
+
+		if (putTo_saFIFO(&sa_pipe->pipe,&data)) {
+			PDEBUG("SA:putTo_saFIFO: fifo would owerflow\n");
+			ret=written;
+			goto out;
+		}
+		
+		written += sizeof(libera_atom_sa_t);	
+		buf +=sizeof(libera_atom_sa_t);
+		ret=written;
+	}	
+
+out:
+	return ret;
+
+}
+#endif /* _LIBERA_SA_H_ */
diff --git a/i-tech/driver/include/llrf.h b/i-tech/driver/include/llrf.h
new file mode 100644
index 0000000000000000000000000000000000000000..a0e6166747210f9f18166caf0737fa160c908397
--- /dev/null
+++ b/i-tech/driver/include/llrf.h
@@ -0,0 +1,98 @@
+/* $Id: llrf.h,v 1.2 2007/10/17 14:06:27 tomazb Exp $ */
+
+/** \file llrf.h */
+/** Public include file for Libera Low Level RF (LLRF). */
+
+/*
+LIBERA - Libera GNU/Linux device driver
+Copyright (C) 2004-2006 Instrumentation Technologies
+
+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
+or visit http://www.gnu.org
+*/
+
+#ifndef _LLRF_H_
+#define _LLRF_H_
+
+/** Libera magic number */
+#define LIBERA_MAGIC 0xad00
+
+
+/** Low lever RF specific CFG parameters. */
+typedef enum {
+    LIBERA_CFG_NONE = LIBERA_CFG_CUSTOM_FIRST, //!< Default.
+} LIBERA_CFG_LLRF_GENERIC;
+
+
+/** Libera Low Level RF sample */
+typedef struct {
+    short chan[4];
+} libera_sample_t;
+
+/* Atom vs. sample vs. longwords & bytes constants */
+#define LIBERA_DD_CIRCBUF_ATOMS  (32*1024*1024) //<! No. of atoms in HB.
+#define LIBERA_DD_MT_SAMPLES           1        //<! No. of samples in 1 MT.
+#define LIBERA_DD_ATOM_MTS             1        //<! No. of MTs in 1 atom.
+#define LIBERA_DD_ATOM_SAMPLES   (LIBERA_DD_ATOM_MTS*LIBERA_DD_MT_SAMPLES) //<! No. of samples in 1 ATOM.
+/** No. of DD atoms in one DMA block */
+#define LIBERA_DMA_BLOCK_ATOMS  512
+/* DMA buffer size = PAGE_SIZE << LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_PAGE_ORDER     5
+/** No. of DD atoms in DMA fifo  - Must be power of 2 and sync
+ *  with LIBERA_DMA_PAGE_ORDER */
+#define LIBERA_DMA_FIFO_ATOMS  16384
+#define LIBERA_DMA_FIFO_MASK (LIBERA_DMA_FIFO_ATOMS - 1)
+/** Maximal No. of samples in read(request) */
+#define LLRF_MAX_SAMPLES   (2*1024*1024)
+
+/** Libera Low Level RF Data on Demand (DD) atom */
+/*  NOTE: The size of libera_atom_dd_t structure is important. 
+ *        The minimal lenght of libera_atom_dd_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    libera_sample_t sample[LIBERA_DD_ATOM_SAMPLES];
+} libera_atom_dd_t;
+
+
+/* Libera LLRF ADC-rate Data (ADC) atom */
+/* NOTE: The size of libera_atom_adc_t structure is important. 
+ *       The minimal lenght of libera_atom_adc_t is 4 bytes and it must be 
+ *       integer (4-byte) aligned!
+ */
+typedef void* libera_atom_adc_t;  // Unused
+
+
+/** Libera Low Level RF Slow Acquisition (SA) atom */
+/*  NOTE: The size of libera_atom_sa_t structure is important. 
+ *        PAGE_SIZE MUST be a multiple of sizeof(libera_atom_sa_t) for proper 
+ *        buffer wrapping. Pad this structure to the nearest common 
+ *        denominator of PAGE_SIZE and sizeof(libera_atom_sa_t).
+ *        The minimal lenght of libera_atom_sa_t is 4 bytes and it must be 
+ *        integer (4-byte) aligned!
+ */
+typedef struct {
+    /* 4 amplitudes */
+    libera_S32_t Va, Vb, Vc, Vd;
+    /* 4 synthetic values -> X, Y, Q & Sum */
+    libera_S32_t X, Y, Q, Sum;
+    /* Cx and Cy for FF */
+    libera_S32_t Cx, Cy;
+    /* 6 values reserved for future use */
+    libera_S32_t reserved[6];
+} libera_atom_sa_t;
+
+
+#endif // _LLRF_H_
diff --git a/i-tech/server/include/bbfp.h b/i-tech/server/include/bbfp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ca2e9c3f906e76ddb55adc5b1307a2f6bd99efb
--- /dev/null
+++ b/i-tech/server/include/bbfp.h
@@ -0,0 +1,53 @@
+// $Id: bbfp.h,v 1.1 2006/03/08 07:58:42 miha Exp $
+
+//! \file bbfp.h
+//! Declares BBFP specific functions and classes.
+
+#if !defined(_SRV_BBFP_H)
+#define _SRV_BBFP_H
+
+#include "cspi.h"
+#include "transform.h"
+
+typedef CSPI_CONPARAMS_DD SUPER_CONPARAMS;
+
+//--------------------------------------------------------------------------
+
+// return sizeof a CSPI_CONPARAMS-derived structure
+inline size_t sizeof_conparams(CSPI_BITMASK flags) {
+
+	return flags & CSPI_CON_STEP ?
+		sizeof(CSPI_CONPARAMS_DD) : sizeof(CSPI_CONPARAMS);
+}
+
+//--------------------------------------------------------------------------
+
+inline SUPER_CONPARAMS& ntoh(SUPER_CONPARAMS& obj)
+{
+	typedef SUPER_CONPARAMS composite_type;
+	typedef uint32_t        base_type;
+
+	return transform<composite_type,base_type>(obj, ntoh);
+}
+
+//--------------------------------------------------------------------------
+
+inline SUPER_CONPARAMS& hton(SUPER_CONPARAMS& obj)
+{
+	typedef SUPER_CONPARAMS composite_type;
+	typedef uint32_t        base_type;
+
+	return transform<composite_type,base_type>(obj, hton);
+}
+
+//--------------------------------------------------------------------------
+
+// return data_traits object for connection hcon
+const basic_traits* mktraits(int mode)
+{
+	ASSERT(CSPI_MODE_DD == mode);
+	static const data_traits<CSPI_DD_RAWATOM, CSPI_DD_RAWATOM> dd_traits;
+	return &dd_traits;
+}
+
+#endif	// _SRV_BBFP_H
diff --git a/i-tech/server/include/client-lib.h b/i-tech/server/include/client-lib.h
new file mode 100644
index 0000000000000000000000000000000000000000..09fa18a7adc679508ad47803f99da464099c0c00
--- /dev/null
+++ b/i-tech/server/include/client-lib.h
@@ -0,0 +1,13 @@
+// $Id: client-lib.h,v 1.12 2006/03/01 10:56:41 miha Exp $
+
+//! \file client-lib.h
+//! Main header file for the CSPI client library.
+
+#if !defined(_CLIENT_LIB_H)
+#define _CLIENT_LIB_H
+
+#include "cspi.h"
+#include "protocol.h"		// SERVER_... request codes
+#include "client-proxy.h"
+
+#endif	// _CLIENT_LIB_H
diff --git a/i-tech/server/include/client-notify.h b/i-tech/server/include/client-notify.h
new file mode 100644
index 0000000000000000000000000000000000000000..773e5e94cff0f432d0f436f311c2d47bd367fbc4
--- /dev/null
+++ b/i-tech/server/include/client-notify.h
@@ -0,0 +1,127 @@
+// $Id: client-notify.h,v 1.3 2006/03/01 10:56:41 miha Exp $
+
+//! \file client-notify.h
+//! Header file for CSPI client library event receive and
+//! dispatch mechanism.
+
+#if !defined(_CLIENT_NOTIFY_H)
+#define _CLIENT_NOTIFY_H
+
+#include <list>
+#include <algorithm>
+#include <functional>
+
+#include "cspi.h"
+#include "lock.h"
+
+// fdw decl
+class subscriber_list;
+
+// declare one and only event subscriber list
+extern subscriber_list _list;
+
+//--------------------------------------------------------------------------
+
+/* Start event thread.
+ * On success, returns 0. On error, returns error code.
+ */
+int multicast_connect( const char *mcast_addr, int mcast_port );
+
+//--------------------------------------------------------------------------
+
+/* Stop event thread.
+ * Call after multicast_connect() to perform cleanup.
+ */
+void multicast_disconnect();
+
+//--------------------------------------------------------------------------
+
+// event subscriber
+class subscriber {
+public:
+	subscriber() : handle(0) {
+		std::memset(&params, 0, sizeof(params));
+	}
+	subscriber(CSPIHCON _handle, const CSPI_CONPARAMS *_params)
+	: handle(_handle) {
+		std::memcpy(&params, _params, sizeof(params));
+	}
+	~subscriber(){}
+
+	CSPIHCON handle;
+	CSPI_CONPARAMS params;
+};
+
+//--------------------------------------------------------------------------
+
+class subscriber_list {
+protected:
+		typedef std::list<subscriber> list_type;
+		
+		list_type list;
+		mutex list_mutex;
+
+public:
+	subscriber_list() {}
+	~subscriber_list() {}
+	
+	// delete all subscribers
+	void clear() {
+		auto_lock<mutex> lock(list_mutex);
+		list.clear();
+	}
+	// find a subscriber
+	subscriber* find(CSPIHCON handle) {
+		auto_lock<mutex> lock(list_mutex);
+		list_type::iterator p;
+		p = std::find_if(list.begin(),
+						 list.end(),
+						 std::bind2nd(equal_to(),handle));
+		return p != list.end() ? &(*p) : 0;
+	}
+	// add new subscriber
+	void subscribe(CSPIHCON handle, CSPI_CONPARAMS *params) {
+		auto_lock<mutex> lock(list_mutex);
+		list.push_back(subscriber(handle, params));
+	}
+	// remove existing subscriber
+	void unsubscribe(CSPIHCON handle) {
+		auto_lock<mutex> lock(list_mutex);
+		list_type::iterator p;
+		p = std::find_if(list.begin(),
+		                 list.end(),
+		                 std::bind2nd(equal_to(),handle));
+		if (p != list.end()) {
+			list.erase(p);
+		}
+	}
+	// dispatch event to all subscribers
+	void dispatch(const CSPI_EVENTHDR& hdr) {
+		auto_lock<mutex> lock(list_mutex);
+		if (!list.empty()) {
+
+			CSPI_EVENT msg;
+			std::memcpy(&msg, &hdr, sizeof(CSPI_EVENTHDR));
+			for (list_type::iterator p=list.begin(); p!=list.end(); ++p) {
+
+				const CSPI_CONPARAMS *q = &p->params;
+				if (hdr.id & q->event_mask) {
+					
+					msg.user_data = q->user_data;
+					if (q->handler && !q->handler(&msg)) break;
+				}
+			}
+		}
+	}
+
+protected:
+	struct equal_to
+	: public std::binary_function<subscriber, CSPIHCON, bool> {
+
+		bool operator() (const subscriber& obj, CSPIHCON handle) const {
+			return obj.handle == handle;
+		}
+	};
+};
+
+#endif	// _CLIENT_NOTIFY_H
diff --git a/i-tech/server/include/client-proxy.h b/i-tech/server/include/client-proxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..257db2a49bd6010052edbfdbb5a1395bacd88eda
--- /dev/null
+++ b/i-tech/server/include/client-proxy.h
@@ -0,0 +1,71 @@
+// $Id: client-proxy.h,v 1.3 2006/03/15 09:04:45 miha Exp $
+
+//! \file client-proxy.h
+//! Header file for the CSPI client library.
+
+#if !defined(_CLIENT_PROXY_H)
+#define _CLIENT_PROXY_H
+
+extern "C"
+{
+#include <netinet/in.h>	// in_port_t
+}
+
+//--------------------------------------------------------------------------
+
+/** Open connection to a Libera server. This is a
+ *  server extension with no real CSPI counterpart.
+ *  Return 0 on success, or -1 if an error occurred.
+ *  The errno is set appropriately.
+ *  If any of the port, mcast_addr or mcast_port is 0, a
+ *  default value is used instead.
+ *  @param addr Server IP address.
+ *  @param port Server port.
+ *  @param mcast_addr Multicast group address to join to.
+ *  @param mcast_port Not implemented (must be 0).
+ */
+int server_connect(const char *addr, in_port_t port,
+                   const char *mcast_addr, in_port_t mcast_port);
+
+/** Closes open connection to Libera server. This is a
+ *  server extension with no real CSPI counterpart.
+ *  Returns 0 on success, or -1 if an error occurred.
+ *  The errno is set appropriately.
+ */
+int server_disconnect();
+
+/** No operation (NOOP). This is a server extension with no
+ *  real CSPI counterpart.
+ *  On success, returns 0. On error, returns -1. The errno
+ *  is set appropriately.
+ */
+int server_noop();
+
+/** Manipulates server-specific parameters. This is a server extension
+ *  with no real CSPI counterpart.
+ *  On success, returns 0. On error, returns < 0:
+ *  -1 (the errno is set appropriately),
+ *  SRV_E_PROTO,
+ *  SRV_E_INVAL.
+ *  @param code Parameter code (request code). See SERVER_PARAMS
+ *              definition for a list of possible values.
+ *  @param val  Untyped pointer to a variable with request code
+ *              specific value. The type of the variable depends on
+ *              the request code:
+ *              ---------------------------------------------------------
+ *              code              | type    | value description
+ *              ---------------------------------------------------------
+ *              SERVER_CACHE_SIZE | integer | cache size in samples
+ *              SERVER_CACHE_LOCK | integer | unlock if 0, lock otherwise
+ *              ---------------------------------------------------------
+ */
+int server_setparam(int code, const void *val);
+
+/** Retrieves server-specific parameter value. This is a server
+ *  extension with no real CSPI counterpart.
+ *  See server_setparam for description of return values and
+ *  function arguments.
+ */
+int server_getparam(int code, void *val);
+
+#endif	// _CLIENT_PROXY_H
diff --git a/i-tech/server/include/debug.h b/i-tech/server/include/debug.h
new file mode 100644
index 0000000000000000000000000000000000000000..62c9947808d9b08e95ff26c34f963e8f42358f71
--- /dev/null
+++ b/i-tech/server/include/debug.h
@@ -0,0 +1,140 @@
+// $Id: debug.h,v 1.2 2006/03/01 10:56:41 miha Exp $
+
+//! \file debug.h
+//! Debugging macros and declarations.
+
+#if !defined(_DEBUG_H)
+#define _DEBUG_H
+
+extern "C"
+{
+#include <syslog.h>
+}
+
+#if defined( DEBUG )
+#include <cassert>
+#endif  // DEBUG
+
+//--------------------------------------------------------------------------
+// Debugging.
+
+#if !defined(DEBUG)
+#define DEBUG 0
+#endif
+
+#if DEBUG	// defined(DEBUG) && DEBUG>0
+
+#define ASSERT(f)		assert(f)
+#define VERIFY(f)		ASSERT(f)
+#define DEBUG_ONLY(f)	(f)
+
+#else	// DEBUG
+
+#define ASSERT(f)		((void)0)
+#define VERIFY(f)		((void)(f))
+#define DEBUG_ONLY(f)	((void)0)
+
+#endif	// !DEBUG
+
+//--------------------------------------------------------------------------
+
+#if DEBUG < 3
+#define DEBUG_ONLY_3(f)	((void)0)
+#else
+#define DEBUG_ONLY_3(f)	(f)
+#endif
+
+#if DEBUG < 2
+#define DEBUG_ONLY_2(f)	((void)0)
+#else
+#define DEBUG_ONLY_2(f)	(f)
+#endif
+
+#if DEBUG < 1
+#define DEBUG_ONLY_1(f)	((void)0)
+#else
+#define DEBUG_ONLY_1(f)	(f)
+#endif
+
+#define DEBUG_ONLY_0(f)	(f)
+
+//--------------------------------------------------------------------------
+
+// The `##' token paste operator has a special meaning when placed between
+// a comma and a variable argument. If you write
+// #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
+// and the variable argument is left out when the eprintf macro is used,
+// then the comma before the `##' will be deleted.
+// This does not happen if you pass an empty argument, nor does it happen
+// if the token preceding `##' is anything other than a comma.
+
+/** Send crtitical message to the system logger. */
+#define _LOG_CRIT( format, ... ) \
+        DEBUG_ONLY_0( syslog( LOG_ERR, format, ##__VA_ARGS__ ) )
+
+/** Send error message to the system logger. */
+#define _LOG_ERR( format, ... ) \
+        DEBUG_ONLY_1( syslog( LOG_ERR, format, ##__VA_ARGS__ ) )
+
+/** Send warning message to the system logger. */
+#define _LOG_WARNING( format, ... ) \
+        DEBUG_ONLY_1( syslog( LOG_WARNING, format, ##__VA_ARGS__ ) )
+
+/** Send normal, but significant message to the system logger. */
+#define _LOG_NOTICE( format, ... ) \
+        DEBUG_ONLY_2( syslog( LOG_NOTICE, format, ##__VA_ARGS__ ) )
+
+/** Send informational message to the system logger. */
+#define _LOG_INFO( format, ... ) \
+        DEBUG_ONLY_2( syslog( LOG_INFO, format, ##__VA_ARGS__ ) )
+
+/** Send debug-level message to the system logger. */
+#define _LOG_DEBUG( format, ... ) \
+        DEBUG_ONLY_3( syslog( LOG_DEBUG, format, ##__VA_ARGS__ ) )
+
+//--------------------------------------------------------------------------
+
+/** Dumps expression to STDERR.
+ *  This macro is only available in DEBUG build.
+ *  Takes a format string as used in the run-time function printf.
+ */
+#define TRACE( f ) DEBUG_ONLY( fprintf( stderr, f ) )
+
+/** Same as TRACE, but takes a format string plus one argument
+ *  (one variable that is dumped to STDERR).
+ */
+#define TRACE1( f, p ) DEBUG_ONLY( fprintf( stderr, f, p ) )
+
+/** Same as TRACE, but takes a format string plus two arguments
+ *  (two variables that are dumped to STDERR).
+ */
+#define TRACE2( f, p, q ) DEBUG_ONLY( fprintf( stderr, f, p, q ) )
+
+/** Same as TRACE, but takes a format string plus three arguments
+ *  (three variables that are dumped to STDERR).
+ */
+#define TRACE3( f, p, q, r ) DEBUG_ONLY( fprintf( stderr, f, p, q, r ) )
+
+//--------------------------------------------------------------------------
+
+#define DUMP_HEADER(h) \
+	"{magic=%u, cmd=%u, status=%d, cmd_val=%u, req_val=%u, data_size=%u}", \
+	h->magic, \
+	h->cmd, \
+	h->status, \
+	h->cmd_val, \
+	h->req_val,\
+	h->data_size
+
+//--------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//...
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// DEBUG_H
diff --git a/i-tech/server/include/ebpp.h b/i-tech/server/include/ebpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7ec3eed18d364c2bd2c5f12640e461733855fdf
--- /dev/null
+++ b/i-tech/server/include/ebpp.h
@@ -0,0 +1,59 @@
+// $Id: ebpp.h,v 1.1 2006/03/01 10:37:48 miha Exp $
+
+//! \file ebpp.h
+//! Declares EBPP specific functions and classes.
+
+#if !defined(_SRV_EBPP_H)
+#define _SRV_EBPP_H
+
+#include "cspi.h"
+#include "transform.h"
+
+typedef CSPI_CONPARAMS_DD SUPER_CONPARAMS;
+
+//--------------------------------------------------------------------------
+
+// return sizeof a CSPI_CONPARAMS-derived structure
+inline size_t sizeof_conparams(CSPI_BITMASK flags) {
+
+	return flags & CSPI_CON_DEC ?
+		sizeof(CSPI_CONPARAMS_DD) : sizeof(CSPI_CONPARAMS);
+}
+
+//--------------------------------------------------------------------------
+
+inline SUPER_CONPARAMS& ntoh(SUPER_CONPARAMS& obj)
+{
+	typedef SUPER_CONPARAMS composite_type;
+	typedef uint32_t        base_type;
+
+	return transform<composite_type,base_type>(obj, ntoh);
+}
+
+//--------------------------------------------------------------------------
+
+inline SUPER_CONPARAMS& hton(SUPER_CONPARAMS& obj)
+{
+	typedef SUPER_CONPARAMS composite_type;
+	typedef uint32_t        base_type;
+
+	return transform<composite_type,base_type>(obj, hton);
+}
+
+//--------------------------------------------------------------------------
+
+// return data_traits object for connection hcon
+const basic_traits* mktraits(int mode)
+{
+	if (CSPI_MODE_ADC == mode) {
+
+		static const data_traits<CSPI_ADC_ATOM, short> adc_traits;
+		return &adc_traits;
+	}
+	ASSERT(CSPI_MODE_DD == mode || CSPI_MODE_PM == mode);
+	
+	static const data_traits<CSPI_DD_ATOM, int> dd_traits;
+	return &dd_traits;
+}
+
+#endif	// _SRV_EBPP_H
diff --git a/i-tech/server/include/error.h b/i-tech/server/include/error.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f17404cb2bed5b68430651ff5c8755fc381cefa
--- /dev/null
+++ b/i-tech/server/include/error.h
@@ -0,0 +1,92 @@
+// $Id: error.h,v 1.9 2006/03/06 14:21:58 miha Exp $
+
+//! \file error.h
+//! Declares error handling functions, classes and debugging macros
+//! common to all application modules.
+
+#if !defined(_ERROR_H)
+#define _ERROR_H
+
+#include <cerrno>
+#include <string>
+#include <exception>
+
+#define SYS_ERROR(what) \
+	sys_error(what, __FILE__, __FUNCTION__, __LINE__)
+
+#define PTHREAD_ERROR(what,retval) \
+	sys_error(what, __FILE__, __FUNCTION__, __LINE__, retval)
+
+#define CSPI_ERROR(what) \
+	cspi_error(what, __FILE__, __FUNCTION__, __LINE__)
+
+//--------------------------------------------------------------------------
+
+// generic server errors start at SRV_E_FIRST to avoid conflicts with CSPI
+enum {
+	SRV_E_FIRST 	= -128,
+	SRV_E_PROTO,	// protocol mismatch
+	SRV_E_INVAL,	// invalid argument
+	SRV_E_LAST
+};
+
+//--------------------------------------------------------------------------
+
+// thrown to force program to terminate
+struct force_exit {
+	explicit force_exit(int val) throw() : status(val) {}
+	~force_exit() throw() {}
+
+	int status;
+};
+
+//--------------------------------------------------------------------------
+
+// thrown to terminate connection
+class protocol_error : public std::exception
+{
+public:
+	protocol_error() throw() {}
+	~protocol_error() throw() {}
+};
+
+//--------------------------------------------------------------------------
+
+// system call error, togehther with location in code
+class sys_error : public std::exception
+{
+public:
+	explicit
+	sys_error(const char *what,
+              const char *file,
+              const char *function,
+              int line,
+              int retval = errno);
+	~sys_error() throw() {}
+
+	virtual const char* what() const throw() { return str.c_str(); }
+
+private:
+	std::string str;
+};
+
+//--------------------------------------------------------------------------
+
+// cspi error, together with location in code
+class cspi_error : public std::exception
+{
+public:
+	explicit
+	cspi_error(int what,
+               const char *file,
+               const char *function,
+               int line);
+	~cspi_error() throw() {}
+
+	virtual const char* what() const throw() { return str.c_str(); }
+
+private:
+	std::string str;
+};
+
+#endif	// _ERROR_H
diff --git a/i-tech/server/include/fdstream.h b/i-tech/server/include/fdstream.h
new file mode 100644
index 0000000000000000000000000000000000000000..6885a6dc6693c081289c3167130fed095306225d
--- /dev/null
+++ b/i-tech/server/include/fdstream.h
@@ -0,0 +1,178 @@
+// $Id: fdstream.h,v 1.1 2006/03/01 10:37:48 miha Exp $
+
+//! \file fdstream.h
+//! file descriptor streambuf
+
+#if !defined(_FDSTREAM_H)
+#define _FDSTREAM_H
+
+extern "C"
+{
+#include <unistd.h>
+}
+#include <istream>
+#include <streambuf>
+
+//--------------------------------------------------------------------------
+
+/* fdbuf and fdiostream based on work from Nicolai M. Josuttis
+ *
+ * (C) Copyright Nicolai M. Josuttis 2001.
+ * Permission to copy, use, modify, sell and distribute this software
+ * is granted provided this copyright notice appears in all copies.
+ * This software is provided "as is" without express or implied
+ * warranty, and with no claim as to its suitability for any purpose.
+ */
+
+// ReadFuncType provides operator() with the same iface as ::read
+// WriteFuncType provides operator() with the same iface as ::write
+
+// input/output stream buffer class initialized with a file descriptor
+template <typename ReadFuncType, typename WriteFuncType>
+class fdbuf : public std::streambuf
+{
+protected:
+	int fd;	// file descriptor
+
+	/* data buffer:
+	 * - at most, pbSize characters in putback area plus
+	 * - at most, bufSize characters in ordinary read buffer
+	 */
+	static const int pbSize = 4;    // size of putback area
+	const int bufSize;              // size of the data buffer
+	char *buffer;                   // data buffer
+
+	ReadFuncType read_func;
+	WriteFuncType write_func;
+
+public:
+	/* constructor
+	 * - initialize file descriptor
+	 * - initialize empty data buffer
+	 * - no putback area
+	 * => force underflow()
+	 */
+	explicit fdbuf(int _fd, int size=BUFSIZ) : fd(_fd), bufSize(size) {
+
+		buffer = new char [bufSize+pbSize];
+		setg (buffer+pbSize,     // beginning of putback area
+		      buffer+pbSize,     // read position
+		      buffer+pbSize);    // end position
+	}
+	~fdbuf() {
+		delete[] buffer;
+	}
+	// return associated file descriptor
+	int descriptor() const { return this->fd; }
+
+protected:
+	// write one character
+	virtual int_type overflow(int_type c) {
+		if (c != EOF) {
+			const char z(c);
+			if (write_func(fd, &z, 1) != 1) {
+				return EOF;
+			}
+		}
+		return c;
+	}
+
+	// write multiple characters
+	virtual std::streamsize xsputn(const char *s, std::streamsize num) {
+		return write_func(fd, s, num);
+	}
+
+	// read characters into buffer, return one character
+    virtual int_type underflow () {
+		using std::memcpy;
+
+		// is read position before end of buffer?
+		if (gptr() < egptr()) {
+			return traits_type::to_int_type(*gptr());
+		}
+
+		/* process size of putback area
+		 * - use number of characters read
+		 * - but at most size of putback area
+		 */
+		int numPutback = gptr() - eback();
+		if (numPutback > pbSize) {
+			numPutback = pbSize;
+		}
+
+		/* copy up to pbSize characters previously read into
+		 * the putback area
+		 */
+		memcpy(buffer+(pbSize-numPutback), gptr()-numPutback,
+		       numPutback);
+
+		// read at most bufSize new characters
+		const int num = read_func(fd, buffer+pbSize, bufSize);
+		if (num <= 0) {
+			// ERROR or EOF
+			return EOF;
+		}
+
+		// reset buffer pointers
+		setg (buffer+(pbSize-numPutback),    // beginning of putback area
+				buffer+pbSize,               // read position
+				buffer+pbSize+num);          // end of buffer
+
+		// return next character
+		return traits_type::to_int_type(*gptr());
+    }
+};
+
+//--------------------------------------------------------------------------
+
+template <typename ReadFuncType, typename WriteFuncType>
+class fdiostream : public std::iostream
+{
+public:
+	typedef fdbuf<ReadFuncType, WriteFuncType> streambuf_type;
+
+protected:
+	streambuf_type buf;
+
+public:
+	explicit fdiostream(int fd) : std::iostream(0), buf(fd) {
+		rdbuf(&buf);
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// stream buffer class initialized with a UDP socket descriptor
+template <typename ReadFuncType, typename WriteFuncType>
+class udpbuf : public fdbuf<ReadFuncType,WriteFuncType>
+{
+public:
+	explicit udpbuf(int _fd, int size=BUFSIZ)
+	: fdbuf<ReadFuncType,WriteFuncType>(_fd, size)
+	{}
+	~udpbuf() {}
+
+	// return this on success, 0 otherwise
+	udpbuf* attach(int _fd) {
+		if (is_open()) return 0;
+		this->fd = _fd;
+		return this;
+	}
+	// return this
+	udpbuf* detach() {
+		this->fd = -1;
+		return this;
+	}
+	bool is_open() const { return -1 != this->fd; }
+
+	// return pointer to read functor
+	ReadFuncType* reader() {
+		return &this->read_func;
+	}
+	// return pointer to write functor
+	WriteFuncType* writer() {
+		return &this->write_func;
+	}
+};
+
+#endif	// _FDSTREAM_H
diff --git a/i-tech/server/include/handle.h b/i-tech/server/include/handle.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f6de9d43c09399f87900c612826bb889339c154
--- /dev/null
+++ b/i-tech/server/include/handle.h
@@ -0,0 +1,89 @@
+// $Id: handle.h,v 1.1 2006/03/01 10:37:48 miha Exp $
+
+//! \file handle.h
+//! Simple CSPI handle wrappers.
+
+#if !defined(_HANDLE_H)
+#define _HANDLE_H
+
+#include "cspi.h"
+#include "error.h"
+
+// represents cspi handle
+template <typename cspiH>
+struct cspi_handle
+{
+	explicit cspi_handle(cspiH h=0) : handle(h) {}
+	virtual ~cspi_handle() {}
+
+	operator cspiH() { return handle; }
+	cspiH handle;
+
+	private:
+		cspi_handle(cspi_handle<cspiH>&) {}
+};
+
+//--------------------------------------------------------------------------
+
+// represents cspi environment handle
+struct cspihenv : public cspi_handle<CSPIHENV>
+{
+	// uses "construction is initialization" pattern
+	explicit cspihenv(bool as_su=0) : cspi_handle<CSPIHENV>() {
+
+		CSPI_LIBPARAMS lib = {1,1};
+		if (as_su) cspi_setlibparam(&lib, CSPI_LIB_SUPERUSER);
+	
+		int rc = cspi_allochandle(CSPI_HANDLE_ENV, 0, &handle);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	};
+
+	~cspihenv() {
+
+		int rc = cspi_freehandle(CSPI_HANDLE_ENV, handle);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// represents cspi connection handle
+struct cspihcon : public cspi_handle<CSPIHCON>
+{
+	// uses "construction is initialization" pattern
+	explicit cspihcon(CSPIHENV henv) : cspi_handle<CSPIHCON>() {
+
+		int rc = cspi_allochandle(CSPI_HANDLE_CON, henv, &handle);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	};
+
+	~cspihcon() {
+
+		int rc = cspi_freehandle(CSPI_HANDLE_CON, handle);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	}
+};
+
+//--------------------------------------------------------------------------
+
+struct auto_connect
+{
+	explicit auto_connect(CSPIHCON handle, CSPI_MODE mode) : hcon(handle) {
+		CSPI_CONPARAMS p;
+		p.mode = mode;
+
+		int rc = cspi_setconparam(hcon, &p, CSPI_CON_MODE);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+
+		rc = cspi_connect(hcon);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	}
+	~auto_connect() {
+		int rc = cspi_disconnect(hcon);
+		if (CSPI_OK != rc) throw CSPI_ERROR(rc);
+	}
+protected:
+	CSPIHCON hcon;
+};
+
+#endif	// _HANDLE_H
diff --git a/i-tech/server/include/lock.h b/i-tech/server/include/lock.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2960505828e425152113cc4ee71ccb6b57de57b
--- /dev/null
+++ b/i-tech/server/include/lock.h
@@ -0,0 +1,70 @@
+// $Id: lock.h,v 1.1 2006/03/01 10:37:48 miha Exp $
+
+//! \file lock.h
+//! Simple sync. and locking wrappers.
+
+#if !defined(_LOCK_H)
+#define _LOCK_H
+
+extern "C" 
+{
+#include <pthread.h>
+}
+#include "debug.h"
+
+template <class T>
+struct auto_lock
+{
+	explicit auto_lock(T& obj) : sync(obj) {
+		VERIFY(0 == sync.lock());
+	}
+	~auto_lock() {
+		VERIFY(0 == sync.unlock());
+	}
+
+	private:
+		T& sync;
+};
+
+//--------------------------------------------------------------------------
+
+struct mutex
+{
+	mutex() { pthread_mutex_init(&m, 0); }
+	~mutex() { VERIFY(0 == pthread_mutex_destroy(&m)); }
+
+	int lock() { return pthread_mutex_lock(&m); }
+	int unlock() { return pthread_mutex_unlock(&m); }
+
+	// allow passing *this instead of pthread_mutex_t*
+	operator pthread_mutex_t* () { return &m; }
+
+	private:
+		pthread_mutex_t m;
+};
+
+//--------------------------------------------------------------------------
+
+struct cond
+{
+	explicit cond(pthread_mutex_t *p = 0) : m(p) {
+		pthread_cond_init(&c, 0);
+	}
+	~cond() { VERIFY(0 == pthread_cond_destroy(&c)); }
+
+	// mutex must be locked by the caller
+	int lock() { return pthread_cond_wait(&c, m); }
+	int unlock() { return 0; }
+
+	// allow passing *this instead of pthread_cond_t*
+	operator pthread_cond_t* () { return &c; }
+
+	int signal() { return pthread_cond_signal(&c); }
+	int broadcast() { return pthread_cond_broadcast(&c); }
+
+	private:
+		pthread_cond_t c;
+		pthread_mutex_t *m;
+};
+
+#endif	// _LOCK_H
diff --git a/i-tech/server/include/protocol.h b/i-tech/server/include/protocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..13c96627befac60ff77587add81e993ba1387e79
--- /dev/null
+++ b/i-tech/server/include/protocol.h
@@ -0,0 +1,138 @@
+// $Id: protocol.h,v 1.13 2006/03/02 10:04:32 miha Exp $
+
+//! \file protocol.h
+//! Header file for Libera Server protocol.
+
+#if !defined(_PROTOCOL_H)
+#define _PROTOCOL_H
+
+extern "C" {
+#include <stdint.h>	// uint16_t, uint32_t, ...
+}
+#include "cspi.h"
+
+namespace protocol
+{
+	// server magic numbers
+	enum {
+		MAGIC = 23799,
+	};
+
+	/* List of CSPI and server messages.
+	 * CSPI messages: LM_CSPI_FIRST ... LM_CSPI_LAST
+	 * Server messages: LM_SERVER_FIRST ... LM_SERVER_LAST
+	 */
+	enum {
+		LM_FIRST = -1,
+		LM_CSPI_FIRST = LM_FIRST,
+
+		LM_GETLIBPARAM,
+		LM_SETLIBPARAM,
+
+		LM_ALLOCHANDLE,
+		LM_FREEHANDLE,
+
+		LM_GETENVPARAM,
+		LM_SETENVPARAM,
+
+		LM_GETENVPARAM_FA,
+		LM_SETENVPARAM_FA,
+
+		LM_GETCONPARAM,
+		LM_SETCONPARAM,
+
+		LM_CONNECT,
+		LM_DISCONNECT,
+
+		LM_SEEK,
+		LM_READ,
+		LM_READ_EX,
+		LM_GETTIMESTAMP,
+
+		LM_GET,
+
+		LM_SETTIME,
+
+		LM_CSPI_LAST,
+		/* -------------------------------- */
+		LM_SERVER_FIRST = LM_CSPI_LAST,
+
+		LM_SERVER_NOOP,
+		LM_SERVER_SETPARAM,
+		LM_SERVER_GETPARAM,
+
+		LM_SERVER_LAST,
+		LM_LAST = LM_SERVER_LAST
+	};
+
+	// list of available request codes to accompany a
+	//  LM_SERVER_SET/GETPARAM message.
+	typedef enum {
+		// data-on-demand cache size
+		SERVER_CACHE_SIZE = 1,
+		// lock (freeze) or unlock the cache
+		SERVER_CACHE_LOCK,
+	}
+	SERVER_PARAMS;
+
+	// list of server specific async. events
+	// (struct CSPI_EVENTHDR's 'id' member variable)
+	typedef enum {
+		// data-on-demand not cached error
+		SERVER_EVENT_NOCACHE = CSPI_EVENT_USER,
+	}
+	SERVER_EVENTMASK;
+
+	// message header
+	struct header {
+
+		// magic number
+		uint16_t magic;
+		// CSPI command
+		uint16_t cmd;
+		// request or reply status
+		uint8_t  status;
+		// command-specific value
+		int32_t cmd_val;
+		/* Request-specific value Not interpreted by the server
+		 * and included as-is in the reply.
+		 */
+		int32_t req_val;
+		// The size of the trailing data block in bytes.
+		uint32_t data_size;
+	};
+
+	/* Generic server message.
+	 * A message is composed of a fixed-size header, describing
+	 * the request (or reply), and an optional variable-size 
+	 * binary data stream.
+	 */
+	struct message {
+		struct header hdr;
+		// optional data associated with message
+		u_int8_t data[1];
+	};
+
+	// return 1 if id represents a valid message, 0 otherwise
+	inline bool is_valid_message(int id) {
+		return LM_FIRST < id && id < LM_LAST;
+	}
+
+	// return 1 if id represents a valid CSPI message, 0 otherwise
+	inline bool is_valid_cspi_message(int id) {
+		return LM_CSPI_FIRST < id && id < LM_CSPI_LAST;
+	}
+
+	// returns 1 if id represents a valid server message, 0 otherwise
+	inline bool is_valid_server_message(int id) {
+		return LM_SERVER_FIRST < id && id < LM_SERVER_LAST;
+	}
+
+	// validate message header; returns 1 on success, 0 otherwise
+	inline bool is_valid_header(const header *h) {
+		return (MAGIC == h->magic) && is_valid_message(h->cmd);
+	}
+
+};	// namespace protocol
+
+#endif	// _PROTOCOL_H
diff --git a/i-tech/server/include/server-conf.h b/i-tech/server/include/server-conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d751c532e48417bb7c313939bb4f59d6e6fdffc
--- /dev/null
+++ b/i-tech/server/include/server-conf.h
@@ -0,0 +1,36 @@
+// $Id: server-conf.h,v 1.1 2006/03/01 10:37:48 miha Exp $
+
+//! \file server-conf.h
+//! Default server configuration.
+
+#if !defined(_SERVER_CONF_H)
+#define _SERVER_CONF_H
+
+// uncomment to run as a daemon
+//#define DAEMON
+
+// default TCP port to listen on
+#define SERVER_DEFAULT_PORT 23271
+
+// default multicast group address to send events to
+#define SERVER_DEFAULT_MCAST_ADDR "224.0.1.240"
+
+// default multicast TTL (1 = local subnet)
+#define SERVER_DEFAULT_MCAST_TTL 1
+
+// PID file pathname.
+#define SERVER_PID_FILE "/var/run/liberad.pid"
+
+// max. number of pending connections.
+#define SERVER_MAX_BACKLOG 8
+
+// idle connection timeout in seconds
+#define SERVER_CONN_TIMEOUT 30
+
+// max. data block size in a message in bytes
+#define SERVER_MAX_DATABLOCK (250000*32)
+
+// max. size of data-on-demand cache in samples(!)
+#define SERVER_MAX_CACHESIZE 16384
+
+#endif	// _SERVER_CONF_H
diff --git a/i-tech/server/include/server-main.h b/i-tech/server/include/server-main.h
new file mode 100644
index 0000000000000000000000000000000000000000..1277193875d751f3959fa6cb67f4f5d096af222a
--- /dev/null
+++ b/i-tech/server/include/server-main.h
@@ -0,0 +1,33 @@
+// $Id: server-main.h,v 1.6 2006/03/01 10:56:41 miha Exp $
+
+//! \file server-main.h
+//! Main header file for the Libera Server.
+
+#if !defined(_SERVER_MAIN_H)
+#define _SERVER_MAIN_H
+
+#include "server-conf.h"
+
+// worker thread serving an active aconnection
+void* worker_thread(void*);
+
+//--------------------------------------------------------------------------
+
+// program configuration, initialized from command-line
+struct config
+{
+	config() :
+		port(SERVER_DEFAULT_PORT),
+		mcast_addr(SERVER_DEFAULT_MCAST_ADDR),
+		mcast_ttl(SERVER_DEFAULT_MCAST_TTL)
+		{}
+
+	// server port to listen to
+	in_port_t port;
+	// multicast group address to send events to
+	std::string mcast_addr;
+	// multicast TTL
+	u_char mcast_ttl;
+};
+
+#endif	// _SERVER_MAIN_H
diff --git a/i-tech/server/include/server-model.h b/i-tech/server/include/server-model.h
new file mode 100644
index 0000000000000000000000000000000000000000..169b145a9e465644049bb6552b899731648f41eb
--- /dev/null
+++ b/i-tech/server/include/server-model.h
@@ -0,0 +1,241 @@
+// $Id: server-model.h,v 1.5 2006/06/12 07:24:17 miha Exp $
+
+//! \file server-model.h
+//! Header file for multithreaded server model with one thread per client.
+
+#if !defined(_SERVER_MODEL_H)
+#define _SERVER_MODEL_H
+
+#include <stdexcept>
+#include <vector>
+
+#include "debug.h"
+#include "error.h"
+#include "lock.h"
+#include "util.h"
+#include "server-proxy.h"
+#include "server-main.h"
+
+// fwd decls
+class worker_counter;
+class pipe_of_death;
+class event_transmitter;
+class cache_iface;
+
+// main pid
+extern pid_t _process_id;
+
+// declare one and only worker counter
+extern worker_counter _workers;
+
+// declare one and only pipe_of_death
+extern pipe_of_death _pipe;
+
+// declare one and only multicaster
+extern event_transmitter _multicast;
+
+// declare one and only data-on-demand cache
+extern cache_iface _cache;
+
+//--------------------------------------------------------------------------
+
+// worker counter
+class worker_counter {
+public:
+	worker_counter() : blocked(false), count(0) {}
+	~worker_counter() {}
+
+	// bump up worker count
+	size_t operator++ () {
+
+		auto_lock<mutex> lock(list_mutex);
+		if (blocked) throw std::runtime_error("operation canceled");
+		return ++count;
+	}
+	// decrement worker count
+	size_t operator-- () {
+
+		auto_lock<mutex> lock(list_mutex);
+		return --count;
+	}
+	// block counter increments, return count
+	int block() {
+
+		auto_lock<mutex> lock(list_mutex);
+		blocked = true;
+		return count;
+	}
+
+private:
+	bool blocked;	// is blocked?
+	size_t count;
+	mutex list_mutex;
+};
+
+//--------------------------------------------------------------------------
+
+class server
+{
+public:
+	explicit server(const config& cfg);
+	~server() {
+		_workers.block();
+		// Worker threads are running in the detached state.
+		// We need not wait for them to terminate.
+	}
+
+	// wait for new connection request or shutdown
+	int wait() const {
+		return wait_input(fd);	// delegate
+	}
+	// accept connection, return socket descriptor
+	int accept() const;
+
+	// create new worker thread for socket descriptor connfd
+	void new_worker(int connfd) const;
+
+private:
+	int fd;	// descriptor (communication endpoint) to listen to
+
+	// following shortens all typecasts of pointer arguments
+	typedef struct sockaddr SA;
+};
+
+//--------------------------------------------------------------------------
+
+// group together event daemon related ops
+struct eventd
+{
+	// subscribe this process to events
+	static bool subscribe() {
+		/* TODO: All bits in the event mask are set to 1.
+		* This should be replaced with an aggregate mask
+		* for all active connections.
+		*/
+		return request(0xFFFF);
+	}
+	// unsubscribe this process, previously registered with subscibe()
+	static bool unsubscribe(){
+		return request(0x0000);
+	}
+private:
+	// send request to eventd
+	// return true on success, false on sys error
+	static bool request(size_t mask);
+};
+
+//--------------------------------------------------------------------------
+
+class message;	// fwd decl
+class worker
+{
+public:
+	worker() { ++_workers; }
+	~worker() {
+		if (0 == --_workers) eventd::unsubscribe();
+	}
+
+	message& dispatch(message& msg);
+
+private:
+	proxy_ex proxy;
+};
+
+//--------------------------------------------------------------------------
+
+// data-on-demand cache
+class data_cache
+{
+public:
+	data_cache() : buf(0), state(unlockbit) {
+		reset();
+	}
+	~data_cache() {}
+
+	// cache states
+	enum { unlockbit=0x0, lockbit=0x1 };
+	// get cache state
+	size_t rdstate() const { return state; }
+	// set cache state, return old state
+	size_t setstate(size_t st) {
+		size_t tmp(state); state=st; return tmp;
+	}
+
+	const void* data() const { return &buf[0]; }
+	void* data() { return &buf[0]; }
+
+	// resize cache to accommodate size samples
+	void resize(size_t size) {
+		buf.resize(size);
+		reset();
+	}
+	// return cache size in samples
+	size_t size() const { return buf.size(); }
+	// return true if cache empty
+	size_t empty() const { return buf.empty(); }
+
+	// reset timestamp and state
+	void reset() {
+		std::memset(&stamp, 0, sizeof(stamp));
+		setstate(unlockbit);
+	}
+	CSPI_TIMESTAMP* timestamp() { return &stamp; }
+
+	typedef CSPI_DD_RAWATOM element_type;
+
+protected:
+	std::vector<element_type> buf;
+	// state bits
+	size_t state;
+	// cache timestamp
+	CSPI_TIMESTAMP stamp;
+};
+
+//--------------------------------------------------------------------------
+
+// implements thread-safe interface to data-on-demand cache
+struct cache_iface
+{
+	cache_iface() {}
+	~cache_iface() {}
+
+	// resize to accommodate count samples, return cache size
+	size_t resize(size_t count);
+	// return cache size
+	size_t size() {
+		auto_lock<mutex> lock(cache_mutex);
+		return cache.size();
+	}
+	// return true if cache empty
+	bool empty() {
+		auto_lock<mutex> lock(cache_mutex);
+		return cache.empty();
+	}
+	// fill cache with data acquired on a trigger
+	void fill();
+	// get timestamp, return 0 if not avail.
+	CSPI_TIMESTAMP* timestamp(CSPI_TIMESTAMP *ts) {
+
+		auto_lock<mutex> lock(cache_mutex);
+		if (!cache.empty()) {
+
+			return (CSPI_TIMESTAMP *)
+			       std::memcpy(ts, cache.timestamp(), sizeof(*ts));
+		}
+		return 0;	// cache disabled
+	}
+	// copy up to count samples to dest, return num. of samples copied
+	size_t copy(data_cache::element_type *dest, size_t count);
+
+	void lock(bool enable);
+	bool locked() {
+		auto_lock<mutex> lock(cache_mutex);
+		return cache.rdstate() & data_cache::lockbit;
+	}
+
+protected:
+	data_cache cache;
+	mutex cache_mutex;
+};
+
+#endif	// _SERVER_MODEL_H
diff --git a/i-tech/server/include/server-proxy.h b/i-tech/server/include/server-proxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e8a9486d7f7d2ec56bc3f4e5433d459703d8e6f
--- /dev/null
+++ b/i-tech/server/include/server-proxy.h
@@ -0,0 +1,185 @@
+// $Id: server-proxy.h,v 1.15 2006/05/16 06:50:55 miha Exp $
+
+//! \file server-proxy.h
+//! Header file for CSPI proxy.
+
+#if !defined(_SERVER_PROXY_H)
+#define _SERVER_PROXY_H
+
+#include <list>
+
+#include "cspi.h"
+#include "protocol.h"
+
+// fwd decl
+class message;
+
+//--------------------------------------------------------------------------
+
+struct handle_adapter {
+	explicit handle_adapter(CSPIHANDLE h=0, int t=0) : handle(h), type(t) {}
+	~handle_adapter() {}
+
+	operator CSPIHANDLE() { return handle; }
+	int destroy() {
+
+		int rc;
+		if (CSPI_HANDLE_ENV == type) {
+	
+			rc = cspi_freehandle(CSPI_HANDLE_ENV, handle);
+		}
+		else {
+			ASSERT(CSPI_HANDLE_CON == type);
+			cspi_disconnect(handle);
+			rc = cspi_freehandle(CSPI_HANDLE_CON, handle);
+		}
+		ASSERT(CSPI_OK == rc);
+		return rc;
+	}
+
+protected:
+	CSPIHANDLE handle;
+	int type;
+};
+
+//--------------------------------------------------------------------------
+
+inline handle_adapter mkadapter(int type, CSPIHANDLE handle)
+{
+	ASSERT(CSPI_HANDLE_ENV == type || CSPI_HANDLE_CON == type);
+	return handle_adapter(handle, type);
+}
+
+//--------------------------------------------------------------------------
+
+// CSPI proxy class
+class proxy
+{
+public:
+	proxy() {}
+	// dtor; free CSPI resources not released by the user
+	virtual ~proxy();
+
+	// delegate to marshall(msg)
+	int operator() (message& msg) { return marshall(msg); }
+
+protected:
+	/* A pointer to the marshalling member function taking
+	 * a message and returning an integer (return code).
+	 */
+	typedef int (proxy::*marshalling_f)(message&);
+
+	// map Libera messages to marshalling functions
+	static marshalling_f table[];
+
+	/* Top marshalling function. Calls a CSPI marshalling function.
+	 * Returns a value returned by the CSPI call.
+	 */
+	virtual int marshall(message& msg) {
+
+		// NOTE: assume no check is needed on message header
+		const protocol::header *hdr = msg.header();
+
+		// lookup marshalling function
+		marshalling_f f = table[hdr->cmd];
+		// call function on this object
+		return (this->*f)(msg);
+	}
+
+private:
+
+	// shortens declarations in code
+	typedef std::list<handle_adapter> handle_list;
+	// keep track of CSPI resources used by this object
+	handle_list handles;
+
+protected:
+	/* Following are marshalling functions to delegate calls to the
+	 * CSPI layer. A function deserializes call arguments from the
+	 * message, calls CSPI function, then serializes the results back
+	 * into the message.
+	 *
+	 * The data_size field of the message header is assigned the size
+	 * of trailing data block in bytes. Returns a value returned by
+	 * the CSPI call. Can throw a protocol_error or bad_alloc error.
+	 *
+	 * NOTE: the function should be passed message HEADER in host
+	 *  byte order. Data block, on the other hand, is specific to
+	 *  each message and should be left as-is, that is in network
+	 *  byte order.
+	 */
+	int allochandle(message& msg);
+	int freehandle(message& msg);
+	int getlibparam(message& msg);
+	int setlibparam(message& msg);
+	int getenvparam(message& msg);
+	int setenvparam(message& msg);
+	int getenvparam_fa(message& msg);
+	int setenvparam_fa(message& msg);
+	int getconparam(message& msg);
+	int setconparam(message& msg);
+	int connect(message& msg);
+	int disconnect(message& msg);
+	int seek(message& msg);
+	int read(message& msg);
+	int read_ex(message& msg);
+	int gettimestamp(message& msg);
+	int get(message& msg);
+	int settime(message& msg);
+};
+
+//--------------------------------------------------------------------------
+
+/* Extends proxy class to handle server-specific functions in
+ * addition to the CSPI functions.
+ */
+class proxy_ex : public proxy
+{
+public:
+	proxy_ex() : proxy() {}
+	~proxy_ex() {}
+
+protected:
+	/* A pointer to the marshalling member function taking
+	 * a message and returning an integer (return code).
+	 */
+	typedef int (proxy_ex::*marshalling_f)( message& );
+
+	// map Libera messages to server-specific marshalling functions
+	static marshalling_f table_ex[];
+
+	/* Overload base class marshalling function to handle
+	 * server-specific messages. For CSPI messages, call
+	 * base version instead. For server-specific messages,
+	 * invokes the appropriate marshalling code.
+	 */
+	int marshall(message& msg) {
+
+		// NOTE: assume no check is needed on message header
+		const protocol::header *hdr = msg.header();
+		if (protocol::is_valid_cspi_message(hdr->cmd)) {
+			// delegate to base class
+			return proxy::marshall(msg);
+		}
+		ASSERT(protocol::is_valid_server_message(hdr->cmd));
+		_LOG_DEBUG("received server-specific message %u", hdr->cmd);
+
+		// interpret as a server-specific message
+		const size_t idx = hdr->cmd - protocol::LM_SERVER_FIRST - 1;
+
+		// look up marshalling function
+		marshalling_f f = table_ex[idx];
+		// call function on this object
+		return (this->*f)(msg);
+	}
+
+protected:
+	/* A marshalling function for the NOOP (no operation) call.
+	 * Always returns 0.
+	 */
+	int server_noop(message& msg);
+	int server_setparam(message& msg);
+	int server_getparam(message& msg);
+};
+
+#endif	// _SERVER_PROXY_H
diff --git a/i-tech/server/include/socket-io.h b/i-tech/server/include/socket-io.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b22a64d113b7e47aa58e67f4ae2c1d7f9f346f6
--- /dev/null
+++ b/i-tech/server/include/socket-io.h
@@ -0,0 +1,25 @@
+// $Id: socket-io.h,v 1.4 2006/03/01 10:56:41 miha Exp $
+
+//! \file socket-io.h
+//! Declares functions to read or write to a socket stream.
+
+#if !defined(_SOCKET_IO_H)
+#define _SOCKET_IO_H
+
+/* Read n bytes from a socket stream.
+ * On success, returns the number of bytes read. On error,
+ * -1 is returned, and errno is set appropriately.
+ * Used to read from a stream socket (a TCP socket). See A. Stevens'
+ * UNIX Network Programming (section 3.9) for more information.
+ */
+ssize_t readn( int fd, void *vptr, size_t n );
+
+/* Write n bytes to a socket stream.
+ * On success, returns the number of bytes written. On error,
+ * -1 is returned, and errno is set appropriately.
+ * Used to write to a stream socket (a TCP socket). See A. Stevens'
+ * UNIX Network Programming (section 3.9) for more information.
+ */
+ssize_t writen( int fd, const void *vptr, size_t n );
+
+#endif	// _SOCKET_IO_H
diff --git a/i-tech/server/include/transform.h b/i-tech/server/include/transform.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8696f8ed849ee25698af3be0b7b76c4c32829b0
--- /dev/null
+++ b/i-tech/server/include/transform.h
@@ -0,0 +1,273 @@
+// $Id: transform.h,v 1.3 2006/12/18 08:23:27 ales Exp $
+
+//! \file transform.h
+//! Functions and classes to convert between host and network byte order.
+
+#if !defined(_TRANSFORM_H)
+#define _TRANSFORM_H
+
+extern "C"
+{
+#include <netinet/in.h>
+}
+#include <algorithm>
+
+#include "cspi.h"
+
+#include "debug.h"
+#include "error.h"
+#include "protocol.h"
+
+//--------------------------------------------------------------------------
+
+/* Test byte ordering.
+ * Return true on a little-endian system, false on a big-endian system.
+ */
+inline bool is_little_endian()
+{
+	const short int s = 1;
+	return 1 == *((const char*) &s);
+}
+
+//--------------------------------------------------------------------------
+
+// return as-is, no conversion needed
+inline uint8_t ntoh(uint8_t val) { return val; }
+inline uint8_t hton(uint8_t val) { return val; }
+
+// return as-is, no conversion needed
+inline int8_t ntoh(int8_t val) { return val; }
+inline int8_t hton(int8_t val) { return val; }
+
+// return as-is, no conversion needed
+inline char ntoh(char val) { return val; }
+inline char hton(char val) { return val; }
+
+//--------------------------------------------------------------------------
+
+// convert from network to host byte order
+inline uint16_t ntoh(uint16_t val) { return ntohs(val); }
+inline uint32_t ntoh(uint32_t val) { return ntohl(val); }
+
+// convert from host to network byte order
+inline uint16_t hton(uint16_t val) { return htons(val); }
+inline uint32_t hton(uint32_t val) { return htonl(val); }
+inline uint64_t hton(uint64_t val) {
+
+	const uint64_t LOWORD = 0x00000000ffffffffLL;
+
+	typedef uint64_t I64;
+	return is_little_endian() ?
+		// convert and swap both words
+			(((I64) htonl(val & LOWORD)) << 32) | ((I64) htonl(val >> 32))
+	:
+		// return unchanged
+			val;
+}
+inline uint64_t ntoh(uint64_t val) { return hton(val); }
+
+//--------------------------------------------------------------------------
+
+// prevent ambiguous call of overloaded ntoh
+inline int16_t ntoh(int16_t val) { return ntohs(val); }
+// prevent ambiguous call of overloaded ntoh
+inline int32_t ntoh(int32_t val) {
+	return ntoh(static_cast<uint32_t>(val));
+}
+// prevent ambiguous call of overloaded ntoh
+inline long ntoh(long val) {
+	return ntoh(static_cast<uint32_t>(val));
+}
+// prevent ambiguous call of overloaded ntoh
+inline unsigned long ntoh(unsigned long val) {
+	return ntoh(static_cast<uint32_t>(val));
+}
+
+// prevent ambiguous call of overloaded hton
+inline int16_t hton(int16_t val) { return htons(val); }
+// prevent ambiguous call of overloaded hton
+inline int32_t hton(int32_t val) {
+	return hton(static_cast<uint32_t>(val));
+}
+// prevent ambiguous call of overloaded hton
+inline long hton(long val) {
+	return hton(static_cast<uint32_t>(val));
+}
+// prevent ambiguous call of overloaded hton
+inline unsigned long hton(unsigned long val) {
+	return hton(static_cast<uint32_t>(val));
+}
+
+//--------------------------------------------------------------------------
+
+// convert from network to host byte order
+inline protocol::header& ntoh(protocol::header& hdr) {
+
+	hdr.magic     = ntoh(hdr.magic);
+	hdr.cmd       = ntoh(hdr.cmd);
+	hdr.status    = ntoh(hdr.status);
+	hdr.cmd_val   = ntoh(hdr.cmd_val);
+	hdr.req_val   = ntoh(hdr.req_val);
+	hdr.data_size = ntoh(hdr.data_size);
+
+	return hdr;
+}
+
+// convert from host to network byte order
+inline protocol::header& hton(protocol::header& hdr) {
+
+	hdr.magic     = hton(hdr.magic);
+	hdr.cmd       = hton(hdr.cmd);
+	hdr.status    = hton(hdr.status);
+	hdr.cmd_val   = hton(hdr.cmd_val);
+	hdr.req_val   = hton(hdr.req_val);
+	hdr.data_size = hton(hdr.data_size);
+
+	return hdr;
+}
+
+//--------------------------------------------------------------------------
+
+// prevent ambiguous call of overloaded ntoh(void*)
+inline CSPIHANDLE ntoh(CSPIHANDLE val) {
+	return (CSPIHANDLE) ntoh(reinterpret_cast<uint32_t>(val));
+}
+// prevent ambiguous call of overloaded hton(void*)
+inline CSPIHANDLE hton(CSPIHANDLE val) {
+	return (CSPIHANDLE) hton(reinterpret_cast<uint32_t>(val));
+}
+
+//--------------------------------------------------------------------------
+
+// interpret DataType as a vector of BaseType elements
+//  and transform it in-place with a unary operator
+template <typename CompositeType, typename BaseType>
+inline CompositeType&
+transform(CompositeType& obj, BaseType (*op)(BaseType), size_t count=1)
+{
+	BaseType *begin = reinterpret_cast<BaseType*>(&obj);
+	BaseType *end   = reinterpret_cast<BaseType*>(&obj + count);
+
+	std::transform(begin, end, begin, op);
+	return obj;
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_LIBPARAMS& ntoh(CSPI_LIBPARAMS& obj)
+{
+	typedef CSPI_LIBPARAMS composite_type;
+	typedef uint32_t       base_type;
+
+	return transform<composite_type,base_type>(obj, ntoh);
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_LIBPARAMS& hton(CSPI_LIBPARAMS& obj)
+{
+	typedef CSPI_LIBPARAMS composite_type;
+	typedef uint32_t       base_type;
+
+	return transform<composite_type,base_type>(obj, hton);
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_ENVPARAMS& ntoh(CSPI_ENVPARAMS& obj)
+{
+	typedef CSPI_ENVPARAMS composite_type;
+	typedef uint32_t       base_type;
+
+	return transform<composite_type,base_type>(obj, ntoh);
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_ENVPARAMS& hton(CSPI_ENVPARAMS& obj)
+{
+	typedef CSPI_ENVPARAMS composite_type;
+	typedef uint32_t       base_type;
+
+	return transform<composite_type,base_type>(obj, hton);
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_TIMESTAMP& hton(CSPI_TIMESTAMP& obj)
+{
+	// long
+	obj.st.tv_sec  = hton(obj.st.tv_sec);
+	obj.st.tv_nsec = hton(obj.st.tv_nsec);
+
+	// unsigned long long
+	obj.mt = hton(obj.mt);
+	return obj;
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_TIMESTAMP& ntoh(CSPI_TIMESTAMP& obj)
+{
+	// long
+	obj.st.tv_sec  = ntoh(obj.st.tv_sec);
+	obj.st.tv_nsec = ntoh(obj.st.tv_nsec);
+
+	// unsigned long long
+	obj.mt = ntoh(obj.mt);
+	return obj;
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_SETTIMESTAMP& hton(CSPI_SETTIMESTAMP& obj)
+{
+	// long
+	obj.st.tv_sec  = hton(obj.st.tv_sec);
+	obj.st.tv_nsec = hton(obj.st.tv_nsec);
+
+	// unsigned long long
+	obj.mt = hton(obj.mt);
+
+	// unsigned long
+	obj.phase = hton(obj.phase);
+	return obj;
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_SETTIMESTAMP& ntoh(CSPI_SETTIMESTAMP& obj)
+{
+	// long
+	obj.st.tv_sec  = ntoh(obj.st.tv_sec);
+	obj.st.tv_nsec = ntoh(obj.st.tv_nsec);
+
+	// unsigned long long
+	obj.mt = ntoh(obj.mt);
+
+	// unsigned long
+	obj.phase = ntoh(obj.phase);
+	return obj;
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_SA_ATOM& hton(CSPI_SA_ATOM& obj)
+{
+	typedef CSPI_SA_ATOM composite_type;
+	typedef uint32_t     base_type;
+
+	return transform<composite_type,base_type>(obj, hton);
+}
+
+//--------------------------------------------------------------------------
+
+inline CSPI_SA_ATOM& ntoh(CSPI_SA_ATOM& obj)
+{
+	typedef CSPI_SA_ATOM composite_type;
+	typedef uint32_t     base_type;
+
+	return transform<composite_type,base_type>(obj, ntoh);
+}
+
+#endif	// _TRANSFORM_H
diff --git a/i-tech/server/include/util.h b/i-tech/server/include/util.h
new file mode 100644
index 0000000000000000000000000000000000000000..48b6b6c557629c204f93faf0f719677c30f32860
--- /dev/null
+++ b/i-tech/server/include/util.h
@@ -0,0 +1,414 @@
+// $Id: util.h,v 1.1 2006/03/01 10:34:19 miha Exp $
+
+//! \file util.h
+//! Common utility classes and functions that do not really
+//! belong anywhere else.
+
+#if !defined(_SERVER_UTIL_H)
+#define _SERVER_UTIL_H
+
+extern "C"
+{
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+}
+#include <cstdlib>
+
+#include "cspi.h"
+
+#include "debug.h"
+#include "error.h"
+#include "lock.h"
+#include "protocol.h"
+#include "fdstream.h"
+#include "transform.h"
+#include "socket-io.h"
+#include "server-conf.h"
+
+//--------------------------------------------------------------------------
+
+class obytebuf
+{
+public:
+	explicit obytebuf(uint8_t *buf) : pbase(buf), pptr(buf) {}
+	~obytebuf() {}
+
+	void* serialize(const void *p, size_t n) {
+		std::memcpy(pptr, p, n);
+		return pptr += n;
+	}
+	size_t nwritten() const { return pptr - pbase; }
+
+protected:
+	uint8_t *const pbase, *pptr;	// put base and put ptr
+};
+
+//--------------------------------------------------------------------------
+
+class ibytebuf
+{
+public:
+	explicit ibytebuf(const uint8_t *buf) : gbase(buf), gptr(buf) {}
+	~ibytebuf() {}
+
+	const void* deserialize(void *p, size_t n) {
+		std::memcpy(p, gptr, n);
+		return gptr += n;
+	}
+	size_t nread() const { return gptr - gbase; }
+
+protected:
+	const uint8_t *const gbase, *gptr;	// get base and get ptr
+};
+
+//--------------------------------------------------------------------------
+
+template <typename T>
+inline obytebuf& operator<< (obytebuf& obuf, const T& val) {
+	T t(val);
+	t = hton(t);
+	obuf.serialize(&t, sizeof(t));
+	return obuf;
+}
+
+//--------------------------------------------------------------------------
+
+template <typename T>
+inline ibytebuf& operator>> (ibytebuf& obuf, T& val) {
+	obuf.deserialize(&val, sizeof(val));
+	val = ntoh(val);
+	return obuf;
+}
+
+//--------------------------------------------------------------------------
+
+// interface to data traits for various acq. modes
+struct basic_traits
+{
+	basic_traits() {}
+	virtual ~basic_traits() {}
+
+	virtual size_t size() const = 0;
+	virtual void* xntoh(void *begin, size_t count) const = 0;
+	virtual void* xhton(void *begin, size_t count) const = 0;
+};
+
+//--------------------------------------------------------------------------
+
+// adds generic functions to convert between host and network
+// byte order a vector of data elements
+template <typename CompositeType, typename BaseType>
+struct data_traits : public basic_traits {
+
+	size_t size() const {
+		return sizeof(CompositeType);
+	}
+	void* xntoh(void *first, size_t count) const {
+
+		CompositeType *p = static_cast<CompositeType*>(first);
+		transform<CompositeType,BaseType>(*p, ntoh, count);
+		return first;
+	}
+	void* xhton(void *first, size_t count) const {
+
+		CompositeType *p = static_cast<CompositeType*>(first);
+		transform<CompositeType,BaseType>(*p, hton, count);
+		return first;
+	}
+};
+
+//--------------------------------------------------------------------------
+
+/* Set timeout on all read and write operations to a socket descriptor.
+ * On success, return 0. On error, return -1.
+ */
+int set_socket_timeout(int fd, size_t timeout, bool no_rcvtimeo=false);
+
+//--------------------------------------------------------------------------
+
+/* Wait for input on a file descriptor or pipe-of-death.
+ * Return 0 in former, -1 in later case.
+ */
+int wait_input(int fd, struct timeval *timeout = 0);
+
+//--------------------------------------------------------------------------
+
+// used to cancel all threads from main thread
+class pipe_of_death
+{
+public:
+	static const char char_of_death = 0x1B;
+
+	pipe_of_death() {
+		if (-1 == pipe(fd)) throw SYS_ERROR("pipe");
+	}
+	~pipe_of_death() {
+}
+
+	enum pipe_end {read_end = 0, write_end = 1};
+	int operator[] (pipe_end end) const { return fd[end]; }
+
+private:
+	int fd[2];
+};
+
+//--------------------------------------------------------------------------
+
+class message
+{
+public:
+	message() : msg(0), capacity(0) {
+
+		const size_t initial_size = 64 * sizeof(uint32_t);
+		reserve(initial_size);	// the memory is set to zero
+	}
+	~message() {
+		free(msg);
+	}
+
+	// return pointer to message header
+	protocol::header* header() { return &msg->hdr; }
+	const protocol::header* header() const { return &msg->hdr; }
+
+	// return pointer to message data (one past the header)
+	uint8_t* data() { return msg->data; }
+	const uint8_t* data() const { return msg->data; }
+
+	/* Get message status:
+	 * incoming message: 0 = no reply, else need reply
+	 * outgoing message: 0 = success, else failed
+	 */
+	uint8_t status() const { return header()->status; }
+	// delegate to status()
+	operator void*() const {
+		return reinterpret_cast<void *>(status());
+	}
+
+	/* Reserve internal memory for at least a header and num data
+	 * bytes. If num is less than the actual capacity, the call
+	 * no effect. Each reallocation invalidates all pointers.
+	 */
+	void reserve(size_t num);
+
+protected:
+	/* Note: msg is allocated a block of memory large enough to
+	 * accomodate the header AND a variable-size data section.
+	 * Thus, the message can be passed (i.e. to a C function) as
+	 * a single, continuous memory block.
+	 */
+	protocol::message *msg;
+
+	// number of bytes the message may contain without realloc
+	size_t capacity;
+
+private:
+	// NOOP. Prevent compiler from creating a default assignment op.
+	message& operator= (const message&);
+};
+
+std::ostream& operator <<(std::ostream& os, message &msg);
+std::istream& operator >>(std::istream& is, message &msg);
+
+//--------------------------------------------------------------------------
+
+// read functor
+class socket_read {
+public:
+	socket_read() {}
+	~socket_read() {}
+
+	// prevent system read to block
+	ssize_t operator() (int fd, void *buf, size_t count) {
+
+		struct timeval tv = {SERVER_CONN_TIMEOUT, 0};
+		ssize_t rc = wait_input(fd, &tv);
+		if (0 == rc) {
+			do {
+				rc = ::read(fd, (void *)buf, (int)count);
+			} while (-1 == rc && EINTR == rc);
+		}
+		return rc;
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// write functor
+class socket_write {
+public:
+	socket_write() {}
+	~socket_write() {}
+
+	ssize_t operator() (int fd, const void *buf, size_t count) {
+		return writen(fd, buf, count);
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// noop (dummy) read/write functor
+class socket_noop {
+public:
+	explicit socket_noop() {}
+	~socket_noop() {}
+
+	ssize_t operator() (int, void*, size_t) {
+		ASSERT(false);
+		return 0;
+	}
+	ssize_t operator() (int, const void*, size_t) {
+		ASSERT(false);
+		return 0;
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// synonim for udp read/write operations
+typedef socket_noop udp_noop;
+
+//--------------------------------------------------------------------------
+
+// read functor
+class udp_read {
+public:
+	udp_read() {}
+	~udp_read() {}
+
+	// receive a message from a socket
+	ssize_t operator() (int fd, void *buf, size_t count) {
+		
+		ssize_t rc;
+		do {
+			rc = recvfrom(fd, buf, count, 0, 0, 0);
+		} while (-1 == rc && EINTR == rc);
+
+		/* NOTE: We assume that count is much less than
+		* the UDP max datagram size and therefore do not
+		* have to deal with fragmented reads!
+		*/
+		ASSERT(rc < 576);
+
+		return rc;
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// write functor
+class udp_write {
+public:
+	// following shortens all typecasts of pointer arguments
+	typedef struct sockaddr SA;
+	SA addr;    // destination
+
+	explicit udp_write(const SA *sa=0) {
+		set_addr(sa);
+	}
+	~udp_write() {}
+
+	const SA* set_addr(const SA *sa){
+		void *p = sa ? std::memcpy(&addr, sa, sizeof(addr)) : 0;
+		return static_cast<const SA*>(p);
+	}
+	// transmit to destination address
+	ssize_t operator() (int fd, const void *buf, size_t count) {
+		ssize_t rc;
+		do {
+			rc = sendto(fd, buf, count, 0, &addr, sizeof(addr));
+		} while (-1 == rc && EINTR == errno);
+		return rc;
+	}
+};
+
+//--------------------------------------------------------------------------
+
+// implements thread-safe event input interface
+class event_receiver
+{
+public:
+	event_receiver() : udp(-1) {}
+	~event_receiver() {}
+
+	/* Open UDP multicast socket.
+		* On success, return 0. On error, return -1.
+		*/
+	void open(const char* group, in_port_t port);
+
+	// close UDP socket descriptor
+	void close() {
+		auto_lock<mutex> lock(udp_mutex);
+		int rc;
+		do {
+			rc = ::close(udp.descriptor());
+		}
+		while (-1==rc && EINTR==errno);
+		VERIFY(udp.detach());
+	}
+
+	// receive multicast event, return the number of chars read
+	int recv(void *msg, size_t len) {
+		auto_lock<mutex> lock(udp_mutex);
+		return udp.sgetn(static_cast<char*>(msg), len);
+	}
+
+	// return streambuf
+	typedef udpbuf<udp_read,udp_noop> udpbuf_type;
+	const udpbuf_type* rdbuf() const {
+		return &udp;
+	}
+
+protected:
+	udpbuf_type udp;
+	mutex udp_mutex;
+};
+
+//--------------------------------------------------------------------------
+
+// implements thread-safe event output interface
+class event_transmitter
+{
+public:
+	event_transmitter() : udp(-1, 0) {}
+	~event_transmitter() {}
+
+	/* Open UDP multicast socket.
+	 * On success, return 0. On error, return -1.
+	 */
+	void open(const char* group, in_port_t port, u_char ttl);
+
+	// close UDP socket descriptor
+	void close() {
+		auto_lock<mutex> lock(udp_mutex);
+		int rc;
+		do {
+			rc = ::close(udp.descriptor());
+		}
+		while (-1==rc && EINTR==errno);
+		VERIFY(udp.detach());
+	}
+
+	// transmit a multicast message, return the number of chars written
+	int send(const void *msg, size_t len) {
+		auto_lock<mutex> lock(udp_mutex);
+		return udp.sputn(static_cast<const char*>(msg), len);
+	}
+	// delegate to send
+	int operator() (const CSPI_EVENTHDR *p) {
+		const CSPI_EVENTHDR h = { hton(p->id), hton(p->param) };
+		return send(&h, sizeof(h));
+	}
+
+	/* Allow this objects to be tested in control structures in
+	 * a short and idiomatic way for its current state:
+	 * if (multicaster) ...
+	 */
+	operator void*() const { return (void *)udp.is_open(); }
+
+protected:
+	udpbuf<udp_noop,udp_write> udp;
+	mutex udp_mutex;
+};
+
+#endif	// _SERVER_UTIL_H
diff --git a/i-tech/server/lib/README b/i-tech/server/lib/README
new file mode 100644
index 0000000000000000000000000000000000000000..e1e062fc8616eeb7f893ac6f4f82d8ed01507462
--- /dev/null
+++ b/i-tech/server/lib/README
@@ -0,0 +1 @@
+libclient.a : i-tech cspi client lib (generic sever access) for x86 - compiled on 02.12.2010 using gcc-4.4.2 
diff --git a/i-tech/server/lib/libclient.a b/i-tech/server/lib/libclient.a
new file mode 100644
index 0000000000000000000000000000000000000000..4bba399d8c5d5be6e3a69da3a17ec7ef395c4ca0
Binary files /dev/null and b/i-tech/server/lib/libclient.a differ
diff --git a/src/ArmOptimization.cpp b/src/ArmOptimization.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ec6b3b581755dc337c520e5f6f6b74d1b2bef66
--- /dev/null
+++ b/src/ArmOptimization.cpp
@@ -0,0 +1,133 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+
+// ============================================================================
+//- check configuration
+// ============================================================================
+#if ! defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# error ARM optimized code can only runs on ARM target - please undef _USE_ARM_OPTIMIZATION_  
+#endif
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "ArmOptimization.h"
+
+#if ! defined (__INLINE_IMPL__)
+# include "ArmOptimization.i"
+#endif // __INLINE_IMPL___
+
+namespace bpm
+{
+
+// ============================================================================
+// SCALING FACTORS (pre-computed once at startup)
+// ============================================================================
+ArmOptimization::ScalingFactor ArmOptimization::no_scaling_scale;
+ArmOptimization::ScalingShift  ArmOptimization::no_scaling_shift;
+
+ArmOptimization::ScalingFactor ArmOptimization::nm_to_mm_scale;
+ArmOptimization::ScalingShift  ArmOptimization::nm_to_mm_shift;
+
+ArmOptimization::ScalingFactor ArmOptimization::nm_to_um_scale;
+ArmOptimization::ScalingShift  ArmOptimization::nm_to_um_shift;
+
+ArmOptimization::ScalingFactor ArmOptimization::gain_scaling_scale;
+ArmOptimization::ScalingShift  ArmOptimization::gain_scaling_shift;
+
+# if defined(_USE_FLOAT_FP_DATA_) 
+
+// ============================================================================
+// compute_scaling_factor                   ** written by M.Abbott - DIAMOND **
+// ============================================================================
+// Compute optional scaling factor for conversion.  Need to compute
+// i32_scaling and scaling_shift so that:
+//      2**31 <= i32_scaling < 2**32
+//      scaling = i32_scaling * 2**scaling_shift 
+// ============================================================================
+void ArmOptimization::compute_scaling_factor (float scaling, u32& i32_scaling, i32& scaling_shift)   
+{ 
+  float ln2 = logf(scaling) / logf(2.0);
+  i32 bits = (i32)floorf(ln2) + 1;
+  i32_scaling = (u32)(scaling * powf(2.0, 32.0 - bits));
+  scaling_shift = bits - 32;
+}  
+
+#else // _USE_FLOAT_FP_DATA_ 
+
+// ============================================================================
+// compute_scaling_factor                   ** written by M.Abbott - DIAMOND **
+// ============================================================================
+// Compute optional scaling factor for conversion.  Need to compute
+// i32_scaling and scaling_shift so that:
+//      2**31 <= i32_scaling < 2**32
+//      scaling = i32_scaling * 2**scaling_shift 
+// ============================================================================
+void ArmOptimization::compute_scaling_factor (double scaling, u64& i64_scaling, i32& scaling_shift)
+{ 
+  double ln2 = log(scaling) / log(2.0);
+  i32 bits = (i32)floor(ln2) + 1;
+  i64_scaling = (u64)(scaling * pow(2.0, 32.0 - bits));
+  scaling_shift = bits - 32;
+}  
+
+#endif // _USE_FLOAT_FP_DATA_ 
+
+// ============================================================================
+// ArmOptimization::init_scaling_factors
+// ============================================================================
+void ArmOptimization::init_scaling_factors ()
+{
+  compute_scaling_factor(1.0, 
+                         ArmOptimization::no_scaling_scale, 
+                         ArmOptimization::no_scaling_shift);
+
+  compute_scaling_factor(1.e-6, 
+                         ArmOptimization::nm_to_mm_scale,
+                         ArmOptimization::nm_to_mm_shift);
+
+  compute_scaling_factor(1.e-3, 
+                         ArmOptimization::nm_to_um_scale,
+                         ArmOptimization::nm_to_um_shift);
+
+  compute_scaling_factor(1.e-4, 
+                         ArmOptimization::gain_scaling_scale,
+                         ArmOptimization::gain_scaling_shift); 
+}
+
+} // namespace bpm
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
diff --git a/src/ArmOptimization.h b/src/ArmOptimization.h
new file mode 100644
index 0000000000000000000000000000000000000000..236a3f8ad3c8bf58745da4be6791e5245ebe27f1
--- /dev/null
+++ b/src/ArmOptimization.h
@@ -0,0 +1,178 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _ARM_OPTIMIZATION_H_
+#define _ARM_OPTIMIZATION_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+
+// ============================================================================
+//- check configuration
+// ============================================================================
+#if ! defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# error ARM optimized code can only runs on ARM target - please undef _USE_ARM_OPTIMIZATION_  
+#endif
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+// ============================================================================
+// INCLUDE MA's CODE
+// ============================================================================
+# include "ma/cordic.h"
+# include "ma/numeric.h"
+
+// ============================================================================
+// CONVERSION/SCALING MACROS
+// ============================================================================
+# define INT_TO_FP(i, fp) \
+   ArmOptimization::fixed_to_fp(i, \
+                                fp, \
+                                ArmOptimization::no_scaling_scale, \
+                                ArmOptimization::no_scaling_shift)
+//-----------------------------------------------------------------------------    
+# define NM_TO_MM(i, fp) \
+   ArmOptimization::fixed_to_fp(i, \
+                                fp, \
+                                ArmOptimization::nm_to_mm_scale, \
+                                ArmOptimization::nm_to_mm_shift) 
+//-----------------------------------------------------------------------------    
+# define NM_TO_UM(i, fp) \
+   ArmOptimization::fixed_to_fp(i, \
+                                fp, \
+                                ArmOptimization::nm_to_um_scale, \
+                                ArmOptimization::nm_to_um_shift) 
+//----------------------------------------------------------------------------- 
+# define UNSCALE_BUTTON_GAIN_CORRECTION(i, fp) \
+   ArmOptimization::fixed_to_fp(i, \
+                                fp, \
+                                ArmOptimization::gain_scaling_scale, \
+                                ArmOptimization::gain_scaling_shift)
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// SHORTCUTS
+// ============================================================================
+typedef int i32;
+typedef unsigned int u32;
+typedef long long i64;
+typedef unsigned long long u64;
+typedef union
+{
+  u64 l;
+  u32 i[2];
+} u64_pun;
+
+// ============================================================================
+// IEEE-754 EXPONENT BIAS FOR SINGLES (FP32) & DOUBLES (FP64)
+// ============================================================================
+#if defined(_USE_FLOAT_FP_DATA_) 
+# define EXPONENT_BIAS 0x7F   // 127 
+#else
+# define EXPONENT_BIAS 0x3FF  // 1023
+#endif
+
+// ============================================================================
+//! ArmOptimization class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class ArmOptimization
+{
+public:
+  /**
+   * Scaling factors initializations for int to fp conversions
+   */ 
+  static void init_scaling_factors ();
+  
+  /**
+   * int-32 to fp-{32 or 64}
+   */ 
+# if defined(_USE_FLOAT_FP_DATA_)
+  static void fixed_to_fp (i32 input, float *result, u32 scaling, i32 scaling_shift);
+#else
+  static void fixed_to_fp (i32 input, double *result, u64 scaling, i32 scaling_shift);
+#endif
+
+  /**
+   * Scaling factors computation
+   */ 
+#if defined(_USE_FLOAT_FP_DATA_)
+  static void compute_scaling_factor (float scaling, u32& i32_scaling, i32& scaling_shift);
+#else
+  static void compute_scaling_factor (double scaling, u64& i64_scaling, i32& scaling_shift); 
+#endif
+
+  /**
+   * A nice integer sqrt implementation (http://www.embedded.com/98/9802fe2.htm) 
+   */ 
+  static u32 sqrt (u32 a);
+
+  //- scaling factors
+#if defined(_USE_FLOAT_FP_DATA_)
+  typedef u32 ScalingFactor;
+#else
+  typedef u64 ScalingFactor;
+#endif
+  typedef i32 ScalingShift;
+  
+  static ScalingFactor no_scaling_scale;
+  static ScalingShift  no_scaling_shift;
+  static ScalingFactor nm_to_mm_scale;
+  static ScalingShift  nm_to_mm_shift;
+  static ScalingFactor nm_to_um_scale;
+  static ScalingShift  nm_to_um_shift;
+  static ScalingFactor gain_scaling_scale;
+  static ScalingShift  gain_scaling_shift;
+  
+private:
+  // = Disallow these operations.
+  //--------------------------------------------
+  ArmOptimization (void);
+  ArmOptimization (const ArmOptimization &);
+  virtual ~ArmOptimization (void);
+  ArmOptimization & operator= (const ArmOptimization &);
+};
+
+} // namespace bpm
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+#if defined (__INLINE_IMPL__)
+# include "ArmOptimization.i"
+#endif // __INLINE_IMPL__
+
+#endif // _ARM_OPTIMIZATION_H_
diff --git a/src/ArmOptimization.i b/src/ArmOptimization.i
new file mode 100644
index 0000000000000000000000000000000000000000..dbe2619e9660f8901b6fb9347cebf9ad6607a6a3
--- /dev/null
+++ b/src/ArmOptimization.i
@@ -0,0 +1,184 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+namespace bpm
+{
+
+#if defined(_USE_FLOAT_FP_DATA_) 
+
+// ============================================================================
+// fixed_to_single                          ** written by M.Abbott - DIAMOND **
+// ============================================================================
+// Converts fixed point integer to single fp applying the conversion:
+//            *result = input * scaling * 2**scaling_shift
+//
+// For optimal results scaling and scaling_shift should be precomputed so that:
+//                      2**31 <= scaling < 2**32
+// 
+// Scaling factor and shift for conversion are computed so that:
+//                  2**31 <= int_scaling < 2**32
+//             scaling = int_scaling * 2**scaling_shift 
+//  
+// Here is the code:
+//             
+// float ln2 = logf(scaling) / logf(2.0);
+// int bits = floorf(ln2) + 1;
+// unsigned int int_scaling = (unsigned int) (scaling * powf(2.0, 32 - bits));   
+// int scaling_shift = bits - 32;  
+// ============================================================================
+INLINE_IMPL void ArmOptimization::fixed_to_fp (i32 input, 
+                                               float *result, 
+                                               u32 scaling, 
+                                               i32 scaling_shift)
+{
+  u32 * iresult = (u32 *)result;
+  if (input == 0)
+    // Special case for 0
+    *iresult = 0;
+  else
+  {
+    // First extract the sign
+    u32 sign = input & 0x80000000;
+    if (sign != 0)
+        input = -input;
+
+    // Normalise the input to maintain largest possible dynamic range.
+    // After this we have:
+    //      2**31 <= fraction < 2**32
+    //      input = sign * fraction * 2**-shift_in
+    u32 shift_in = ::CLZ((u32)input);
+    u32 fraction = input << shift_in;
+
+    // Rescale the fraction.  The following is optimal, assuming that the
+    // scaling factor has been computed to be in the range:
+    //      2**31 <= scaling < 2**32
+    //
+    // If so then the new fraction satisfies
+    //      2**30 <= fraction' < 2**32
+    //      input = (fraction' / scaling) * 2**(32-shift_in)
+    fraction = ::MulUU(fraction, scaling);
+    
+    // Alas, one more normalisation step required: may need to fix up
+    // fraction by one further bit!  This is as good a point as any to
+    // finally discard the top fraction bit (but we'll pretend it's still
+    // there in the analysis below).
+    u32 fixup = ::CLZ(fraction) + 1;
+    fraction <<= fixup;
+    shift_in += fixup;
+
+    // Finally ready to assemble the final result.  The exponent (which
+    // we don't bother to check, because our dynamic range isn't very
+    // large) is computed so that
+    //      result = sign * fraction * 2**(exponent - BIAS - 32)
+    // As it is, we want
+    //      result = input * scaling * 2**scaling_shift
+    //             = fraction' * 2**(scaling_shift + 32 - shift_in) ,
+    // in other words we want
+    //      exponent - BIAS - 32 = scaling_shift + 32 - shift_in
+    u32 exponent = EXPONENT_BIAS + 64 + scaling_shift - shift_in;
+    
+    *iresult = sign | (exponent << 23) | (fraction >> 9);
+  }
+}
+
+#else // _USE_FLOAT_FP_DATA_ 
+
+// ============================================================================
+// fixed_to_double                          ** written by M.Abbott - DIAMOND **
+// ============================================================================
+INLINE_IMPL void ArmOptimization::fixed_to_fp (i32 input, 
+                                               double *result, 
+                                               u64 scaling, 
+                                               i32 scaling_shift)
+{
+  //- special case: <input> == 0
+  if (input == 0)
+  {
+    *((u64 *)result) = 0;
+    return;
+  }
+  //- capture sign of <input>
+  u32 sign = input & 0x80000000;
+  if (sign != 0)
+      input = -input;
+  //- shift the fraction so that it's spread over 32-bits 
+  //- |-> get number of leading zeros in the binary signature of <input>...
+  u32 shift_in = CLZ((u32)input); 
+  //- |-> do the shift
+  u32 fraction_u32 = input << shift_in;
+  //- scale the fraction and put the result into a 64-bits integer
+  u64_pun fraction_u64;
+  fraction_u64.l = (u64)fraction_u32 * scaling;
+  //- apply IEEE-754 normalization (significant hidden bit)
+  u32 fixup = CLZ(fraction_u64.i[1]) + 1;
+  fraction_u64.l <<= fixup;
+  //- don't forget to add this normalization step to the global shift
+  shift_in += fixup;
+  //- compute the expoent
+  u64 exponent = EXPONENT_BIAS + 64 + scaling_shift - shift_in;
+  //- assemble all components
+  //  |-> shift the significant to its place (sign + exponent = 12 bits)
+  fraction_u64.l >>= 12;
+  //  |-> thanks to u64_pun type, it becomes easy to compose the fp64
+  u32 * iresult = (u32 *)result;
+  iresult[0] = sign | (exponent << 20) | fraction_u64.i[1];
+  iresult[1] = fraction_u64.i[0];
+}
+
+#endif // _USE_FLOAT_FP_DATA_ 
+
+// ============================================================================
+// sqrt                              see http://www.embedded.com/98/9802fe2.htm
+// ============================================================================
+INLINE_IMPL u32 ArmOptimization::sqrt (u32 a)
+{
+  u32 rem = 0;
+  u32 root = 0;
+  for (i32 i = 0; i < 16; i++)
+  {
+    root <<= 1;
+    rem = ((rem << 2) + (a >> 30));
+    a <<= 2;
+    root++;
+    if (root <= rem)
+    {
+      rem -= root;
+      root++;
+    }
+    else
+      root--;
+  }
+  return root >> 1;
+}
+
+} // namespace bpm
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
diff --git a/src/BPM.cpp b/src/BPM.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee15a8c3f2416e4065a3fb5b079cf7dd352042e3
--- /dev/null
+++ b/src/BPM.cpp
@@ -0,0 +1,3726 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51 
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr 
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#if defined(_SIMULATION_)
+# include <stdlib.h>
+#endif
+#include <sys/timeb.h>
+#include "BPM.h" 
+#include "ArmOptimization.h" 
+#include "DataProcessing.h" 
+
+#if !defined(__INLINE_IMPL__)
+# include "BPM.i"
+#endif // __INLINE_IMPL__    
+
+// ============================================================================
+// MISC MACROs & PSEUDO CONSTs
+// ============================================================================
+#define _CSPI_CONNECT_FAILURE_RELEASE_HANDLE_
+//-----------------------------------------------------------------------------
+#define kSRV_TMO 				1500
+#define kWATCH_DOG_TMO	2000
+//-----------------------------------------------------------------------------
+#define kPOST_MORTEM_BUFFER_SIZE 16000
+//-----------------------------------------------------------------------------
+#define kLOCK_BUFFER   1
+#define kUNLOCK_BUFFER 0
+//-----------------------------------------------------------------------------
+#define kCLOSE_DELAY_NSEC  750000000
+//-----------------------------------------------------------------------------
+#define kENV_CHANGED_MSG      static_cast<size_t>((bpm::FIRST_USER_MSG +  0))
+#define kSRC_CHANGED_MSG      static_cast<size_t>((bpm::FIRST_USER_MSG +  1))
+#define kDD_DECIM_CHANGED_MSG static_cast<size_t>((bpm::FIRST_USER_MSG +  2))
+#define kGET_ENV_MSG          static_cast<size_t>((bpm::FIRST_USER_MSG +  3))
+#define kSET_TIME_MSG         static_cast<size_t>((bpm::FIRST_USER_MSG +  4))
+#define kSET_ENV_FA_MSG       static_cast<size_t>((bpm::FIRST_USER_MSG +  5))
+#define kGET_ENV_FA_MSG       static_cast<size_t>((bpm::FIRST_USER_MSG +  6))    
+#define kSAVE_DSC_PARAMS_MSG  static_cast<size_t>((bpm::FIRST_USER_MSG +  7))
+#define kALGO_CHANGED_MSG     static_cast<size_t>((bpm::FIRST_USER_MSG +  8))
+#define kRESET_PM_MSG         static_cast<size_t>((bpm::FIRST_USER_MSG +  9))
+#define kRESET_INTERLOCK_MSG  static_cast<size_t>((bpm::FIRST_USER_MSG + 10))
+#define kEVT_MAN_ERROR_MSG    static_cast<size_t>((bpm::FIRST_USER_MSG + 11))
+//-----------------------------------------------------------------------------
+#if ! defined(_EMBEDDED_DEVICE_)
+# define kDD_UNLOCK_CACHE_MSG  static_cast<size_t>((bpm::FIRST_USER_MSG + 100))
+# define kDD_CACHE_STATUS_MSG  static_cast<size_t>((bpm::FIRST_USER_MSG + 101))
+#endif
+//-----------------------------------------------------------------------------
+#define kNO_SA_SAMPLE_AVAILABLE (rc == CSPI_E_SYSTEM && errno == EWOULDBLOCK)
+//-----------------------------------------------------------------------------
+#define kSA_STAT_PROC_THRESHOLD 10
+//-----------------------------------------------------------------------------
+#if ! defined(_EMBEDDED_DEVICE_)
+//- TCP/IP connection timeout may be really huge (Libera down or network problem)
+# define kCONNECTION_TIMEOUT (5 * 60 * 1000)
+#else
+# define kCONNECTION_TIMEOUT
+#endif
+//-----------------------------------------------------------------------------
+#define kRECONFIG_MSG_PRIORITY (LOWEST_MSG_PRIORITY + 10)
+//-----------------------------------------------------------------------------
+#define kRSC_TEMP_UNAVAILABLE_CSPI  -5
+#define kRSC_TEMP_UNAVAILABLE_ERRNO 11
+//-----------------------------------------------------------------------------
+
+// =========================================================================
+// DUMP_CSPI_ERROR
+// =========================================================================
+#define DUMP_CSPI_ERROR(CSPI_ERR_CODE, CSPI_CMD, ORIGIN) \
+  if (CSPI_ERR_CODE) \
+  { \
+    const char * cspi_err_txt =(CSPI_ERR_CODE != -1) \
+                            ? \
+                            ::cspi_strerror(CSPI_ERR_CODE) \
+                            : \
+                            "unknown or generic error"; \
+    TangoSys_OMemStream r; \
+    r << CSPI_CMD << " failed [err:" << CSPI_ERR_CODE; \
+    if (errno) \
+      r << " - errno:" << errno << ":" << ::strerror(errno); \
+    r << "]" << std::ends; \
+    TangoSys_OMemStream d; \
+    d << "Libera CSPI error: " \
+      << cspi_err_txt \
+      << ":" \
+      << ::strerror(errno) \
+      << std::ends; \
+    TangoSys_OMemStream o; \
+    o << ORIGIN << " [" << __FILE__ << "::" << __LINE__ << "]" << std::ends; \
+    try { \
+      Tango::Except::throw_exception(r.str(), d.str(), o.str()); \
+    } \
+    catch(Tango::DevFailed& df) { \
+      BPM::singleton->get_logger()->info_stream() << log4tango::LogInitiator::_begin_log << df << std::endl; \
+    } \
+  }
+  
+// ==========================================================================
+// HANDLE_CSPI_ERROR: CSPI ERROR HANDLING MACRO 
+// ==========================================================================
+#define HANDLE_CSPI_ERROR(CSPI_ERR_CODE, CSPI_CMD, ORIGIN) \
+  if (CSPI_ERR_CODE) \
+  { \
+    this->state_ = BPM_FAULT; \
+    const char * cspi_err_txt = (CSPI_ERR_CODE != -1) \
+							             ? \
+							             ::cspi_strerror(CSPI_ERR_CODE) \
+							             : \
+							             "unknown or generic error"; \
+    TangoSys_OMemStream r; \
+    r << CSPI_CMD << " failed [err:" << CSPI_ERR_CODE; \
+    if (errno) \
+      r << " - errno:" << errno << ":" << ::strerror(errno); \
+    r << "]" << std::ends; \
+    TangoSys_OMemStream d; \
+    d << "Libera CSPI error: " \
+      << cspi_err_txt \
+      << ":" \
+      << ::strerror(errno) \
+      << std::ends; \
+    TangoSys_OMemStream o; \
+    o << ORIGIN << " [" << __FILE__ << "::" << __LINE__ << "]" << std::ends; \
+    try { \
+      Tango::Except::throw_exception(r.str(), d.str(), o.str()); \
+    } \
+    catch(Tango::DevFailed& df) { \
+      ERROR_STREAM << df << std::endl; \
+      throw; \
+    } \
+  } \
+  else \
+  { \
+    if (this->state_ != BPM_FAULT) \
+        this->state_ = BPM_RUNNING; \
+  } \
+  
+// =========================================================================
+// LOGGING MACROS (for static members)
+// =========================================================================  
+#define BPM_ERROR_STREAM BPM::singleton->get_logger()->error_stream()
+#define BPM_WARN_STREAM  BPM::singleton->get_logger()->warn_stream()
+#define BPM_INFO_STREAM  BPM::singleton->get_logger()->info_stream()
+#define BPM_DEBUG_STREAM BPM::singleton->get_logger()->debug_stream()
+
+// =========================================================================
+// HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER: CSPI ERROR HANDLING MACRO
+// =========================================================================
+#define HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(CSPI_ERR_CODE, CSPI_CMD, ORIGIN) \
+  if (CSPI_ERR_CODE) \
+  { \
+    BPM::singleton->state_ = BPM_FAULT; \
+    const char * cspi_err_txt =(CSPI_ERR_CODE != -1) \
+							             ? \
+							             ::cspi_strerror(CSPI_ERR_CODE) \
+							             : \
+							             "unknown or generic error"; \
+    TangoSys_OMemStream r; \
+    r << CSPI_CMD << " failed [err:" << CSPI_ERR_CODE; \
+    if (errno) \
+      r << " - errno:" << errno << ":" << ::strerror(errno); \
+    r << "]" << std::ends; \
+    TangoSys_OMemStream d; \
+    d << "Libera CSPI error: " \
+      << cspi_err_txt \
+      << ":" \
+      << ::strerror(errno) \
+      << std::ends; \
+    TangoSys_OMemStream o; \
+    o << ORIGIN << " [" << __FILE__ << "::" << __LINE__ << "]" << std::ends; \
+    try { \
+      Tango::Except::throw_exception(r.str(), d.str(), o.str()); \
+    } \
+    catch(Tango::DevFailed& df) { \
+      BPM::singleton->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << df << std::endl; \
+      throw; \
+    } \
+  } \
+  else \
+  { \
+    if (BPM::singleton->state_ != BPM_FAULT) \
+        BPM::singleton->state_ = BPM_RUNNING; \
+  } \
+
+#if ! defined(_EMBEDDED_DEVICE_)
+// =========================================================================
+// HANDLE_SERVER_ERROR: GENERIC SERVER ERROR HANDLING MACRO 
+// =========================================================================
+#define HANDLE_SERVER_ERROR(SRV_ERR_CODE, SRV_CMD, ORIGIN) \
+  if (SRV_ERR_CODE) \
+  { \
+    BPM::singleton->state_ = BPM_FAULT; \
+    std::string err_txt("unknown generic server error"); \
+    switch(errno) \
+    { \
+      case SRV_E_PROTO: \
+        err_txt = "generic server error [protocol mismatch]"; \
+        break; \
+      case SRV_E_INVAL: \
+        err_txt = "generic server error [invalid argument]"; \
+        break; \
+    } \
+    TangoSys_OMemStream r; \
+    r << SRV_CMD << " failed [err:" << SRV_ERR_CODE; \
+    if (errno) \
+      r << " - errno:" << errno << ":" << ::strerror(errno); \
+    r << "]" << std::ends; \
+    TangoSys_OMemStream d; \
+    d << "Libera generic server error: " << err_txt << std::ends; \
+    TangoSys_OMemStream o; \
+    o << ORIGIN << " [" << __FILE__ << "::" << __LINE__ << "]" << std::ends; \
+    try { \
+      Tango::Except::throw_exception(r.str(), d.str(), o.str()); \
+    } \
+    catch(Tango::DevFailed& df) { \
+      ERROR_STREAM << df << std::endl; \
+      throw; \
+    } \
+  } \
+  else \
+  { \
+		if (BPM::singleton->state_ != BPM_FAULT) \
+        BPM::singleton->state_ = BPM_RUNNING; \
+  }
+#endif //- _EMBEDDED_DEVICE_
+
+namespace bpm
+{
+  
+// ============================================================================
+// BPM static members
+// ===========================================================================
+BPM * BPM::singleton = 0;
+bpm::Mutex BPM::lock;
+bool BPM::closed = true;
+
+// ============================================================================
+// BPM::BPM
+// ============================================================================
+BPM::BPM(Tango::DeviceImpl * _host_device)
+  : Tango::LogAdapter(_host_device),
+    state_(BPM_UNKNOWN),
+    dd_raw_buffer_(0),
+    last_dd_data_(0),
+    last_dd_data_updated_(false),
+    dd_data_1_(0),
+    dd_data_2_(0),
+    adc_raw_buffer_(0),
+    last_adc_data_(0),
+    last_adc_data_updated_(false),
+    adc_data_1_(0),
+    adc_data_2_(0),
+    last_sa_data_(0),
+    last_sa_data_updated_(false),
+    sa_data_1_(0),
+    sa_data_2_(0),
+    last_pm_data_(0),
+    last_pm_data_updated_(false),
+    trigger_counter_(0),
+#if ! defined(_EMBEDDED_DEVICE_)
+    connected_(false),
+#endif
+    dd_buffer_frozen_(false),
+    srv_task_(0),
+    dd_task_(0),
+    sa_task_(0),
+    adc_task_(0),
+    host_device_(_host_device),
+    pm_notified_(false),
+    pm_event_counter_(0),
+    dd_requires_trigger_notifications_(false),
+    adc_requires_trigger_notifications_(false)
+#if defined(_EMBEDDED_DEVICE_)
+    , evts_man_(0)
+#endif 
+
+{
+  BPM::singleton = this;
+  BPM::closed = true;
+}
+
+// ============================================================================
+// BPM::~BPM
+// ============================================================================
+BPM::~BPM (void)
+{
+  try
+  {
+    //- set BPM::closed to true before locking the mutex (see cspi_evt_handler)
+    BPM::closed = true;
+    //- enter critical section
+    bpm::AutoMutex<bpm::Mutex> guard(BPM::lock);
+    //- call actual close/release impl
+    this->close_i();
+  }
+  catch(...)
+  {
+    //- ignore any error
+  }
+  BPM::singleton = 0;
+}
+
+// ============================================================================
+// BPM::init
+// ============================================================================
+void BPM::init(const BPMConfig & _config)
+  throw (Tango::DevFailed)
+{
+  //- enter critical section
+  bpm::AutoMutex<bpm::Mutex> guard(BPM::lock);
+  //- call actual init impl
+  this->init_i(_config);
+}
+
+// ============================================================================
+// BPM::init_i
+// ============================================================================
+void BPM::init_i(const BPMConfig & _config)
+  throw (Tango::DevFailed)
+
+{
+  DEBUG_STREAM << "BPM::init <-" << std::endl;
+
+  //- allocate the BPM thread
+  try
+  {
+#if defined(_EMBEDDED_DEVICE_)
+    //- be sure the liberad is not running on the Libera
+    if (LiberaEventsManager::is_liberad_running(true))
+    {
+      Tango::Except::throw_exception(_CPTC("DEVICE_ERROR"),
+                                    _CPTC("the Libera generic server is running on the Libera [kill it then exec init on the BPM device]"),
+                                    _CPTC("BPM::init"));
+    }
+    //- be sure the eventd is not running on the Libera
+    if (LiberaEventsManager::is_eventd_running(true))
+    {
+      Tango::Except::throw_exception(_CPTC("DEVICE_ERROR"),
+                                    _CPTC("the Libera events daemon is running on the Libera [kill it then exec init on the BPM device]"),
+                                    _CPTC("BPM::init"));
+    }
+#endif
+ 
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+    //- precompute scaling factors for int to fp conversions
+    ArmOptimization::init_scaling_factors();
+#endif
+      
+    //- store "requested" configuration localy
+    this->config_ = _config;
+
+    //- enable/disable dd optional data
+    DDData::m_optional_data_enabled =
+            _config.dd_optional_data_enabled();
+            
+    //- enable/disable sa optional data
+    SAData::m_optional_data_enabled =
+            _config.sa_optional_data_enabled();
+
+    //- enable/disable adc optional data
+    ADCData::m_optional_data_enabled =
+            _config.adc_optional_data_enabled();
+            
+    //- enable/disable sa history optional data 
+    SAHistory::m_optional_data_enabled =
+            _config.sa_history_optional_data_enabled();
+            
+    //- SRV task ----------------------------------------
+    DEBUG_STREAM << "BPM::instanciating SRV task" << std::endl;
+    bpm::Task::Config srv_config(this->host_device_,
+                                BPM::srv_message_handler,
+                                static_cast<Thread::IOArg>(this));
+    this->srv_task_ = new bpm::Task(srv_config);
+    if (this->srv_task_ == 0)
+      throw std::bad_alloc();
+      
+    //- DD task ----------------------------------------
+    DEBUG_STREAM << "BPM::instanciating DD task" << std::endl;
+    bpm::Task::Config dd_config(this->host_device_,
+                                BPM::dd_message_handler,
+                                static_cast<Thread::IOArg>(this));
+    this->dd_task_ = new bpm::Task(dd_config);
+    if (this->dd_task_ == 0)
+      throw std::bad_alloc();
+      
+    //- SA task ----------------------------------------
+    DEBUG_STREAM << "BPM::instanciating SA task" << std::endl;
+    bpm::Task::Config sa_config(this->host_device_,
+                                BPM::sa_message_handler,
+                                static_cast<Thread::IOArg>(this));
+    this->sa_task_ = new bpm::Task(sa_config);
+    if (this->sa_task_ == 0)
+      throw std::bad_alloc();
+      
+    //- ADC task ----------------------------------------
+    DEBUG_STREAM << "BPM::instanciating ADC task" << std::endl;
+    bpm::Task::Config adc_config(this->host_device_,
+                                BPM::adc_message_handler,
+                                static_cast<Thread::IOArg>(this));
+    this->adc_task_ = new bpm::Task(adc_config);
+    if (this->adc_task_ == 0)
+      throw std::bad_alloc();
+
+#if defined(_EMBEDDED_DEVICE_)
+    //- evt manager -------------------------------------
+    LiberaEventsManagerConfig cfg;
+    cfg.user_data = this;
+    cfg.host_device = this->host_device_;
+    cfg.evt_handler = BPM::libera_event_callback;
+    cfg.evts_mask = 0;
+    this->evts_man_ = new LiberaEventsManager(cfg);
+    if (this->evts_man_ == 0)
+      throw std::bad_alloc();
+#endif //- _EMBEDDED_DEVICE_
+
+  }
+  catch(const std::bad_alloc&)
+  {
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("bpm::Task allocation failed"),
+                                   _CPTC("BPM::init"));
+  }
+  catch(const Tango::DevFailed& df)
+  {
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("INTERNAL_ERROR"),
+                                      _CPTC("bpm::Task allocation failed"),
+                                      _CPTC("BPM::init"));
+  }
+  catch(...)
+  {
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("bpm::Task allocation failed"),
+                                   _CPTC("BPM::init"));
+  }
+
+  //- start the BPM tasks
+  try
+  {
+#if defined(_EMBEDDED_DEVICE_)
+    //- start the Libera events manager
+    this->evts_man_->go();
+    //- give other threads some time to run
+    Thread::yield();
+#endif
+
+    //- start the service task(use the huge connection tmo)
+    this->srv_task_->go(kCONNECTION_TIMEOUT);
+    
+    //- start the dd task(use the huge connection tmo)
+    this->dd_task_->go(kCONNECTION_TIMEOUT);
+      
+    //- start the sa task(use the huge connection tmo)
+    this->sa_task_->go(kCONNECTION_TIMEOUT);
+      
+    //- start the adc task(use the huge connection tmo)
+    this->adc_task_->go(kCONNECTION_TIMEOUT);
+  }
+  catch (const Tango::DevFailed& df)
+  {
+    //- cleanup
+    try { this->close_i(); } 
+    catch (const Tango::DevFailed&) { }
+    catch (...) { }
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("initialization error"),
+                                      _CPTC("BPM intialization failed"),
+                                      _CPTC("BPM::init"));
+  }
+  catch (...)
+  {
+    //- cleanup
+    try { this->close_i(); } 
+    catch (const Tango::DevFailed&) { }
+    catch (...) { }
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("BPM initialization failed"),
+                                   _CPTC("BPM::init"));
+  }
+
+  //- start to accept cspi notification
+  BPM::closed = false;
+
+  //- update internal state
+  this->state_ = BPM_RUNNING;
+
+  DEBUG_STREAM << "BPM::init ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::close_i
+// ============================================================================
+void BPM::close_i (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::close <-" << std::endl;
+  
+#if defined(_EMBEDDED_DEVICE_)
+  //- disable all cspi events
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  this->evts_man_->set_events_mask(0);
+#endif
+
+  //- stop SRV task -----------------
+  if (this->srv_task_)
+  {
+    try
+    {
+      this->srv_task_->exit();
+      this->srv_task_ = 0;
+    }
+    catch(...) {}
+  }
+  
+  //- stop DD task -----------------------
+  if (this->dd_task_)
+  {
+    try
+    {
+      this->dd_task_->exit();
+      this->dd_task_ = 0;
+    }
+    catch(...) {}
+  }
+  
+  //- stop ADC task ----------------------
+  if (this->adc_task_)
+  {
+    try
+    {
+      this->adc_task_->exit();
+      this->adc_task_ = 0;
+    }
+    catch(...) {}
+  }
+  
+  //- stop SA task -----------------------
+  if (this->sa_task_)
+  {
+    try
+    {
+      //- abort task
+      this->sa_task_->exit();
+      this->sa_task_ = 0;
+    }
+    catch(...) {}
+  }
+
+#if defined(_EMBEDDED_DEVICE_)
+  //- delete the Libera events manager
+  if (this->evts_man_)
+  {
+    try
+    {
+      this->evts_man_->exit();
+      this->evts_man_ = 0;
+    }
+    catch (...) {}
+  }
+#endif
+
+  //- release preallocate data structures
+  if (this->dd_data_1_)
+  {
+    this->dd_data_1_->release();
+    this->dd_data_1_ = 0;
+  }
+  if (this->dd_data_2_)
+  {
+    this->dd_data_2_->release();
+    this->dd_data_2_ = 0;
+  }
+  if (this->adc_data_1_)
+  {
+    this->adc_data_1_->release();
+    this->adc_data_1_ = 0;
+  }
+  if (this->adc_data_2_)
+  {
+    this->adc_data_2_->release();
+    this->adc_data_2_ = 0;
+  }
+  if (this->sa_data_1_)
+  {
+    this->sa_data_1_->release();
+    this->sa_data_1_ = 0;
+  }
+  if (this->sa_data_2_)
+  {
+    this->sa_data_2_->release();
+    this->sa_data_2_ = 0;
+  }
+  
+  this->last_dd_data_ = 0;
+  this->last_sa_data_ = 0;
+  this->last_adc_data_ = 0;
+  
+  //- update internal state
+  this->state_ = BPM_UNKNOWN;
+  
+  DEBUG_STREAM << "BPM::close ->" << std::endl;
+}
+
+# if ! defined(_EMBEDDED_DEVICE_)
+// ============================================================================
+// BPM::connect_to_generic_server
+// ============================================================================
+void BPM::connect_to_generic_server (const std::string& caller)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << caller << "::connecting to Libera generic server..." << std::endl;
+  
+  //- max num of connection retries
+  size_t retries = 4;
+  
+  //- retry loop
+  do
+  {
+    //- open connection to Libera generic server
+    int rc =::server_connect(this->config_.ip_addr_.c_str(), 
+                             this->config_.gs_port_,
+                             this->config_.mcast_ip_addr_.c_str(),
+                             0);
+                        
+    //- connected, exit do/while loop                  
+    if (! rc)
+      break;
+      
+    //- not connected, let's retry unless we reach the "retry limit"
+    if (--retries == 0)
+    {
+      HANDLE_SERVER_ERROR(rc, "server_connect", "BPM::connect_to_generic_server");  
+    }
+ 
+    //- about to retry, sleep for a while before retrying
+    INFO_STREAM << caller << "::connection to Libera generic server failed, retrying..." << std::endl;
+    Thread::sleep(250);                     
+  }
+  while (true);
+  
+  INFO_STREAM << caller << " connected to Libera generic server" << std::endl;
+}
+
+// ============================================================================
+// BPM::disconnect_from_generic_server
+// ============================================================================
+void BPM::disconnect_from_generic_server (const std::string& caller)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << caller << "::disconnecting from Libera generic server..." << std::endl;
+  
+  int rc =::server_disconnect();
+  
+  INFO_STREAM << caller << " disconnected from Libera generic server" << std::endl;
+}
+# endif // ! _EMBEDDED_DEVICE_
+
+// ============================================================================
+// BPM::init_srv_task
+// ============================================================================
+void BPM::init_srv_task (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::init_srv_task <-" << std::endl;
+  
+  //- The bpm::Task's mutex is locked (from message handler)
+  //-------------------------------------------------------------------
+  try
+  {
+    //- error code
+    int rc = 0;
+
+    //- instanciate the fa data cache(s)
+    fa_data_rd_.allocate(0, 4, 1024);
+    fa_data_cp_.allocate(0, 4, 1024);
+
+#if ! defined(_SIMULATION_)      
+
+# if ! defined(_EMBEDDED_DEVICE_)
+    //- connect to Libera generic server
+    this->connect_to_generic_server("Service-task");
+# endif // ! _EMBEDDED_DEVICE_
+      
+    CSPI_LIBPARAMS lib_params = {1, 1};
+    DEBUG_STREAM << "BPM::init_srv_task::getting super-user access to the CSPI" << std::endl;
+    rc = ::cspi_setlibparam(&lib_params, CSPI_LIB_SUPERUSER);
+    HANDLE_CSPI_ERROR(rc, "cspi_setlibparam", "BPM::init_srv_task");
+
+    DEBUG_STREAM << "BPM::init_srv_task::allocating env. handle" << std::endl;
+    rc = ::cspi_allochandle(CSPI_HANDLE_ENV, 0, &this->srv_task_->henv_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::init_srv_task");
+    
+    DEBUG_STREAM << "BPM::init_srv_task::allocating con. handle" << std::endl;
+    rc = ::cspi_allochandle(CSPI_HANDLE_CON, this->srv_task_->henv_, &this->srv_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::init_srv_task");
+    
+#endif //- !_SIMULATION_
+
+  //- compute actual offset(synch. with current auto switching config) 
+  //- this will also update <this->config_.requested_ep_> to pass Kx, Kz and offsets to the Libera FPGA
+  this->config_.compute_actual_offsets(this->config_.requested_ep_,
+                                       this->config_.requested_ep_.switches == kAUTO_SWITCHING_MODE); 
+    
+#if ! defined(_SIMULATION_) 
+  //- pass Kx, Kz, offsets, interlock thresholds & switching config to the Libera FPGA 
+  int ep_flags = CSPI_ENV_KX 
+               | CSPI_ENV_KY 
+               | CSPI_ENV_XOFFSET 
+               | CSPI_ENV_YOFFSET 
+               | CSPI_ENV_QOFFSET 
+               | CSPI_ENV_ILK 
+               | CSPI_ENV_SWITCH;
+  DEBUG_STREAM << "BPM::init_srv_task::passing Kx, Kz and offsets to the Libera [FPGA side]" << std::endl;
+  rc = ::cspi_setenvparam(this->srv_task_->henv_, &this->config_.requested_ep_, ep_flags);
+  HANDLE_CSPI_ERROR(rc, "cspi_setenvparam", "BPM::init_srv_task");
+  
+  DEBUG_STREAM << "BPM::init_srv_task::obtaining current env. params from the Libera" << std::endl;
+  this->get_env_parameters(this->srv_task_->henv_, this->config_.actual_ep_);
+#endif
+
+  //- sync requested with actual env. params
+  this->config_.actual_to_requested_ep();
+      
+//#if defined(_DEBUG)
+  this->config_.dump_env_parameters();
+//#endif
+
+#if ! defined(_SIMULATION_)
+    //- set mode of operation - required in order to connect to data source
+    DEBUG_STREAM << "BPM::init_srv_task::applying default con. parameters" << std::endl;
+    this->set_con_parameters(this->srv_task_->hcon_, &this->config_.cp_srv_, CSPI_CON_MODE);
+    
+    //- actual connection to data source
+    DEBUG_STREAM << "BPM::init_srv_task::connecting to PM data source" << std::endl;
+    rc = ::cspi_connect(this->srv_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_connect", "BPM::init_srv_task");
+    
+    this->srv_task_->connected_ = true;
+    
+    DEBUG_STREAM << "BPM::init_srv_task::enabling PM & ITLK notifications" << std::endl;
+    this->enable_pm_notifications();
+    this->enable_interlock_notifications();
+    
+    this->srv_task_->enable_timeout_msg(false);
+    size_t p = this->config_.fa_cache_refresh_period_;
+    if (p > kSRV_TMO)
+      p = kSRV_TMO;
+    this->srv_task_->set_periodic_msg_period(p);
+    this->srv_task_->enable_periodic_msg(true);
+
+#else
+    this->srv_task_->connected_ = true;
+#endif //- !_SIMULATION_
+  }
+  catch(const Tango::DevFailed& df)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("initialization error"),
+                                      _CPTC("TANGO exception caught while trying to initialize the BPM"),
+                                      _CPTC("BPM::init_srv_task"));
+  }
+  catch(const std::bad_alloc &)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                  _CPTC("memory allocation failed"), 
+                                  _CPTC("BPM::init_srv_tDSC_CHANGED...................yeask"));
+  }
+  catch(...)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    //- propagate caught exception as Tango::DevFailed
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("unknown exception caught while trying to initialize the BPM"),
+                                   _CPTC("BPM::init_srv_task"));
+  }
+  DEBUG_STREAM << "BPM::init_srv_task ->" << std::endl; 
+}
+
+// ============================================================================
+// BPM::close_srv_task
+// ============================================================================
+void BPM::close_srv_task (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::close_srv_task <-" << std::endl;
+  
+#if ! defined(_SIMULATION_)
+  //- The bpm::Task's mutex is locked
+  //-------------------------------------------------------------------
+  try
+  {
+    //- disable periodic message
+    this->srv_task_->enable_periodic_msg(false);
+  
+    //- disable notification
+    DEBUG_STREAM << "BPM::close_srv_task::disable asynch. notifications" << std::endl;
+    if (this->srv_task_->connected_) 
+      this->disable_notifications();
+    
+    //- disable buffer freezing
+    DEBUG_STREAM << "BPM::close_srv_task::disable buffer freezing" << std::endl;
+    this->disable_dd_buffer_freezing();
+    
+    //- sleep for a while in order to let incoming notification to be handle
+#if ! defined(_EMBEDDED_DEVICE_)
+    omni_thread::sleep(0, kCLOSE_DELAY_NSEC);
+#endif
+  }
+  catch(Tango::DevFailed df)
+  {
+    ERROR_STREAM << df << std::endl;
+  }
+  catch(...)
+  {
+    /*ignore error */
+  }
+  
+  try 
+  {
+    //- release con handle
+    if (this->srv_task_->hcon_)
+    {
+      DEBUG_STREAM << "BPM::close_srv_task::disconnect from Libera data source" << std::endl;
+      ::cspi_disconnect(this->srv_task_->hcon_);
+      DEBUG_STREAM << "BPM::close_srv_task::release con. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_CON, this->srv_task_->hcon_);
+      this->srv_task_->hcon_ = 0;
+    }
+    
+    //- release env handle
+    if (this->srv_task_->henv_)
+    {
+      DEBUG_STREAM << "BPM::close_srv_task::release env. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_ENV, this->srv_task_->henv_);
+      this->srv_task_->henv_ = 0;
+    }
+      
+#if ! defined(_EMBEDDED_DEVICE_)
+    //- close TCP/IP connection to generic server
+    if (this->srv_task_->connected_)
+      this->disconnect_from_generic_server("Service-task");
+#endif
+
+    this->srv_task_->connected_ = false;
+  }
+  catch(...) 
+  { 
+    /* ignore error */ 
+  }
+  
+#else
+
+  this->srv_task_->connected_ = false;
+  
+#endif //- !_SIMULATION_
+
+  DEBUG_STREAM << "BPM::close_srv_task::release last_pm_data" << std::endl;
+  
+  //- release any existing DD data
+  if (this->last_pm_data_)
+  {
+    this->last_pm_data_->release();
+    this->last_pm_data_ = 0;
+  }
+  
+  DEBUG_STREAM << "BPM::close_srv_task ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::dd_task_connect
+// ============================================================================
+void BPM::dd_task_connect (void)
+    throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::dd_task_connect <-" << std::endl;
+
+  //- The bpm::Task's mutex is locked(from message handler)
+  //-------------------------------------------------------------------
+  try
+  {
+    //- error code
+    int rc = 0;
+
+    try
+    {
+      //- preallocate DDData 1
+      this->dd_data_1_ = new DDData();
+      if (! this->dd_data_1_)
+        throw(std::bad_alloc());
+      this->dd_data_1_->allocate(this->config_.get_dd_raw_buffer_depth(), true);
+      
+      //- preallocate DDData 2
+      this->dd_data_2_ = new DDData();
+      if (! this->dd_data_2_)
+        throw(std::bad_alloc());
+      this->dd_data_2_->allocate(this->config_.get_dd_raw_buffer_depth(), true);
+
+      //- do as if last_data has been acquired in DDData 2
+      this->last_dd_data_ = this->dd_data_2_;
+    }
+    catch (...)
+    {
+      ERROR_STREAM << "BPM::dd_task_connect::DDData preallocation failed" << std::endl;
+      throw(std::bad_alloc());
+    }
+
+#if defined(_SIMULATION_) 
+    this->dd_task_->connected_ = true;
+    DEBUG_STREAM << "BPM::dd_task_connect ->" << std::endl;
+    return;
+#endif
+
+#if ! defined(_EMBEDDED_DEVICE_)
+    //- connect to Libera generic server
+    this->connect_to_generic_server("DD-task");
+
+    //- tbt (i.e. DD) buffer freezing configuration : cache size
+    int cache_size = this->config_.dd_buffer_freezing_enabled_
+                   ? this->config_.get_dd_raw_buffer_depth() 
+                   : 0;
+                  
+    //- tbt (i.e. DD) buffer freezing configuration : cache status
+    int cache_lock = kUNLOCK_BUFFER;
+
+    //- set cache size
+    DEBUG_STREAM << "BPM::dd_task_connect::setting cache size" << std::endl;
+    rc =::server_setparam(protocol::SERVER_CACHE_SIZE, &cache_size);
+    HANDLE_SERVER_ERROR(rc, "server_setparam", "BPM::dd_task_connect");
+    
+    //- unlock the cache
+    DEBUG_STREAM << "BPM::dd_task_connect::setting cache lock" << std::endl;
+    rc =::server_setparam(protocol::SERVER_CACHE_LOCK, &cache_lock);
+    HANDLE_SERVER_ERROR(rc, "server_setparam", "BPM::dd_task_connect");
+#endif // ! _EMBEDDED_DEVICE_
+
+    //- reset buffer freezing flag
+    this->dd_buffer_frozen_ = false;
+
+    DEBUG_STREAM << "BPM::dd_task_connect::allocating env. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_ENV, 0, &this->dd_task_->henv_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::dd_task_connect");
+
+    DEBUG_STREAM << "BPM::dd_task_connect::allocating con. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_CON, this->dd_task_->henv_, &this->dd_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::dd_task_connect");
+
+    //- set mode of operation - required in order to connect to data source
+    DEBUG_STREAM << "BPM::dd_task_connect::applying default con. parameters" << std::endl;
+    this->set_con_parameters(this->dd_task_->hcon_, &this->config_.cp_dd_, CSPI_CON_MODE);
+    
+    //- actual connection to data source
+    DEBUG_STREAM << "BPM::dd_task_connect::connecting to DD data source" << std::endl;
+    rc = ::cspi_connect(this->dd_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_connect", "BPM::dd_task_connect");
+    
+    this->dd_task_->connected_ = true;
+    
+    //- apply DD decimation factor parameters
+    DEBUG_STREAM << "BPM::dd_task_connect::applying decimation factor" << std::endl;
+    this->config_.cp_dd_.dec = this->config_.get_decimation_factor();
+    this->set_con_parameters(this->dd_task_->hcon_, &this->config_.cp_dd_, CSPI_CON_DEC);
+    
+    //- enable DD?
+    if (this->configuration().dd_enabled())
+      this->enable_dd_notifications();
+    else
+      this->disable_dd_notifications();
+      
+    size_t tmo = this->config_.external_trigger_enabled()
+              ? kWATCH_DOG_TMO
+              : this->config_.get_dd_thread_activity_period();
+              
+    this->dd_task_->set_periodic_msg_period(tmo);
+    this->dd_task_->enable_periodic_msg(true);
+  }
+  catch(const Tango::DevFailed& df)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("initialization error"),
+                                      _CPTC("TANGO exception caught while trying to initialize the BPM"),
+                                      _CPTC("BPM::dd_task_connect"));
+  }
+  catch(const std::bad_alloc &)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("BPM::dd_task_connect"));
+  }
+  catch(...)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    //- propagate caught exception as Tango::DevFailed
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("unknown exception caught while trying to initialize the BPM"),
+                                   _CPTC("BPM::dd_task_connect"));
+  }
+  DEBUG_STREAM << "BPM::dd_task_connect ->" << std::endl;
+}
+  
+// ============================================================================
+// BPM::dd_task_disconnect
+// ============================================================================
+void BPM::dd_task_disconnect (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::dd_task_disconnect <-" << std::endl;
+
+  //- The bpm::Task's mutex is locked
+  //-------------------------------------------------------------------
+  try
+  {
+		this->dd_task_->enable_periodic_msg(false);
+
+    this->disable_dd_notifications();
+    
+#if ! defined(_SIMULATION_) 
+    //- release con handle
+    if (this->dd_task_->hcon_)
+    {
+      DEBUG_STREAM << "BPM::dd_task_disconnect::disconnect from Libera data source" << std::endl;
+      ::cspi_disconnect(this->dd_task_->hcon_);
+      DEBUG_STREAM << "BPM::dd_task_disconnect::release con. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_CON, this->dd_task_->hcon_);
+      this->dd_task_->hcon_ = 0;
+    }
+    
+    //- release env handle
+    if (this->dd_task_->henv_)
+    {
+      DEBUG_STREAM << "BPM::dd_task_disconnect::release env. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_ENV, this->dd_task_->henv_);
+      this->dd_task_->henv_ = 0;
+    }
+    
+ #if ! defined(_EMBEDDED_DEVICE_)
+    //- close TCP/IP connection to generic server
+    if (this->dd_task_->connected_)
+      this->disconnect_from_generic_server("DD-task");
+#endif
+
+#endif
+  
+    this->dd_task_->connected_ = false;
+  }
+  catch(...) 
+  { 
+    /* ignore error */ 
+  }
+  
+  DEBUG_STREAM << "BPM::dd_task_disconnect::release last_dd_data" << std::endl;
+
+  //- release DDData 1
+  if (this->dd_data_1_)
+  {
+    this->dd_data_1_->release();
+    this->dd_data_1_ = 0;
+  }
+  //- release DDData 2
+  if (this->dd_data_2_)
+  {
+    this->dd_data_2_->release();
+    this->dd_data_2_ = 0;
+  }
+  
+  //- no last data
+  this->last_dd_data_ = 0;
+  
+  DEBUG_STREAM << "BPM::dd_task_disconnect ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::sa_task_connect
+// ============================================================================
+void BPM::sa_task_connect (void)
+    throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::sa_task_connect <-" << std::endl;
+  
+  //- The bpm::Task's mutex is locked(from message handler)
+  //-------------------------------------------------------------------
+  try
+  {
+    try
+    {
+      //- preallocate SAData 1
+      this->sa_data_1_ = new SAData();
+      if (! this->sa_data_1_)
+        throw(std::bad_alloc());
+      
+      //- preallocate SAData 2
+      this->sa_data_2_ = new SAData();
+      if (! this->sa_data_2_)
+        throw(std::bad_alloc());
+
+      //- do as if last_data has been acquired in SAData 2
+      this->last_sa_data_ = this->sa_data_2_;
+    }
+    catch (...)
+    {
+      ERROR_STREAM << "BPM::sa_task_connect::SAData preallocation failed" << std::endl;
+      throw(std::bad_alloc());
+    }
+    
+    //- allocate SA history buffer
+    DEBUG_STREAM << "BPM::sa_task_connect::allocating history buffer" << std::endl;
+    size_t count = this->config_.get_sa_history_depth();
+    if (count == 0)
+    {
+      Tango::Except::throw_exception(_CPTC("invalid parameter"), 
+                                      _CPTC("invalid SA history depth specified"), 
+                                      _CPTC("BPM::sa_task_connect"));
+    }
+    this->sa_history_.depth(count);
+		this->num_sa_samples_since_last_stat_proc_ = 0;
+
+#if ! defined(_SIMULATION_) 
+    //- error code
+    int rc = 0;
+      
+# if ! defined(_EMBEDDED_DEVICE_)
+    //- connect to Libera generic server
+    this->connect_to_generic_server("SA-task");
+# endif //- _EMBEDDED_DEVICE_
+
+    DEBUG_STREAM << "BPM::sa_task_connect::allocating env. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_ENV, 0, &this->sa_task_->henv_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::sa_task_connect");
+
+    DEBUG_STREAM << "BPM::sa_task_connect::allocating con. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_CON, this->sa_task_->henv_, &this->sa_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::sa_task_connect");
+
+    //- set mode of operation - required in order to connect to data source
+    DEBUG_STREAM << "BPM::sa_task_connect::applying default con. parameters" << std::endl;
+    this->set_con_parameters(this->sa_task_->hcon_, &this->config_.cp_sa_, CSPI_CON_MODE);
+    
+    //- actual connection to data source
+    DEBUG_STREAM << "BPM::sa_task_connect::connecting to SA data source" << std::endl;
+    rc = ::cspi_connect(this->sa_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_connect", "BPM::sa_task_connect");
+    
+    this->sa_task_->connected_ = true;
+    
+    //- set non blocking reading mode
+    DEBUG_STREAM << "BPM::sa_task_connect::set mode non-blocking reading mode" << std::endl;
+    this->set_con_parameters(this->sa_task_->hcon_, &this->config_.cp_sa_, CSPI_CON_SANONBLOCK);
+    
+    //- enable SA?
+    if (this->configuration().sa_enabled())
+      this->enable_sa_notifications();
+    else
+      this->disable_sa_notifications();
+            
+#else
+
+    this->sa_task_->connected_ = true;  
+      
+#endif // !_SIMULATION_ 
+
+    size_t tmo = 0;
+    bool enable_pmsg = false;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+
+#	if defined(_USE_SA_EVENTS_)
+    tmo = kWATCH_DOG_TMO;
+#	else
+    tmo = this->config_.get_sa_thread_activity_period();
+#	endif
+    enable_pmsg = true;
+
+#else //- !_EMBEDDED_DEVICE_
+
+#	if ! defined(_USE_SA_EVENTS_)
+    tmo = this->config_.get_sa_thread_activity_period();
+    enable_pmsg = true;
+# endif 
+
+#endif //- !_EMBEDDED_DEVICE_
+
+    this->sa_task_->set_periodic_msg_period(tmo);
+    this->sa_task_->enable_periodic_msg(enable_pmsg);
+  }
+  catch(const Tango::DevFailed& df)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("initialization error"),
+                                      _CPTC("TANGO exception caught while trying to initialize the BPM"),
+                                      _CPTC("BPM::sa_task_connect"));
+  }
+  catch(const std::bad_alloc &)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                    _CPTC("memory allocation failed"), 
+                                    _CPTC("BPM::sa_task_connect"));
+  }
+  catch(...)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    //- propagate caught exception as Tango::DevFailed
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                    _CPTC("unknown exception caught while trying to initialize the BPM"),
+                                    _CPTC("BPM::sa_task_connect"));
+  }
+  
+  DEBUG_STREAM << "BPM::sa_task_connect ->" << std::endl;
+}
+  
+// ============================================================================
+// BPM::sa_task_disconnect
+// ============================================================================
+void BPM::sa_task_disconnect (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::sa_task_disconnect <-" << std::endl;
+  
+  //- The bpm::Task's mutex is locked
+  //-------------------------------------------------------------------
+  try
+  {
+    this->sa_task_->enable_periodic_msg(false);
+
+    this->disable_sa_notifications();
+      
+#if ! defined(_SIMULATION_) 
+    //- release con handle
+    if (this->sa_task_->hcon_)
+    {
+      DEBUG_STREAM << "BPM::sa_task_disconnect::disconnect from Libera data source" << std::endl;
+      ::cspi_disconnect(this->sa_task_->hcon_);
+      ::cspi_freehandle(CSPI_HANDLE_CON, this->sa_task_->hcon_);
+      this->sa_task_->hcon_ = 0;
+    }
+      
+    //- release env handle
+    if (this->sa_task_->henv_)
+    {
+      ::cspi_freehandle(CSPI_HANDLE_ENV, this->sa_task_->henv_);
+      this->sa_task_->henv_ = 0;
+    }
+      
+# if ! defined(_EMBEDDED_DEVICE_)
+    //- close connection to generic server
+    if (this->sa_task_->connected_)
+      this->disconnect_from_generic_server("SA-task");
+# endif //- _EMBEDDED_DEVICE_
+
+#endif // !_SIMULATION_
+
+    this->sa_task_->connected_ = false;
+  }
+  catch(...) 
+  { 
+    /* ignore error */ 
+  }
+  
+  //- release any existing SA data
+  DEBUG_STREAM << "BPM::sa_task_disconnect::release last_sa_data" << std::endl;
+
+  //- release SAData 1
+  if (this->sa_data_1_)
+  {
+    this->sa_data_1_->release();
+    this->sa_data_1_ = 0;
+  }
+  //- release DDData 2
+  if (this->sa_data_2_)
+  {
+    this->sa_data_2_->release();
+    this->sa_data_2_ = 0;
+  }
+  
+  //- no last data
+  this->last_sa_data_ = 0;
+  
+  DEBUG_STREAM << "BPM::sa_task_disconnect ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::adc_task_connect
+// ============================================================================
+void BPM::adc_task_connect (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::adc_task_connect <-" << std::endl;
+
+  //- The bpm::Task's mutex is locked(from message handler)
+  //-------------------------------------------------------------------
+  try
+  {
+    //- error code
+    int rc = 0;
+    
+    try
+    {
+      //- preallocate ADCData 1
+      this->adc_data_1_ = new ADCData();
+      if (! this->adc_data_1_)
+        throw(std::bad_alloc());
+      this->adc_data_1_->allocate(this->config_.get_adc_raw_buffer_depth(), true);
+      
+      //- preallocate ADCData A
+      this->adc_data_2_ = new ADCData();
+      if (! this->adc_data_2_)
+        throw(std::bad_alloc());
+      this->adc_data_2_->allocate(this->config_.get_adc_raw_buffer_depth(), true);
+
+      //- do as if last_data has been acquired in ADCData 2
+      this->last_adc_data_ = this->adc_data_2_;
+    }
+    catch (...)
+    {
+      ERROR_STREAM << "BPM::adc_task_connect::ADCData preallocation failed" << std::endl;
+      throw(std::bad_alloc());
+    }
+
+#if defined(_SIMULATION_) 
+    this->adc_task_->connected_ = true;
+    DEBUG_STREAM << "BPM::adc_task_connect ->" << std::endl;
+    return;
+#endif
+
+#if ! defined(_EMBEDDED_DEVICE_)
+    //- connect to Libera generic server
+    this->connect_to_generic_server("ADC-task");
+#endif //- _EMBEDDED_DEVICE_
+
+    DEBUG_STREAM << "BPM::adc_task_connect::allocating env. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_ENV, 0, &this->adc_task_->henv_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::adc_task_connect");
+
+    DEBUG_STREAM << "BPM::adc_task_connect::allocating con. handle" << std::endl;
+		rc = ::cspi_allochandle(CSPI_HANDLE_CON, this->adc_task_->henv_, &this->adc_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_allochandle", "BPM::adc_task_connect");
+
+    //- set mode of operation - required in order to connect to data source
+    DEBUG_STREAM << "BPM::adc_task_connect::applying default con. parameters" << std::endl;
+    this->set_con_parameters(this->adc_task_->hcon_, &this->config_.cp_adc_, CSPI_CON_MODE);
+    
+    //- actual connection to data source
+    DEBUG_STREAM << "BPM::adc_task_connect::connecting to DD data source" << std::endl;
+    rc = ::cspi_connect(this->adc_task_->hcon_);
+    HANDLE_CSPI_ERROR(rc, "cspi_connect", "BPM::adc_task_connect");
+    
+    this->adc_task_->connected_ = true;
+
+    //- enable ADC?
+    if (this->configuration().adc_enabled())
+      this->enable_adc_notifications();
+    else
+      this->disable_adc_notifications();
+      
+    size_t tmo = this->config_.external_trigger_enabled()
+               ? kWATCH_DOG_TMO
+               : this->config_.get_dd_thread_activity_period();
+              
+    this->adc_task_->set_periodic_msg_period(tmo);
+    this->adc_task_->enable_periodic_msg(true);
+  }
+  catch(const Tango::DevFailed& df)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::re_throw_exception(const_cast<Tango::DevFailed&>(df),
+                                      _CPTC("initialization error"),
+                                      _CPTC("TANGO exception caught while trying to initialize the BPM"),
+                                      _CPTC("BPM::adc_task_connect"));
+  }
+  catch(const std::bad_alloc &)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("BPM::adc_task_connect"));
+  }
+  catch(...)
+  {
+    //- update internal state
+    this->state_ = BPM_FAULT;
+    //- propagate caught exception as Tango::DevFailed
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("unknown exception caught while trying to initialize the BPM"),
+                                   _CPTC("BPM::adc_task_connect"));
+  }
+  
+  DEBUG_STREAM << "BPM::adc_task_connect ->" << std::endl;
+}
+  
+// ============================================================================
+// BPM::adc_task_disconnect
+// ============================================================================
+void BPM::adc_task_disconnect (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::adc_task_disconnect <-" << std::endl;
+
+  //- The bpm::Task's mutex is locked
+  //-------------------------------------------------------------------
+  try
+  {
+    this->adc_task_->enable_periodic_msg(false);
+    
+    this->disable_adc_notifications();
+    
+#if ! defined(_SIMULATION_) 
+    //- release con handle
+    if (this->adc_task_->hcon_)
+    {
+      DEBUG_STREAM << "BPM::adc_task_disconnect::disconnect from Libera data source" << std::endl;
+      ::cspi_disconnect(this->adc_task_->hcon_);
+      DEBUG_STREAM << "BPM::adc_task_disconnect::release con. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_CON, this->adc_task_->hcon_);
+      this->adc_task_->hcon_ = 0;
+    }
+    //- release env handle
+    if (this->adc_task_->henv_)
+    {
+      DEBUG_STREAM << "BPM::adc_task_disconnect::release env. handle" << std::endl;
+      ::cspi_freehandle(CSPI_HANDLE_ENV, this->adc_task_->henv_);
+      this->adc_task_->henv_ = 0;
+    }
+    
+# if ! defined(_EMBEDDED_DEVICE_)
+    //- close connection to generic server
+    if (this->adc_task_->connected_)
+      this->disconnect_from_generic_server("ADC-task");
+# endif
+
+#endif // ! _SIMULATION_
+
+    this->adc_task_->connected_ = false;
+  }
+  catch(...) 
+  { 
+    //- ignore error 
+  }
+  
+  DEBUG_STREAM << "BPM::adc_task_disconnect::release last_adc_data" << std::endl;
+  
+  //- release ADCData 1
+  if (this->adc_data_1_)
+  {
+    this->adc_data_1_->release();
+    this->adc_data_1_ = 0;
+  }
+  //- release ADCData 2
+  if (this->adc_data_2_)
+  {
+    this->adc_data_2_->release();
+    this->adc_data_2_ = 0;
+  }
+  //- no last data
+  this->last_adc_data_ = 0;
+  
+  DEBUG_STREAM << "BPM::adc_task_disconnect ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_dd_buffer_freezing
+// ============================================================================
+void BPM::disable_dd_buffer_freezing (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_dd_buffer_freezing <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  //- be sure we have something to do...
+  if (! this->srv_task_ || ! this->srv_task_->connected_ || ! this->config_.dd_buffer_freezing_enabled())
+    return;
+    
+  //- ok do the job...
+  int cache_size = 0;
+  int rc =::server_setparam(protocol::SERVER_CACHE_SIZE, &cache_size);
+  HANDLE_SERVER_ERROR(rc, "server_setparam", "BPM::disable_dd_buffer_freezing");
+  
+#endif
+
+  DEBUG_STREAM << "BPM::disable_dd_buffer_freezing ->" << std::endl;
+  
+  this->config_.disable_dd_buffer_freezing();
+}
+
+// ============================================================================
+// BPM::enable_notifications
+// ============================================================================
+void BPM::enable_notifications (int cspi_events_mask)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_notification <-" << std::endl; 
+                           
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  if (!this->srv_task_ || !this->srv_task_->connected_)
+    return;
+
+  CSPI_CONPARAMS * cp = reinterpret_cast<CSPI_CONPARAMS*>(&this->config_.cp_srv_);
+                  
+  cp->handler = BPM::libera_event_callback;
+  cp->user_data = this;
+  cp->event_mask = cspi_events_mask;
+  
+  size_t con_flags = CSPI_CON_HANDLER 
+                   | CSPI_CON_USERDATA 
+                   | CSPI_CON_EVENTMASK;
+                   
+  this->set_con_parameters(this->srv_task_->hcon_, cp, con_flags);
+  
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  this->evts_man_->enable_events(cspi_events_mask);
+  
+#endif
+
+  DEBUG_STREAM << "BPM::enable_notification ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_notifications
+// ============================================================================
+void BPM::disable_notifications (void)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  if (!this->srv_task_ || !this->srv_task_->connected_)
+    return;
+
+  CSPI_CONPARAMS * cp = reinterpret_cast<CSPI_CONPARAMS*>(&this->config_.cp_srv_);
+                  
+  cp->handler = 0;
+  cp->user_data = 0;
+  cp->event_mask = 0;
+  
+  size_t con_flags = CSPI_CON_HANDLER 
+                   | CSPI_CON_USERDATA 
+                   | CSPI_CON_EVENTMASK;
+                   
+  this->set_con_parameters(this->srv_task_->hcon_, cp, con_flags);
+  
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  this->evts_man_->enable_events(0);
+
+#endif
+
+  DEBUG_STREAM << "BPM::disable_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::enable_pm_notifications
+// ============================================================================
+void BPM::enable_pm_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_pm_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+ 
+  int mask = this->current_cspi_events_mask() | CSPI_EVENT_PM;
+      
+  this->enable_notifications(mask);
+                             
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() | CSPI_EVENT_PM;
+    
+  this->evts_man_->enable_events(mask); 
+  
+#endif
+
+  DEBUG_STREAM << "BPM::enable_pm_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_pm_notifications
+// ============================================================================
+void BPM::disable_pm_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_pm_notifications <-" << std::endl;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+ 
+  int mask = this->current_cspi_events_mask() & ~CSPI_EVENT_PM;
+      
+  this->enable_notifications(mask);
+                             
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() & ~CSPI_EVENT_PM;
+    
+  this->evts_man_->enable_events(mask); 
+  
+#endif
+
+  DEBUG_STREAM << "BPM::disable_pm_notifications ->" << std::endl; 
+}
+
+// ============================================================================
+// BPM::enable_interlock_notifications
+// ============================================================================
+void BPM::enable_interlock_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_interlock_notifications <-" << std::endl;
+     
+#if ! defined(_EMBEDDED_DEVICE_)
+ 
+  int mask = this->current_cspi_events_mask() | CSPI_EVENT_INTERLOCK;
+      
+  this->enable_notifications(mask);
+                             
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() | CSPI_EVENT_INTERLOCK;
+    
+  this->evts_man_->enable_events(mask); 
+  
+#endif
+
+  DEBUG_STREAM << "BPM::enable_interlock_notifications ->" << std::endl;
+}
+  
+// ============================================================================
+// BPM::disable_interlock_notifications
+// ============================================================================
+void BPM::disable_interlock_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_interlock_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+ 
+  int mask = this->current_cspi_events_mask() & ~CSPI_EVENT_INTERLOCK;
+      
+  this->enable_notifications(mask);
+                             
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() & ~CSPI_EVENT_INTERLOCK;
+    
+  this->evts_man_->enable_events(mask); 
+  
+#endif
+
+  DEBUG_STREAM << "BPM::disable_interlock_notifications ->" << std::endl; 
+}
+
+// ============================================================================
+// BPM::enable_dd_notifications
+// ============================================================================
+void BPM::enable_dd_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_dd_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask();
+
+  if (this->configuration().external_trigger_enabled())
+  {
+    this->dd_requires_trigger_notifications_ = true;
+      
+    mask |= CSPI_EVENT_TRIGGET;
+  }
+  
+  this->enable_notifications(mask);
+  
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() ;
+             
+  if (this->configuration().external_trigger_enabled())
+  {
+    this->dd_requires_trigger_notifications_ = true;
+    
+    mask |= CSPI_EVENT_TRIGGET;    
+  }
+  
+  this->evts_man_->enable_events(mask);
+    
+#endif
+
+  DEBUG_STREAM << "BPM::enable_dd_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_dd_notifications
+// ============================================================================
+void BPM::disable_dd_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_dd_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask();
+  
+  //- this works because we are under critical section
+  if (! this->adc_requires_trigger_notifications_)
+    mask &= ~CSPI_EVENT_TRIGGET;
+     
+  this->enable_notifications(mask);
+
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask();
+  
+  //- this works because we are under critical section           
+  if (! this->adc_requires_trigger_notifications_)
+    mask &= ~CSPI_EVENT_TRIGGET; 
+    
+  this->evts_man_->enable_events(mask);
+    
+#endif
+
+  DEBUG_STREAM << "BPM::disable_dd_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::enable_adc_notifications
+// ============================================================================
+void BPM::enable_adc_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_adc_notifications <-" << std::endl;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask();
+
+  if (this->configuration().external_trigger_enabled())
+  {
+    this->adc_requires_trigger_notifications_ = true;
+      
+    mask |= CSPI_EVENT_TRIGGET;
+  }
+  
+  this->enable_notifications(mask);
+  
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask(); 
+             
+  if (this->configuration().external_trigger_enabled())
+  {
+    this->adc_requires_trigger_notifications_ = true;
+    
+    mask |= CSPI_EVENT_TRIGGET;    
+  }
+  
+  this->evts_man_->enable_events(mask);
+    
+#endif
+
+  //- whatever are the external trigger settings, we don't need the TRIGEVENT anymore
+  this->adc_requires_trigger_notifications_ =  false ;
+
+  DEBUG_STREAM << "BPM::enable_adc_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_adc_notifications
+// ============================================================================
+void BPM::disable_adc_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_adc_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask();
+  
+  //- this works because we are under critical section
+  if (! this->dd_requires_trigger_notifications_)
+    mask &= ~CSPI_EVENT_TRIGGET;
+     
+  this->enable_notifications(mask);
+
+#else
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask();
+             
+  //- this works because we are under critical section
+  if (! this->dd_requires_trigger_notifications_)
+    mask &= ~CSPI_EVENT_TRIGGET; 
+    
+  this->evts_man_->enable_events(mask);
+    
+#endif
+
+  //- 
+  this->adc_requires_trigger_notifications_ = false;
+
+  DEBUG_STREAM << "BPM::disable_adc_notifications ->" << std::endl;
+}
+  
+// ============================================================================
+// BPM::enable_sa_notifications
+// ============================================================================
+void BPM::enable_sa_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::enable_sa_notifications <-" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask() | CSPI_EVENT_OVERFLOW;
+# if defined(_USE_SA_EVENTS_)
+  mask |= CSPI_EVENT_SA;
+# endif  
+    
+  this->enable_notifications(mask);
+  
+#else //- _EMBEDDED_DEVICE_
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() | CSPI_EVENT_OVERFLOW;
+# if defined(_USE_SA_EVENTS_)
+  mask |= CSPI_EVENT_SA;
+# endif 
+
+  this->evts_man_->enable_events(mask);
+    
+#endif //- _EMBEDDED_DEVICE_
+
+  DEBUG_STREAM << "BPM::enable_sa_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::disable_sa_notifications
+// ============================================================================
+void BPM::disable_sa_notifications (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::disable_sa_notifications <-" << std::endl;
+    
+#if ! defined(_EMBEDDED_DEVICE_)
+
+  int mask = this->current_cspi_events_mask() & ~CSPI_EVENT_OVERFLOW;
+# if defined(_USE_SA_EVENTS_)
+  mask &= ~CSPI_EVENT_SA;
+# endif  
+    
+  this->enable_notifications(mask);
+  
+#else //- _EMBEDDED_DEVICE_
+
+  DEBUG_ASSERT(this->evts_man_ != 0);
+  
+  int mask = this->evts_man_->get_events_mask() & ~CSPI_EVENT_OVERFLOW;
+# if defined(_USE_SA_EVENTS_)
+  mask &= ~CSPI_EVENT_SA;
+# endif 
+
+  this->evts_man_->enable_events(mask);
+    
+#endif //- _EMBEDDED_DEVICE_
+
+  DEBUG_STREAM << "BPM::disable_sa_notifications ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::reset_pm_notification
+// ============================================================================
+void BPM::reset_pm_notification (void) 
+{
+  if (this->srv_task_)
+    this->srv_task_->post(new Message(kRESET_PM_MSG, kRECONFIG_MSG_PRIORITY));
+}
+
+// ============================================================================
+// BPM::reset_interlock_notification
+// ============================================================================
+void BPM::reset_interlock_notification (void) 
+{
+  if (this->srv_task_)
+    this->srv_task_->post(new Message(kRESET_INTERLOCK_MSG, kRECONFIG_MSG_PRIORITY));
+}
+
+// ============================================================================
+// BPM::get_env_parameters
+// ============================================================================
+void BPM::get_env_parameters (CSPIHENV he, CSPI_ENVPARAMS & ep, size_t mask, size_t retries)
+  throw (Tango::DevFailed)
+{
+  do
+  {
+    int rc = ::cspi_getenvparam(he, &ep, mask);
+    if (rc)
+    {
+      //- might encounter a "kRSC_TEMP_UNAVAILABLE" problem 
+      //- this pb seems to be linked to a timeout that might occurs when trying 
+      //- to read the Libera health info (hw temp & fans speed) !
+      if (rc == kRSC_TEMP_UNAVAILABLE_CSPI && errno == kRSC_TEMP_UNAVAILABLE_ERRNO)
+      {
+        //- let's retry...
+        retries--;
+        if (! retries)
+        {
+          HANDLE_CSPI_ERROR(rc, "cspi_getenvparam", "BPM::get_env_parameters");
+        }
+      }
+      else
+      {
+        //- any other cspi error is considered critical...
+        HANDLE_CSPI_ERROR(rc, "cspi_getenvparam", "BPM::get_env_parameters");
+      }
+    }
+    else
+    {
+      break;
+    }
+  }
+  while (retries);
+}
+
+// ============================================================================
+// BPM::set_con_parameters
+// ============================================================================
+void BPM::set_con_parameters (CSPIHCON hc, CSPI_CONPARAMS * cp, int con_flags)
+  throw (Tango::DevFailed)
+{
+  int rc = ::cspi_setconparam(hc, cp, con_flags);
+  
+  HANDLE_CSPI_ERROR(rc, "cspi_setconparam", "set_con_parameters");
+}
+
+// ============================================================================
+// BPM::set_con_parameters
+// ============================================================================
+void BPM::set_con_parameters (CSPIHCON hc, CSPI_CONPARAMS_EBPP * cp, int con_flags)
+  throw (Tango::DevFailed)
+{
+  int rc = ::cspi_setconparam(hc, reinterpret_cast < CSPI_CONPARAMS * >(cp), con_flags);
+  
+  HANDLE_CSPI_ERROR(rc, "cspi_setconparam", "set_con_parameters");
+}
+
+// ============================================================================
+// BPM::get_con_parameters
+// ============================================================================
+void BPM::get_con_parameters (CSPIHCON hc, CSPI_CONPARAMS * cp)
+  throw (Tango::DevFailed)
+{
+  size_t con_flags = CSPI_CON_MODE 
+                   | CSPI_CON_HANDLER 
+                   | CSPI_CON_USERDATA 
+                   | CSPI_CON_EVENTMASK;
+                   
+  int rc = ::cspi_getconparam(hc, cp, con_flags);
+  
+  HANDLE_CSPI_ERROR(rc, "cspi_getconparam", "get_con_parameters");
+}
+
+// ============================================================================
+// BPM::set_con_parameters
+// ============================================================================
+void BPM::get_con_parameters (CSPIHCON hc, CSPI_CONPARAMS_EBPP * cp)
+  throw (Tango::DevFailed)
+{
+  size_t con_flags = CSPI_CON_MODE 
+                   | CSPI_CON_HANDLER 
+                   | CSPI_CON_USERDATA 
+                   | CSPI_CON_EVENTMASK 
+                   | CSPI_CON_DEC 
+                   | CSPI_CON_SANONBLOCK;
+                  
+  int rc = ::cspi_getconparam(hc, reinterpret_cast < CSPI_CONPARAMS * >(cp), con_flags);
+  
+  HANDLE_CSPI_ERROR(rc, "cspi_getconparam", "get_con_parameters");
+}
+
+// ============================================================================
+// BPM::set_interlock_configuration
+// ============================================================================
+void BPM::set_interlock_configuration(const BPMConfig & _config)  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::set_interlock_configuration" << std::endl;
+
+  //- check passed config
+  this->config_.check_env_parameters(_config.requested_ep_);
+
+  //- copy requested interlock config
+  this->config_.requested_ep_.ilk.mode  = _config.requested_ep_.ilk.mode;
+  this->config_.requested_ep_.ilk.Xlow  = _config.requested_ep_.ilk.Xlow;
+  this->config_.requested_ep_.ilk.Xhigh = _config.requested_ep_.ilk.Xhigh;
+  this->config_.requested_ep_.ilk.Ylow  = _config.requested_ep_.ilk.Ylow;
+  this->config_.requested_ep_.ilk.Yhigh = _config.requested_ep_.ilk.Yhigh;
+  this->config_.requested_ep_.ilk.overflow_limit = _config.requested_ep_.ilk.overflow_limit;
+  this->config_.requested_ep_.ilk.overflow_dur = _config.requested_ep_.ilk.overflow_dur;
+  this->config_.requested_ep_.ilk.gain_limit = _config.requested_ep_.ilk.gain_limit;
+  
+  //- only change the interlock part of the configuration
+  int env_flags = 0;
+  env_flags |= CSPI_ENV_ILK;
+  
+  //- tell what to change to the srv task 
+  BPM::EnvParamsSpecifier * eps = new BPM::EnvParamsSpecifier(this->config_.requested_ep_, env_flags);
+  
+  //- apply the new interlock config
+  Message * msg = new Message(kENV_CHANGED_MSG, kRECONFIG_MSG_PRIORITY, true);
+  
+  //- attach EnvParamsSpecifier to the msg
+  msg->attach_data(eps);
+  
+  //- notify the srv task
+  this->srv_task_->wait_msg_handled(msg, 5000);
+}
+  
+// ============================================================================
+// BPM::reconfigure
+// ============================================================================
+void BPM::reconfigure(const BPMConfig& _config)  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::reconfigure <-" << std::endl;
+
+  //- nature of the reconfiguration (optimization)
+  int cfg_modifs = this->config_.compare(_config);
+      
+  //- store "requested" configuration localy(see BPMConfig::operator=)
+  this->config_ = _config;
+      
+#if defined(_DEBUG)
+  this->config_.dump_env_parameters();
+#endif
+    
+  //- do nothing in case config modifs do not require any change on Libera side
+  if (! cfg_modifs)
+  {
+    DEBUG_STREAM << "BPM::reconfigure [cfg not changed] ->" << std::endl;
+    return;
+  }
+
+  //- any change in data sources?
+  if (cfg_modifs & BPMConfig::DD_SOURCE_CHANGED)
+  {
+    //- post an env. change msg to the task
+    if (this->dd_task_)
+      this->dd_task_->post(new Message(kSRC_CHANGED_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+
+  if (cfg_modifs & BPMConfig::ADC_SOURCE_CHANGED)
+  {
+    //- post an env. change msg to the task
+    if (this->adc_task_)
+      this->adc_task_->post(new Message(kSRC_CHANGED_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+
+  if (cfg_modifs & BPMConfig::SA_SOURCE_CHANGED)
+  {
+    //- post an env. change msg to the task
+    if (this->sa_task_)
+      this->sa_task_->post(new Message(kSRC_CHANGED_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+
+  //- any change in env. parameters?
+  bool env_changed = false;
+  
+  //- setup env. params flags
+  int env_flags = 0;
+  
+  if (cfg_modifs & BPMConfig::SWITCHES_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_SWITCH;   
+  }
+  
+  if (cfg_modifs & BPMConfig::AGC_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_AGC;   
+  }
+  
+  if (cfg_modifs & BPMConfig::DSC_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_DSC;    
+  }
+  
+  if (cfg_modifs & BPMConfig::GAIN_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_GAIN;   
+  }
+
+  if (cfg_modifs & BPMConfig::GAINS_OR_OFFSETS_CHANGED || cfg_modifs & BPMConfig::SWITCHES_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_KX;
+    env_flags |= CSPI_ENV_KY;
+    env_flags |= CSPI_ENV_XOFFSET;
+    env_flags |= CSPI_ENV_YOFFSET;
+    env_flags |= CSPI_ENV_QOFFSET;
+  }
+
+  if (cfg_modifs & BPMConfig::EXT_SWITCHING_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_EXTSWITCH;
+  }
+
+  if (cfg_modifs & BPMConfig::SWITCHING_DELAY_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_SWDELAY;
+  }
+  
+  if (cfg_modifs & BPMConfig::TUNE_COMPENSATION_CHANGED)
+  {
+    env_changed = true;
+		env_flags |= CSPI_ENV_MTNCOSHFT; 
+  }
+
+  if (cfg_modifs & BPMConfig::TUNE_OFFSET_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_MTVCXOFFS; 
+  }
+
+  if (cfg_modifs & BPMConfig::EXT_TRIGGER_DELAY_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_TRIGDELAY; 
+  }
+
+  if (cfg_modifs & BPMConfig::PM_OFFSET_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_PMOFFSET; 
+  }
+
+  if (cfg_modifs & BPMConfig::MAF_LENGTH_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_DDC_MAFLENGTH;
+  }
+  
+  if (cfg_modifs & BPMConfig::MAF_DELAY_CHANGED)
+  {
+    env_changed = true;
+    env_flags |= CSPI_ENV_DDC_MAFDELAY;
+  }               
+
+  //- always apply interlock thresholds
+  env_flags |= CSPI_ENV_ILK;
+
+  //- any change in env. parameters?
+  if (env_changed && this->srv_task_)
+  {
+    //- tell what to change to the srv task 
+    BPM::EnvParamsSpecifier * eps = new BPM::EnvParamsSpecifier(this->config_.requested_ep_, env_flags);
+    //- post an env. change msg to the service task
+    Message * msg = new Message(kENV_CHANGED_MSG, kRECONFIG_MSG_PRIORITY);
+    //- attach EnvParamsSpecifier to the msg 
+    msg->attach_data(eps);
+    //- post msg
+    this->srv_task_->post(msg);
+  }
+
+  //- any change in DD cache status?
+  if ((cfg_modifs & BPMConfig::DD_DECIMATION_CHANGED) && this->dd_task_)
+  {
+    this->dd_task_->post(new Message(kDD_DECIM_CHANGED_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+    
+#if ! defined(_EMBEDDED_DEVICE_) && ! defined (_SIMULATION_)
+  //- any change in DD cache status?
+  if (this->dd_task_ && (cfg_modifs & BPMConfig::DD_CACHE_STATUS_CHANGED))
+  {
+    this->dd_task_->post(new Message(kDD_CACHE_STATUS_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+#else
+  if (this->dd_task_)
+  {
+    bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock()); 
+    if (! this->config_.dd_buffer_freezing_enabled_)
+      this->dd_buffer_frozen_ = false;
+  }
+#endif
+
+  //- did user select a new pos. comp. algo?
+  if ((cfg_modifs & BPMConfig::POS_COMP_ALGO_CHANGED) && this->sa_task_)
+  {
+    this->sa_task_->post(new Message(kALGO_CHANGED_MSG, kRECONFIG_MSG_PRIORITY));
+  }
+
+
+  DEBUG_STREAM << "BPM::reconfigure ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::set_time_on_next_trigger
+// ============================================================================
+void BPM::set_time_on_next_trigger(const TimeSettings& _ts)  
+    throw (Tango::DevFailed)
+{
+  if (! this->srv_task_) return;
+  
+  Message * msg = Message::allocate(kSET_TIME_MSG, kRECONFIG_MSG_PRIORITY);
+  msg->attach_data(_ts);  
+  this->srv_task_->post(msg);
+} 
+
+// ============================================================================
+// BPM::unfreeze_dd_buffer
+// ============================================================================
+void BPM::unfreeze_dd_buffer (void) throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BPM::unfreeze_dd_buffer" << std::endl;
+  
+#if ! defined(_EMBEDDED_DEVICE_) && ! defined(_SIMULATION_)
+
+  //- be sure service task exists
+  if (! this->srv_task_) return;
+  
+  //- post an env. change msg to the task
+  this->srv_task_->post(new Message(kDD_UNLOCK_CACHE_MSG, kRECONFIG_MSG_PRIORITY));
+  
+#else
+
+  //- enter critical section
+  bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock());
+  this->dd_buffer_frozen_ = false;
+  
+#endif
+}
+
+// ============================================================================
+// BPM::is_dd_buffer_freezing_enabled
+// ============================================================================
+bool BPM::is_dd_buffer_freezing_enabled (void) throw (Tango::DevFailed)
+{
+  return this->config_.dd_buffer_freezing_enabled_;
+}
+
+// ============================================================================
+// BPM::is_dd_buffer_frozen
+// ============================================================================
+bool BPM::is_dd_buffer_frozen (void) throw (Tango::DevFailed)
+{
+  if (! this->dd_task_) 
+    return false; 
+
+  bool frozen;
+  {
+    bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock());
+    frozen = this->dd_buffer_frozen_;
+  }
+  
+  return frozen;
+}
+
+// ============================================================================
+// BPM::read_fa_data
+// ============================================================================
+void BPM::read_fa_data(FAData & fad_)  throw (Tango::DevFailed)
+{
+  //- be sure service task exists
+  if (! this->srv_task_) return;
+
+  if (this->fa_data_cp_.pbuf)
+  {
+    bpm::AutoMutex<bpm::Mutex> guard(this->fa_data_lock_);
+    fad_.copy_from_full_fa_data_set(this->fa_data_cp_);
+    return;
+  }
+
+  try
+  {
+    delete[] fad_.pbuf;
+    fad_.pbuf = new char[fad_.size * fad_.count];
+    if (! fad_.pbuf) 
+      throw std::bad_alloc();
+  }
+  catch(const std::bad_alloc&)
+  { 
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("BPM::read_fa_data"));
+  }
+  
+  Message * msg = new Message(kGET_ENV_FA_MSG, kRECONFIG_MSG_PRIORITY, true);
+  msg->attach_data(&fad_, false);
+  this->srv_task_->wait_msg_handled(msg, 5000); 
+}
+
+// ============================================================================
+// BPM::write_fa_data
+// ============================================================================
+void BPM::write_fa_data(const FAData & _fa_data)  throw (Tango::DevFailed)
+{
+  //- be sure service task exists
+  if (! this->srv_task_) return;
+  
+  Message * msg = Message::allocate(kSET_ENV_FA_MSG, kRECONFIG_MSG_PRIORITY);
+  msg->attach_data(_fa_data);
+  this->srv_task_->post(msg);
+}
+  
+// ============================================================================
+// BPM::save_dsc_parameters
+// ============================================================================
+void BPM::save_dsc_parameters (void) throw (Tango::DevFailed)
+{
+  //- be sure service task exists
+  if (! this->srv_task_) return;
+  
+  //- post an env. change msg to the task
+  this->srv_task_->post(new Message(kSAVE_DSC_PARAMS_MSG, kRECONFIG_MSG_PRIORITY));
+}
+  
+// ============================================================================
+// BPM::read_dd
+// ============================================================================
+void BPM::read_dd (void) throw (Tango::DevFailed)
+{
+  // DEBUG_STREAM << "BPM::read_dd <-" << std::endl;
+
+#if ! defined(_SIMULATION_) 
+  //- be sure dd source is properly initialized
+  if (! this->dd_task_->hcon_) return;
+#endif
+    
+#if defined(_EMBEDDED_DEVICE_) || defined (_SIMULATION_)
+  { //- critical section : begin
+    bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock()); 
+    if (this->config_.dd_buffer_freezing_enabled_ && this->dd_buffer_frozen_)
+    {
+      DEBUG_STREAM << "BPM::read_dd (DD buffer frozen) ->" << std::endl;
+      return;
+    }
+  }
+#endif
+
+#if ! defined(_SIMULATION_) 
+  int rc = 0;
+  //- set data retrieval position
+  unsigned long long offset = 0;
+  if (! this->config_.external_trigger_enabled())
+  {
+    rc =::cspi_seek(this->dd_task_->hcon_, &offset, CSPI_SEEK_MT);
+    HANDLE_CSPI_ERROR(rc, "cspi_seek", "BPM::read_dd");
+  }
+  else 
+  {
+    offset = this->config_.get_dd_trigger_offset();
+    rc =::cspi_seek(this->dd_task_->hcon_, &offset, CSPI_SEEK_TR);
+    HANDLE_CSPI_ERROR(rc, "cspi_seek", "BPM::read_dd");
+  }
+#endif // !_SIMULATION_
+
+  //- realloc buffer if needed
+  try
+  {
+    size_t required_depth = this->config_.get_dd_raw_buffer_depth();
+    if (this->dd_raw_buffer_.depth() != required_depth)
+    {
+      //- change buffers size under critical section
+      bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock()); 
+      this->dd_raw_buffer_.depth(required_depth);
+      this->dd_data_1_->allocate(required_depth, false);
+      this->dd_data_2_->allocate(required_depth, false);
+    }
+  }
+  catch(const std::bad_alloc &)
+  {
+    { //- critical section : begin
+      bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock()); 
+      this->last_dd_data_ = 0;
+    } //- critical section : end
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_dd"));
+  }
+  catch(...)
+  {
+    { //- critical section : begin
+      bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock());
+      this->last_dd_data_ = 0;
+    } //- critical section : end
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_dd")); 
+  }
+  
+  size_t actual_nsamples = 0; 
+    
+#if ! defined(_SIMULATION_) 
+
+  //- read the DD (i.e. turn by turn) data
+  rc =::cspi_read_ex(this->dd_task_->hcon_,
+                    this->dd_raw_buffer_.base(),
+                    this->dd_raw_buffer_.depth(),
+                    &actual_nsamples, 
+                    0);     
+                               
+  //- <cspi_read_ex> special error case: err:-5 and errno:61: no data available 
+  //----------------------------------------------------------------------------
+  //- this might occur when usign a huge DD buffer size. in this case reading 
+  //- DD data on Libera side is VERY slow and DD data might be overwritten in 
+  //- the circular DD data buffer on Libera side (or something similar). let's 
+  //- ignore this error...   
+  if (rc == -5 && errno == 61)
+  {
+    WARN_STREAM << "BPM::read_dd::cspi_read_ex failed for DD data source "
+                << "[err: -5 - no data available]"
+                << std::endl;
+    return;
+  }
+  else
+  {
+    HANDLE_CSPI_ERROR(rc, "cspi_read_ex", "BPM::read_dd");
+  }
+  
+  //- request timestamp to the Libera
+  CSPI_TIMESTAMP ts;
+  rc =::cspi_gettimestamp(this->dd_task_->hcon_, &ts);
+  
+  //- <cspi_gettimestamp> special error case: err:-3 function call sequence error 
+  //-----------------------------------------------------------------------------
+  //- this might occur when changing time (using the SetTimeOnNextTrigger) on 
+  //- Libera while DD data source is enabled - the trigger timestamp seems to be 
+  //- reset on Libera side. anyway...     
+  if (rc == -3)
+  {
+    //- reset <ts> 
+    ::memset(&ts, 0, sizeof(CSPI_TIMESTAMP));
+    //- log the problem
+    WARN_STREAM << "<cspi_gettimestamp> failed for DD data "
+                << "[might be due to a recent <SetTimeOnNextTrigger> call]"
+                << std::endl;
+  }
+  else
+  {
+    //- no error -3 - handle error normally (might throw an exception)
+    HANDLE_CSPI_ERROR(rc, "cspi_gettimestamp", "BPM::read_dd");
+  }
+    
+#else // !_SIMULATION_
+
+  //- inject dummy values into the buffer
+  actual_nsamples = this->dd_raw_buffer_.depth();
+  CSPI_DD_RAWATOM * dd_raw_atoms = this->dd_raw_buffer_.base();
+  for (size_t a = 0; a < actual_nsamples; a++)
+  {
+    dd_raw_atoms[a].cosVa = static_cast<int>(::random());
+    dd_raw_atoms[a].sinVa = static_cast<int>(::random());
+    dd_raw_atoms[a].cosVb = static_cast<int>(::random());     
+    dd_raw_atoms[a].sinVb = static_cast<int>(::random());
+    dd_raw_atoms[a].cosVc = static_cast<int>(::random());      
+    dd_raw_atoms[a].sinVc = static_cast<int>(::random());
+    dd_raw_atoms[a].cosVd = static_cast<int>(::random());  
+    dd_raw_atoms[a].sinVd = static_cast<int>(::random()); 
+  } 
+    
+#endif // !_SIMULATION_
+
+  //- select preallocated data structure
+  DDData * data = (this->last_dd_data_ == this->dd_data_1_)
+                ? this->dd_data_2_
+                : this->dd_data_1_;
+      
+  //- adapt length to actual number of DD raw atoms
+  data->actual_num_samples(actual_nsamples);
+                
+  //- compute beam pos
+  try
+  {
+    DataProcessing::compute_pos(*data,
+                                this->dd_raw_buffer_,
+                                actual_nsamples,
+                                this->config_);
+  }
+  catch(...)
+  {
+    { //- critical section : begin
+      bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock()); 
+      this->last_dd_data_ = 0;
+    } //- critical section : end
+    throw;
+  }
+  
+#if ! defined(_SIMULATION_) 
+  //- copy the obtained timestamp
+  ::memcpy(&data->timestamp_, &ts.st, sizeof(struct timespec));
+#endif
+    
+  { //- critical section : begin
+    bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock());
+    
+    //- make <last_dd_data_> point to the most recently acquired data
+    this->last_dd_data_ = data;
+    this->last_dd_data_updated_ = true;
+      
+#if defined(_EMBEDDED_DEVICE_) || defined (_SIMULATION_)
+    //- mark DD buffer as frozen
+    if (this->config_.dd_buffer_freezing_enabled_)
+      this->dd_buffer_frozen_ = true;
+#endif
+  } //- critical section : end
+  
+  // DEBUG_STREAM << "BPM::read_dd ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::get_dd_data
+// ============================================================================
+void BPM::get_dd_data (DDData & dest, bool force_update)  throw (Tango::DevFailed)
+{
+  if (! this->dd_task_)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                   _CPTC("no data available"), 
+                                   _CPTC("BPM::get_dd_data"));
+  }
+  
+  //- enter critical section for remaining code
+  bpm::AutoMutex<bpm::Mutex> guard(this->dd_task_->lock());
+  
+  if (this->last_dd_data_ == 0)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                   _CPTC("no data available"), 
+                                   _CPTC("BPM::get_dd_data"));
+  }
+
+  if (this->last_dd_data_updated_ || force_update)
+  {
+    dest = *(this->last_dd_data_);
+    this->last_dd_data_updated_ = false;
+  }
+}
+  
+// ============================================================================
+// BPM::read_sa
+// ============================================================================
+void BPM::read_sa (void) throw (Tango::DevFailed)
+{ 
+  // DEBUG_STREAM << "BPM::read_sa <-" << std::endl; 
+
+  //- be sure sa source is properly initialized
+#if ! defined(_SIMULATION_)
+  if (! this->sa_task_->hcon_) return;
+#endif
+
+  //- cspi error code
+  int rc = 0;
+  
+  //- CSPI SA data struct for read op
+  CSPI_SA_ATOM sa_atom;
+  std::vector<CSPI_SA_ATOM> sa_atoms;
+    
+#if ! defined(_SIMULATION_)
+
+  size_t sa_atom_cnt = 0;
+  //- enter SA reading loop (read till no more samples in the SA buffer)
+  do 
+  {
+    rc =::cspi_get(this->sa_task_->hcon_, &sa_atom);
+    if (rc)
+    {
+      if (kNO_SA_SAMPLE_AVAILABLE)
+      {
+        if (! sa_atom_cnt) 
+          return;
+        else
+          break;
+      }
+      else
+        HANDLE_CSPI_ERROR(rc, "cspi_get", "BPM::read_sa");
+    }
+    sa_atoms.push_back(sa_atom);
+    sa_atom_cnt++;
+  }
+  while(1);
+
+#else // !_SIMULATION_
+
+  ::memset(&sa_atom, 0, sizeof(CSPI_SA_ATOM));
+  //- simulate 16-bits ADC data
+  sa_atom.Va = static_cast<short>(::random());
+  sa_atom.Vb = static_cast<short>(::random());
+  sa_atom.Vc = static_cast<short>(::random());
+  sa_atom.Vd = static_cast<short>(::random());
+  sa_atoms.push_back(sa_atom);
+  
+#endif // !_SIMULATION_
+
+  if (! sa_atoms.size())
+    return;
+
+  //- select preallocated data structure
+  SAData * data = (this->last_sa_data_ == this->sa_data_1_)
+                ? this->sa_data_2_
+                : this->sa_data_1_;
+                
+  //- no timestamp for SA - reset timestamp (should be removed from SAData class)
+  ::memset(&data->timestamp_, 0, sizeof(struct timespec));
+  
+  for (size_t i = 0; i < sa_atoms.size(); i++)
+  {  
+    //- populate our SAData from the CSPI_SA_ATOM
+    *data = sa_atoms[i];  
+    //- compute SA position
+    DataProcessing::compute_pos(*data, this->config_);
+    //- push SA data into the SA history
+    this->sa_history_.push(*data);
+    this->num_sa_samples_since_last_stat_proc_++; 
+  } 
+  
+  { //- critical section : begin
+    bpm::AutoMutex<bpm::Mutex> guard(this->sa_task_->lock()); 
+    //- point to last acquired data
+    this->last_sa_data_ = data;
+    this->last_sa_data_updated_ = true;
+  } //- critical section : end
+
+  //- update SA statistics
+  if (this->num_sa_samples_since_last_stat_proc_ > kSA_STAT_PROC_THRESHOLD)
+  {
+    this->sa_history_.compute_statistics(this->config_.sa_stats_num_samples_);
+    this->num_sa_samples_since_last_stat_proc_ = 0;
+  }
+
+  // DEBUG_STREAM << "BPM::read_sa ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::get_sa_data
+// ============================================================================
+void BPM::get_sa_data (SAData & dest, bool force_update)  throw (Tango::DevFailed)
+{
+  if (! this->sa_task_)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                   _CPTC("no data available"), 
+                                   _CPTC("BPM::get_sa_data"));
+  }
+  
+  //- enter critical section for remaining code
+  bpm::AutoMutex<bpm::Mutex> guard(this->sa_task_->lock());
+  
+  if (this->last_sa_data_ == 0)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                   _CPTC("no data available"), 
+                                   _CPTC("BPM::get_sa_data")); 
+  }
+  
+  if (this->last_sa_data_updated_ || force_update)
+  {
+    dest = *(this->last_sa_data_);
+    this->last_sa_data_updated_ = false;
+  }
+}
+  
+// ============================================================================
+// BPM::get_incoherence
+// ============================================================================
+bpm::FPDataType BPM::get_incoherence (void) throw (Tango::DevFailed)
+{
+  if  (! this->sa_task_)
+  {
+    Tango::Except::throw_exception (_CPTC (kNO_DATA_MSG), 
+                                    _CPTC ("no data available"), 
+                                    _CPTC ("BPM::get_incoherence"));
+  }
+
+  //- enter critical section for remaining code
+  bpm::AutoMutex<bpm::Mutex> guard(this->sa_task_->lock());
+
+  //- check for available SA data
+  if (this->last_sa_data_ == 0)
+  {
+    Tango::Except::throw_exception (_CPTC (kNO_DATA_MSG), 
+                                    _CPTC ("no data available"), 
+                                    _CPTC ("BPM::get_incoherence")); 
+  }
+
+  //- compute the incoherence value
+  bpm::FPDataType dx = 
+    (last_sa_data_->va_ - last_sa_data_->vb_) / (last_sa_data_->va_ + last_sa_data_->vb_)
+        - (last_sa_data_->vd_ - last_sa_data_->vc_) / (last_sa_data_->vd_ + last_sa_data_->vc_);
+  
+  bpm::FPDataType dz = 
+    (last_sa_data_->va_ - last_sa_data_->vd_) / (last_sa_data_->va_ + last_sa_data_->vd_)
+        - (last_sa_data_->vb_ - last_sa_data_->vc_) / (last_sa_data_->vb_ + last_sa_data_->vc_);
+
+  bpm::FPDataType incoherence = 0.36 * this->config_.Kz * ::hypot(dx,dz);
+  
+  return incoherence;
+} 
+
+// ============================================================================
+// BPM::read_adc
+// ============================================================================
+void BPM::read_adc (void) throw (Tango::DevFailed)
+{ 
+  // DEBUG_STREAM << "BPM::read_adc <-" << std::endl;
+
+#if ! defined(_SIMULATION_)
+  //- be sure adc source is properly initialized
+  if (! this->adc_task_->hcon_) return;
+#endif
+
+  //- realloc buffer if needed
+  try
+  {
+    size_t required_depth = this->config_.get_adc_raw_buffer_depth();
+    if (this->adc_raw_buffer_.depth() != required_depth)
+    {
+      this->adc_raw_buffer_.depth(required_depth);
+      this->adc_data_1_->allocate(required_depth, false);
+      this->adc_data_2_->allocate(required_depth, false);
+    }
+  }
+  catch(const std::bad_alloc &)
+  {
+    { //- critical section : begin
+      bpm::AutoMutex<bpm::Mutex> guard(this->adc_task_->lock()); 
+      this->last_adc_data_ = 0;
+    } //- critical section : end
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_adc"));
+  }
+  catch(...)
+  {
+    { //- critical section : begin
+      bpm::AutoMutex<bpm::Mutex> guard(this->adc_task_->lock()); 
+      this->last_adc_data_ = 0;
+    } //- critical section : end
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_adc"));
+  }
+  
+  size_t actual_nsamples;
+    
+#if ! defined(_SIMULATION_)
+
+  int rc = ::cspi_read_ex(this->adc_task_->hcon_,
+                          this->adc_raw_buffer_.base(),
+                          this->adc_raw_buffer_.depth(),
+                          &actual_nsamples,
+                          0);
+  HANDLE_CSPI_ERROR(rc, "cspi_read_ex", "BPM::read_adc");
+    
+#else // ! _SIMULATION_
+
+  //- inject dummy values into the buffer
+  actual_nsamples = this->adc_raw_buffer_.depth();
+    
+#endif // ! _SIMULATION_
+
+  //- select preallocated data structure
+  ADCData * data = (this->last_adc_data_ == this->adc_data_1_)
+                 ? this->adc_data_2_
+                 : this->adc_data_1_;
+                
+  //- adapt length to actual number of ADC raw atoms
+  data->actual_num_samples(actual_nsamples);
+    
+  //- fill the buffers
+  for (size_t i = 0; i < actual_nsamples; i++)
+  {
+    CSPI_ADC_ATOM & adc_raw_atom = this->adc_raw_buffer_[i];
+#if ! defined(_SIMULATION_)
+    *(data->a_.base() + i) = adc_raw_atom.chA;
+    *(data->b_.base() + i) = adc_raw_atom.chB;
+    *(data->c_.base() + i) = adc_raw_atom.chC;
+    *(data->d_.base() + i) = adc_raw_atom.chD;
+#else
+    *(data->a_.base() + i) = static_cast<int>(::random());
+    *(data->b_.base() + i) = static_cast<int>(::random());
+    *(data->c_.base() + i) = static_cast<int>(::random());
+    *(data->d_.base() + i) = static_cast<int>(::random());
+#endif 
+  }    
+
+  //- copy timestamp
+  //- ::memcpy(&last_adc_data_->timestamp_, &ts.st, sizeof(struct timespec));
+
+  {
+    //- critical section : begin
+    bpm::AutoMutex<bpm::Mutex> guard(this->adc_task_->lock()); 
+    //- make <last_dd_data_> point to the most recently acquired data
+    this->last_adc_data_ = data;
+    this->last_adc_data_updated_ = true;
+  }
+  
+  // DEBUG_STREAM << "BPM::read_adc ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::get_adc_data
+// ============================================================================
+void BPM::get_adc_data (ADCData & dest, bool force_update)  throw (Tango::DevFailed)
+{
+  if (! this->adc_task_)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                    _CPTC("no data available"), 
+                                    _CPTC("BPM::get_adc_data"));
+  }
+  
+  //- enter critical section for remaining code
+  bpm::AutoMutex<bpm::Mutex> guard(this->adc_task_->lock());
+  
+  if (this->last_adc_data_ == 0)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                    _CPTC("no data available"), 
+                                    _CPTC("BPM::get_adc_data"));
+  }
+  
+  if (this->last_adc_data_updated_ || force_update)
+  {
+    dest = *(this->last_adc_data_);
+    this->last_adc_data_updated_ = false;
+  }
+}
+  
+// ============================================================================
+// BPM::read_pm
+// ============================================================================
+void BPM::read_pm (void) throw (Tango::DevFailed)
+{
+  // DEBUG_STREAM << "BPM::read_pm <-" << std::endl;
+
+  //- critical section
+  bpm::AutoMutex<bpm::Mutex> guard(this->srv_task_->lock()); 
+    
+  //- leave if frozen
+	if (this->pm_notified_)
+		return;
+
+  //- read the data
+  DEBUG_STREAM << "BPM::read_pm::reading PM data" << std::endl;
+
+  size_t actual_nsamples;
+  DDRawBuffer pm_raw_buffer(kPOST_MORTEM_BUFFER_SIZE);
+  int rc =::cspi_read_ex(this->srv_task_->hcon_, 
+                         pm_raw_buffer.base(), 
+                         pm_raw_buffer.depth(), 
+                         &actual_nsamples, 
+                         0);
+  HANDLE_CSPI_ERROR(rc, "cspi_read_ex", "BPM::read_pm");
+  
+  DEBUG_STREAM << "BPM::read_pm::got " << actual_nsamples << " PM samples" << std::endl;
+  
+  //- try to allocate the returned DDData
+  DEBUG_STREAM << "BPM::read_pm::computing data" << std::endl;
+  DDData * data = 0;
+  try
+  {
+    //- creat an instance of DDData...
+    data = new DDData();
+    if (data == 0)
+      throw std::bad_alloc();
+    //- ...then allocate its buffers
+    data->allocate(actual_nsamples);
+    //- compute beam pos
+    DataProcessing::compute_pos(*data, pm_raw_buffer, actual_nsamples, this->config_);
+  }
+  catch(const std::bad_alloc &)
+  {
+    if (data) data->release();
+    if (this->last_pm_data_)
+      this->last_pm_data_->release();
+    this->last_pm_data_ = 0;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"), 
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_pm"));
+  }
+  catch(...)
+  {
+    if (data) data->release(); 
+    if (this->last_pm_data_)
+      this->last_pm_data_->release();
+    this->last_pm_data_ = 0;
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"), 
+                                   _CPTC("memory allocation failed"), 
+                                   _CPTC("BPM::read_pm"));
+  }
+  
+  //- reset timestamp(no timestamp here)
+  ::memset(&data->timestamp_, 0, sizeof(struct timespec));
+  
+  if (this->last_pm_data_)
+    this->last_pm_data_->release();
+    
+  //- point to acquired data
+  this->last_pm_data_ = data;
+  this->last_pm_data_updated_ = true;
+  
+  //- mark PM notification has received
+  this->pm_notified_ = true;
+  
+  //- inc. our pm notification counter
+  this->pm_event_counter_++;
+  
+  DEBUG_STREAM << "BPM::read_pm::disconnect from PM data source" << std::endl;
+        
+  INFO_STREAM << "<POST MORTEM> notification handled [PM data bufferized]" << std::endl;
+        
+  // DEBUG_STREAM << "BPM::read_pm ->" << std::endl;
+}
+
+// ============================================================================
+// BPM::get_pm_data
+// ============================================================================
+void BPM::get_pm_data (DDData & dest, bool force_update)  throw (Tango::DevFailed)
+{
+  if (! this->srv_task_)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                    _CPTC("no data available"), 
+                                    _CPTC("BPM::get_pm_data"));
+  }
+  
+  //- enter critical section for remaining code
+  bpm::AutoMutex<bpm::Mutex> guard(this->srv_task_->lock());
+  
+  if (! this->pm_notified_ || this->last_pm_data_ == 0)
+  {
+    Tango::Except::throw_exception(_CPTC(kNO_DATA_MSG), 
+                                    _CPTC("no data available"), 
+                                    _CPTC("BPM::get_pm_data"));
+  }
+  
+  if (this->last_pm_data_updated_ || force_update)
+  {
+    dest = *(this->last_pm_data_);
+    this->last_pm_data_updated_ = false;
+  }
+}
+ 
+// ============================================================================
+// BPM::watch_dog
+// ============================================================================
+void BPM::watch_dog (void) throw (Tango::DevFailed)
+{
+#if ! defined(_EMBEDDED_DEVICE_)
+  //- maintain connection
+  int rc =::server_noop();
+  HANDLE_SERVER_ERROR(rc, "server_noop", "BPM::watch_dog");
+#endif
+}
+
+// ============================================================================
+// BPM::libera_event_callback
+// ============================================================================
+int BPM::libera_event_callback (CSPI_EVENT * evt)
+{
+  //- be sure evt is valid (parano impl)
+  if (! evt)
+    return 0;
+
+  //- try to acquire the BPM::lock (enter critical section)
+  bpm::MutexState status = BPM::lock.try_lock();
+  if (status == bpm::MUTEX_BUSY)
+  {
+    //- if lock already owned and BPM closed it means that an other thread 
+    //- is executing BPM::close_i - we avoid deadlock by leaving the place...
+    if (BPM::closed)
+      return 0;
+  }
+  //- if lock acquired but BPM closed then...
+  else if (BPM::closed)
+  {
+    //- leave critical section
+    if (status == bpm::MUTEX_LOCKED)
+      BPM::lock.unlock();
+    return 0;
+  }
+  
+  //- retry to enter critical section (BPM was just busy)
+  if (status != bpm::MUTEX_LOCKED)
+    BPM::lock.lock();
+
+  //- get ref. to our BPM instance (reinterpret user data)
+  BPM * instance = reinterpret_cast<BPM*>(evt->user_data);
+  if (! instance || instance != BPM::singleton)
+  {
+    BPM::lock.unlock();
+    return 0;
+  }
+  
+  //- handle event
+  try 
+  {
+    switch(evt->hdr.id)
+    {
+      //--------------------------------------
+      case CSPI_EVENT_TRIGGET:
+      {
+        //- increment our trigger counter
+        instance->trigger_counter_++;
+        //- notify the DD task 
+        if (instance->dd_task_ && instance->configuration().dd_enabled()) 
+          instance->dd_task_->post(evt);
+        //- notify the ADC task
+        if (instance->adc_task_ && instance->configuration().adc_enabled()) 
+          instance->adc_task_->post(evt);
+      }
+      break;
+      //--------------------------------------
+      case CSPI_EVENT_SA:
+      {
+        //- notify the SA task 
+        if (instance->sa_task_ && instance->configuration().sa_enabled()) 
+          instance->sa_task_->post(evt);
+      }
+      break;
+      //--------------------------------------
+      case CSPI_EVENT_PM:
+      case CSPI_EVENT_INTERLOCK:
+      {
+        //- notify the SRV task
+        if (instance->srv_task_)
+          instance->srv_task_->post(new Message(evt, kRECONFIG_MSG_PRIORITY));
+      }
+      break;
+#if defined(_EMBEDDED_DEVICE_)
+      case CSPI_EVENTS_MANAGER_ERROR:
+      {
+        //- notify the SRV task
+        instance->srv_task_->post(evt);
+      }
+      break;
+#endif
+      //--------------------------------------
+      default:
+      {
+        //- for any other CSPI event we notify the service task
+        if (instance->srv_task_)
+          instance->srv_task_->post(evt);
+      }
+      break;
+    }
+  }
+  catch (Tango::DevFailed& df)
+  {
+    BPM_ERROR_STREAM << df.errors[0].desc
+                     << " [lost message type: " 
+                     << bpm::Message(evt).to_string() 
+                     << "]" 
+                     << std::endl;
+  }
+  
+  //- leave critical section
+  BPM::lock.unlock();
+  
+  return 0;
+}
+  
+// ============================================================================
+// BPM::srv_message_handler
+// ============================================================================
+void BPM::srv_message_handler (const bpm::Message& _msg)
+{     
+  //- reinterpret user data
+  BPM * instance = reinterpret_cast<BPM*>(_msg.user_data());
+  if (instance == 0 || instance != BPM::singleton)
+    return;
+    
+  //- handle msg
+  switch(_msg.type())
+  {
+    //- TASK_INIT ----------------------
+    case TASK_INIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        instance->init_srv_task();
+      }
+      break;
+    //- TASK_EXIT ----------------------
+    case TASK_EXIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        instance->close_srv_task();
+      }
+      break;
+    //- TASK_PERIODIC -------------------
+    case TASK_PERIODIC:
+      {
+        instance->srv_periodic_job();
+      }
+      break;  
+#if ! defined(_SIMULATION_) 
+    //- kSET_ENV_FA_MSG ------------------
+    case kSET_ENV_FA_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        FAData & fad = _msg.get_data<FAData>();
+        int rc = ::cspi_setenvparam_fa(instance->srv_task_->henv_, 
+                                      fad.offset, 
+                                      fad.pbuf, 
+                                      fad.size, 
+                                      fad.count);                          
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_setenvparam_fa", "BPM::srv_message_handler");
+      }
+      break; 
+    //- kGET_ENV_FA_MSG ------------------
+    case kGET_ENV_FA_MSG:
+      {
+        FAData & fad = _msg.get_data<FAData>();
+        int rc = ::cspi_getenvparam_fa(instance->srv_task_->henv_, 
+                                      fad.offset, 
+                                      fad.pbuf, 
+                                      fad.size, 
+                                      fad.count);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_getenvparam_fa", "BPM::srv_message_handler");
+      }
+      break; 
+    //- kSAVE_DSC_PARAMS_MSG ------------------
+    case kSAVE_DSC_PARAMS_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        CSPI_ENVPARAMS ep;
+        ep.dsc = CSPI_DSC_SAVE_LASTGOOD;
+        int rc = ::cspi_setenvparam(instance->srv_task_->henv_, &ep, CSPI_ENV_DSC);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_setenvparam", "BPM::srv_message_handler");
+      }
+      break; 
+    //- kENV_CHANGED_MSG -----------------
+    case kENV_CHANGED_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        //- check requested env. params
+        instance->config_.check_env_parameters(instance->config_.requested_ep_);
+        //- get env. parameters specifier (what to change on Libera side?)
+        BPM::EnvParamsSpecifier & eps = _msg.get_data<BPM::EnvParamsSpecifier>();
+        //- do not try to change the input gain in case the AGC mode is changed (cspi_setenvprams will complain otherwise)
+        if (eps.ep_flags & CSPI_ENV_AGC) 
+          eps.ep_flags &= ~CSPI_ENV_GAIN;   
+        //- compute actual offsets
+        instance->config_.compute_actual_offsets(eps.ep, eps.ep.switches == kAUTO_SWITCHING_MODE);
+        //- apply requested params
+        int rc = ::cspi_setenvparam(instance->srv_task_->henv_, &eps.ep, eps.ep_flags);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_setenvparam", "BPM::srv_message_handler");
+        //- sync actual with requested params 
+        bpm::Thread::sleep(200);
+        instance->get_env_parameters(instance->srv_task_->henv_, instance->config_.actual_ep_);
+        //- update requested env. params
+        instance->config_.actual_to_requested_ep();
+        instance->config_.dump_env_parameters();
+      }
+      break;
+#if ! defined(_EMBEDDED_DEVICE_) 
+    //- kDD_UNLOCK_CACHE_MSG -----------
+    case kDD_UNLOCK_CACHE_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        int val = kUNLOCK_BUFFER;
+        int rc =::server_setparam(protocol::SERVER_CACHE_LOCK, &val);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "server_setparam", "BPM::srv_message_handler");
+      }
+      break;
+#endif //- _EMBEDDED_DEVICE_
+    //- POST MORTEM EVENT --------------
+    case CSPI_PM:
+      {       
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        BPM_INFO_STREAM << "received a <POST MORTEM> notification from Libera" << std::endl;
+        instance->disable_pm_notifications();
+        instance->read_pm();
+      }
+      break;  
+    //- kRESET_PM_MSG ------------------
+    case kRESET_PM_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        instance->pm_notified_ = false;
+        instance->enable_pm_notifications();
+        BPM_INFO_STREAM << "<POST MORTEM> notification acknowlegded by operator" << std::endl;
+      }
+      break;  
+    //- CSPI_INTERLOCK -----------------
+    case CSPI_INTERLOCK:
+      { 
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        if (! instance->hw_status_.intl_flags)
+        {
+          instance->disable_interlock_notifications();
+          InterlockFlags ilk = _msg.cspi_data();
+          instance->hw_status_.intl_flags = ilk;
+          BPM_INFO_STREAM << "received an <INTERLOCK> notification from Libera [ " 
+                          << ((ilk & INTERLOCK_X)    ? "X "    : "")   
+                          << ((ilk & INTERLOCK_Z)    ? "Z "    : "")  
+                          << ((ilk & INTERLOCK_ATTN) ? "ATTN " : "")  
+                          << ((ilk & INTERLOCK_ADC)  ? "ADC "  : "")  
+                          << ((ilk & INTERLOCK_ADCF) ? "ADCF " : "")  
+                          << "]"
+                          << std::endl;
+        }
+		  }
+		  break;
+    //- kRESET_INTERLOCK_MSG -----------
+    case kRESET_INTERLOCK_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        instance->hw_status_.intl_flags = 0;
+        instance->enable_interlock_notifications();
+        BPM_INFO_STREAM << "<INTERLOCK> notification acknowlegded by operator" << std::endl;
+      }
+      break;
+    //- kSET_TIME_MSG ------------------
+    case kSET_TIME_MSG:
+      {
+        bpm::AutoMutex<bpm::Mutex> guard(instance->srv_task_->lock());
+        TimeSettings & _ts = _msg.get_data<TimeSettings>();
+        CSPI_SETTIMESTAMP ts;
+        CSPI_BITMASK mask = 0;
+        //- machine time
+        mask |= CSPI_TIME_MT;
+        ts.mt = static_cast<unsigned long long>(_ts.mt);
+        //- system time
+        mask |= CSPI_TIME_ST;
+        ts.st.tv_sec = static_cast<size_t>(_ts.st);
+        //- phase 
+        ts.phase = static_cast<unsigned long>(_ts.tp);
+        int rc = ::cspi_settime(instance->srv_task_->henv_, &ts, mask);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, " cspi_settime", "BPM::srv_message_handler");
+        CSPI_ENVPARAMS ep; 
+        ep.trig_mode = CSPI_TRIGMODE_SET;
+        rc = ::cspi_setenvparam(instance->srv_task_->henv_, &ep, CSPI_ENV_TRIGMODE);
+        HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_setenvparam", "BPM::srv_message_handler");
+      }
+      break;  
+#endif // ! _SIMULATION_
+#if defined(_EMBEDDED_DEVICE_)
+      //- kEVT_MAN_ERROR_MSG -------------
+      case kEVT_MAN_ERROR_MSG:
+      {
+        //TODO: change dev state to FAULT and update status
+      }
+      break;
+#endif
+    //- REMAINING EVENTS ---------------
+    default:      
+      {
+        //- noop
+      }
+      break;
+  }
+}
+
+// ============================================================================
+// BPM::srv_periodic_job
+// ============================================================================
+void BPM::srv_periodic_job () 
+    throw (Tango::DevFailed)
+{     
+  static bpm::Timer t;
+  double dt_ms = 0.;
+  static bpm::Timer srv_timer;
+
+  //- cspi bug: crash if try to call a cspi function without a valid connection so.
+  //- ... be sure we are properly connected 
+  if (! this->srv_task_->connected_)
+    return;
+
+#if ! defined(_SIMULATION_)
+
+  double fa_dt_msec = this->fa_data_timer_.elapsed_msec() + 0.1 * this->config_.fa_cache_refresh_period_;
+  if (fa_dt_msec >= this->config_.fa_cache_refresh_period_)
+  {
+    try
+    {
+      BPM_DEBUG_STREAM << "BPM::srv_periodic_job::updating FA data cache" << std::endl;
+      t.restart();
+      this->update_fa_data_cache();
+      dt_ms = t.elapsed_msec();
+      BPM_DEBUG_STREAM << "BPM::srv_periodic_job::FA data cache update took " << dt_ms << " ms" << std::endl;
+    }
+    catch (Tango::DevFailed& df)
+    {
+      BPM_ERROR_STREAM << "BPM::srv_periodic_job::FA data cache update gave error" << std::endl;
+      //- BPM_ERROR_STREAM << df << std::endl;
+    }
+    catch (...)
+    {
+      BPM_ERROR_STREAM << "BPM::srv_periodic_job::FA data cache update gave error" << std::endl;
+    }
+    this->fa_data_timer_.restart();
+  }
+
+  double srv_dt_msec = srv_timer.elapsed_msec() + 0.1 * kSRV_TMO;
+  if (srv_dt_msec < kSRV_TMO)
+    return;
+  srv_timer.restart();
+
+  BPM_DEBUG_STREAM << "BPM::srv_periodic_job::it's time to read the env. parameters... " << std::endl;
+  t.restart();
+
+  static int cnt = 0;
+  size_t flags = kALL_PARAMS_EXCEPT_HEALTH;
+  if (! (cnt % 20))
+  { 
+    flags = kALL_PARAMS;
+    cnt = 0;
+  }
+  CSPI_ENVPARAMS ep;
+  ::memcpy(&ep, &this->config_.actual_ep_, sizeof(CSPI_ENVPARAMS));
+  int rc = ::cspi_getenvparam(this->srv_task_->henv_, &ep, flags);
+  //- error handling
+  if (rc)
+  {
+    //- might encounter a "kRSC_TEMP_UNAVAILABLE" problem
+    if (rc == kRSC_TEMP_UNAVAILABLE_CSPI && errno == kRSC_TEMP_UNAVAILABLE_ERRNO)
+    {
+      //- not really a problem - just log then retry later (on next TASK_PERIODIC notification) 
+      DUMP_CSPI_ERROR(rc, "cspi_getenvparam", "BPM::srv_message_handler");
+      return;
+    }
+    else
+    {
+      //- any other cspi error is considered critical...
+      HANDLE_CSPI_ERROR(rc, "cspi_getenvparam", "BPM::srv_message_handler");
+    }
+  }
+  cnt++;
+  {
+    //- get env. params under crtical section to avoid race condition on set/get env. params
+    bpm::AutoMutex<bpm::Mutex> guard(this->srv_task_->lock());
+    ::memcpy(&this->config_.actual_ep_, &ep, sizeof(CSPI_ENVPARAMS));      
+  }    
+  //- update hw status: cspi health info
+  this->update_libera_health_info();
+#endif // ! _SIMULATION_
+
+  //- update hw status: system info
+#if defined(_EMBEDDED_DEVICE_)
+  //- we update the system sensors if running embedded - no system sensors while running externally 
+  //- in order to avoid to have tens of instances (running on the same host) accessing /proc !!!!
+  this->update_libera_sensors_info();     
+#endif // _EMBEDDED_DEVICE_       
+
+#if ! defined(_SIMULATION_) && ! defined(_EMBEDDED_DEVICE_)
+  //- get DD cache status
+  int val;
+  rc =::server_getparam(protocol::SERVER_CACHE_LOCK, &val);
+  HANDLE_CSPI_ERROR(rc, "server_getparam", "BPM::srv_message_handler");
+  this->dd_buffer_frozen_ = val ? true : false;
+#endif // !_SIMULATION_ && ! _EMBEDDED_DEVICE_
+
+#if ! defined(_SIMULATION_)
+  dt_ms = t.elapsed_msec();
+  BPM_DEBUG_STREAM << "BPM::srv_periodic_job::env. data update took " << dt_ms << " ms"<< std::endl;
+#endif  // ! _SIMULATION_
+}
+
+// ============================================================================
+// BPM::update_fa_data_cache
+// ============================================================================
+void BPM::update_fa_data_cache () 
+    throw (Tango::DevFailed)
+{     
+  if (!this->fa_data_rd_.pbuf || !this->fa_data_rd_.size || !this->fa_data_rd_.count)
+    return;
+
+  int rc = ::cspi_getenvparam_fa(this->srv_task_->henv_, 
+                                 this->fa_data_rd_.offset, 
+                                 this->fa_data_rd_.pbuf, 
+                                 this->fa_data_rd_.size, 
+                                 this->fa_data_rd_.count);
+  HANDLE_CSPI_ERROR_FROM_STATIC_MEMBER(rc, "cspi_getenvparam_fa", "BPM::srv_message_handler");
+        
+  {
+    bpm::AutoMutex<bpm::Mutex> guard(this->fa_data_lock_); 
+    this->fa_data_cp_ = this->fa_data_rd_;
+  }
+}
+
+// ============================================================================
+// BPM::dd_message_handler
+// ============================================================================
+void BPM::dd_message_handler (const bpm::Message& _msg)
+{
+  //- reinterpret user data
+  BPM *instance = reinterpret_cast<BPM*>(_msg.user_data());
+  if (instance == 0 || instance != BPM::singleton)
+    return;
+
+  //- handle msg
+  switch(_msg.type())
+  {
+    //- TASK_INIT ----------------------
+    case TASK_INIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->dd_task_->lock());
+        instance->dd_task_->enable_timeout_msg(false);
+        if (instance->configuration().dd_enabled()) 
+          instance->dd_task_connect();
+      }
+      break;
+    //- TASK_EXIT ----------------------
+    case TASK_EXIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->dd_task_->lock());
+        if (instance->configuration().dd_enabled()) 
+          instance->dd_task_disconnect();
+      }
+      break;
+    //- TASK_PERIODIC -------------------
+    case TASK_PERIODIC:
+      {
+        //- cspi bug: crash if try to call a cspi function without a valid connection so...
+        //- ... be sure we are properly connected 
+        if (! instance->dd_task_->connected_)
+          return;
+        if (instance->configuration().dd_enabled())
+        {
+          if (instance->configuration().external_trigger_enabled())
+            instance->watch_dog();
+          else             
+            instance->read_dd();
+        }
+      }
+      break;
+    //- CSPI_TRIGGET --------------------- 
+    case CSPI_TRIGGET:
+      {
+        instance->read_dd();
+      }
+      break;
+    //- DD_DECIMATION_CHANGED_MSG -------- 
+    case kDD_DECIM_CHANGED_MSG:
+      {
+        int flags = CSPI_CON_DEC;
+        if (::cspi_setconparam(instance->dd_task_->hcon_, 
+                               reinterpret_cast<CSPI_CONPARAMS*>(&instance->config_.cp_dd_), flags))
+        {
+          Tango::Except::throw_exception(_CPTC("BPM configuration failed"),
+                                        _CPTC("cspi_setconparam failed"),
+                                        _CPTC("BPM::dd_message_handler"));
+        }
+      }
+      break;
+    //- SRC_CHANGED_MSG ------------------  
+    case kSRC_CHANGED_MSG:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->dd_task_->lock());
+        if (instance->configuration().dd_enabled())
+        {
+          instance->dd_task_connect();
+        }
+        else
+        {
+          instance->dd_task_disconnect();
+          if (instance->last_dd_data_)
+          {
+            instance->last_dd_data_->release();
+            instance->last_dd_data_ = 0;
+          }
+        }
+      }
+      break;
+#if ! defined(_EMBEDDED_DEVICE_)
+    //- DD_CACHE_STATUS_MSG --------------
+    case kDD_CACHE_STATUS_MSG:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->dd_task_->lock());
+        //- this could be written a better way but... 
+        instance->dd_task_disconnect();
+        instance->dd_task_connect();
+      }
+      break;
+#endif
+    //- REMAINING CPSI EVENTS ------------
+    default:
+      break;
+  }
+}
+
+// ============================================================================
+// BPM::sa_message_handler
+// ============================================================================
+void BPM::sa_message_handler (const bpm::Message& _msg)
+{
+  static int local_sa_evt_counter;
+
+  //- reinterpret user data
+  BPM *instance = reinterpret_cast<BPM*>(_msg.user_data());
+  if (instance == 0 || instance != BPM::singleton)
+    return;
+
+  //- handle msg
+  switch(_msg.type())
+  {
+    //- TASK_INIT ----------------------
+    case TASK_INIT:
+      { 
+        //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->sa_task_->lock());
+        instance->sa_task_->enable_timeout_msg(false);
+        if (instance->configuration().sa_enabled()) 
+          instance->sa_task_connect();
+        //- init our local SA event/reading counter
+        local_sa_evt_counter = 0;
+      }
+      break;
+    //- TASK_EXIT ----------------------
+    case TASK_EXIT:
+      { 
+        //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->sa_task_->lock());
+        if (instance->configuration().sa_enabled()) 
+          instance->sa_task_disconnect();
+      }
+      break;
+    //- TASK_PERIODIC -------------------
+    case TASK_PERIODIC:
+      {
+        //- cspi bug: crash if try to call a cspi function without a valid connection so...
+        //- ... be sure we are properly connected 
+        if (! instance->sa_task_->connected_)
+          return;
+#if defined(_USE_SA_EVENTS_)
+# if ! defined(_EMBEDDED_DEVICE_) &&  ! defined(_SIMULATION_)
+        instance->watch_dog();
+# endif
+#else
+        if (instance->configuration().sa_enabled())
+          instance->read_sa();
+#endif
+      }
+      break;
+#if defined(_USE_SA_EVENTS_)
+    //- SA EVENT -------------------------
+    case CSPI_SA:
+      {
+        if (instance->configuration().sa_enabled())
+            instance->read_sa(); 
+        //- inc. SA event counter
+        local_sa_evt_counter++;
+      }
+      break;
+#endif 
+    //- kSRC_CHANGED_MSG -----------------
+    case kSRC_CHANGED_MSG:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->sa_task_->lock());
+        if (instance->configuration().sa_enabled())
+        {
+          instance->sa_task_connect();
+        }
+        else
+        {
+          instance->sa_task_disconnect();
+          if (instance->last_sa_data_)
+          {
+            instance->last_sa_data_->release();
+            instance->last_sa_data_ = 0;
+          }
+        }
+      }
+      break;
+    case kALGO_CHANGED_MSG:
+      {
+        instance->get_sa_history().reset();
+      }
+      break;
+    //- REMAINING CPSI EVENTS ------------
+    default:
+      break;  
+  } 
+}
+
+// ============================================================================
+// BPM::adc_message_handler
+// ============================================================================
+void BPM::adc_message_handler (const bpm::Message& _msg)
+{
+  //- reinterpret user data
+  BPM *instance = reinterpret_cast<BPM*>(_msg.user_data());
+  if (instance == 0 || instance != BPM::singleton)
+    return;
+
+  //- handle msg
+  switch(_msg.type())
+  {
+    //- TASK_INIT ----------------------
+    case TASK_INIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->adc_task_->lock());
+        instance->adc_task_->enable_timeout_msg(false);
+        if (instance->configuration().adc_enabled()) 
+          instance->adc_task_connect();
+      }
+      break;
+    //- TASK_EXIT ----------------------
+    case TASK_EXIT:
+      { //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->adc_task_->lock());
+        if (instance->configuration().adc_enabled()) 
+          instance->adc_task_disconnect();
+      }
+      break;
+    //- TASK_PERIODIC -------------------
+    case TASK_PERIODIC:
+      {
+        //- cspi bug: crash if try to call a cspi function without a valid connection so...
+        //- ... be sure we are properly connected 
+        if (! instance->adc_task_->connected_)
+          return;
+        //- read data or watch dog activity     
+        if (instance->configuration().adc_enabled())
+        {
+          if (instance->configuration().external_trigger_enabled())
+            instance->watch_dog();
+          else             
+            instance->read_adc();
+        }
+      }  
+      break;
+    //- kSRC_CHANGED_MSG -----------------
+    case kSRC_CHANGED_MSG:  
+      { 
+        //- critical section
+        bpm::AutoMutex<bpm::Mutex> guard(instance->adc_task_->lock());
+        if (instance->configuration().adc_enabled())
+          instance->adc_task_connect();
+        else
+          instance->adc_task_disconnect();
+      }
+      break;
+    //- CSPI_TRIGGET --------------------- 
+    case CSPI_TRIGGET:
+      {
+        if (instance->configuration().adc_enabled())
+          instance->read_adc();
+      }
+      break;
+    //- REMAINING CPSI EVENTS ------------
+    default:
+      break;
+  }
+}
+
+// ============================================================================
+// BPM::update_libera_health_info
+// ============================================================================
+void BPM::update_libera_health_info ()
+{
+  this->hw_status_.temp = static_cast<short>(this->config_.actual_ep_.health.temp);
+  this->hw_status_.fan_1_speed = static_cast<short>(this->config_.actual_ep_.health.fan[0]);
+  this->hw_status_.fan_2_speed = static_cast<short>(this->config_.actual_ep_.health.fan[1]);
+  this->hw_status_.sc_ppl_lock_status = this->config_.actual_ep_.pll.sc ? true : false;
+  this->hw_status_.mc_ppl_lock_status = this->config_.actual_ep_.pll.mc ? true : false;
+} 
+
+// ============================================================================
+// BPM::update_libera_sensors_info
+// ============================================================================
+#if defined(_EMBEDDED_DEVICE_)
+void BPM::update_libera_sensors_info ()
+{
+  this->sensors_.update_all();
+  this->hw_status_.memory_free = this->sensors_.memory_free;
+  this->hw_status_.ram_fs_usage = this->sensors_.ram_fs_usage;
+  this->hw_status_.uptime = this->sensors_.uptime;
+  this->hw_status_.cpu_usage = this->sensors_.cpu_usage; 
+}
+#endif      
+} // namespace bpm
diff --git a/src/BPM.h b/src/BPM.h
new file mode 100644
index 0000000000000000000000000000000000000000..87094749dbc8b0382816a8ca7cddc9de9877d21f
--- /dev/null
+++ b/src/BPM.h
@@ -0,0 +1,972 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr 
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_H_
+#define _BPM_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "BPMConfig.h"
+#include "BPMData.h"
+#include "BPMBuffer.h"
+#include "BPMSensors.h"
+#include "LiberaEvents.h"
+#include "threading/Task.h"
+
+// ============================================================================
+// DEFINEs
+// ============================================================================
+#define kNO_DATA_MSG "NO_DATA"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_TIMEOUT_MS 1000
+//-----------------------------------------------------------------------------
+#define kDEFAULT_CON_FLAGS \
+  CSPI_CON_MODE | CSPI_CON_HANDLER | CSPI_CON_USERDATA | CSPI_CON_EVENTMASK
+//-----------------------------------------------------------------------------
+#define kDEFAULT_DD_CON_FLAGS kDEFAULT_CON_FLAGS | CSPI_CON_DEC
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+//! BPM abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class BPM  : public Tango::LogAdapter
+{
+public:
+  /**
+   * BPM states
+   */
+  typedef enum
+  {
+    BPM_RUNNING,
+    BPM_FAULT,
+    BPM_UNKNOWN
+  } BPMState;
+
+  typedef int InterlockFlags;
+  
+	/**
+	 * Interlock reasons
+	 */
+	enum 
+	{
+	  /** IL: position X out of limit. */
+    INTERLOCK_X =    (1<<0),
+    /** IL: position Y out of limit. */
+    INTERLOCK_Z =    (1<<1),
+    /** IL: Attenuators set higher than predefined value. */
+    INTERLOCK_ATTN = (1<<2),
+    /** IL: ADC Overflow  (filtered). */
+    INTERLOCK_ADCF = (1<<3),
+    /** IL: ADC Overflow  (not filtered). */
+    INTERLOCK_ADC =  (1<<4)
+  };
+       
+  /**
+   * BPM software status (connection)
+   */
+  typedef struct BPMSwStatus
+  {
+  	BPMState state;
+  	std::string status;
+  } BPMSwStatus;
+
+  /**
+   * BPM hardware status (Health & PLL info)
+   */
+  typedef struct BPMHwStatus
+  {
+    //- 
+    short temp;
+    short fan_1_speed;
+    short fan_2_speed;
+    bool sc_ppl_lock_status;
+    bool mc_ppl_lock_status;
+    InterlockFlags intl_flags; 
+    long memory_free;  
+    long ram_fs_usage;
+    long uptime; 
+    long cpu_usage;
+    //- ctor
+    BPMHwStatus () 
+      : temp (0), 
+        fan_1_speed (0), 
+        fan_2_speed (0), 
+        sc_ppl_lock_status(false),
+        mc_ppl_lock_status(false),
+        intl_flags (0),
+        memory_free (0),  
+        ram_fs_usage (0), 
+        uptime (0), 
+        cpu_usage (0)
+    {
+      //- noop ctor
+    }
+    //- operator=
+    BPMHwStatus& operator= (const BPMHwStatus& _src) 
+    {
+      ::memcpy(this, &_src, sizeof(BPMHwStatus));
+      return *this;
+    }  
+  } BPMHwStatus;
+  
+  /**
+   * FA env. data struct
+   */
+  typedef struct FAData
+  {
+public:
+    //- map "cspi_set/getenvparam_fa" parameters
+    //-----------------------------------------
+    //- offset from the beginning of the FA config. bloc 
+    size_t offset; 
+    //- pointer to data to be written/read
+    char * pbuf;
+    //- size of a data element
+    size_t size;
+    //- number of data elements
+    size_t count;
+    //-default ctor
+    FAData () 
+      : offset(0), pbuf(0), size(0), count(0)
+    {
+      //- noop ctor
+    }
+    //- ctor
+    FAData (size_t _off, void * _pbuf, size_t _size, size_t _count) 
+      : offset(_off), pbuf(reinterpret_cast<char*>(_pbuf)), size(_size), count(_count)
+    {
+      //- noop ctor
+    }
+    //- ctor
+    FAData (size_t _off, size_t _size, size_t _count) 
+    {
+      this->allocate(_off, _size, _count);
+    }
+    //- copy ctor
+    FAData (const FAData& _src)
+      : offset(0), pbuf(0), size(0), count(0)
+    {
+      *this = _src;
+    }
+    //- dtor
+    ~FAData () 
+    {
+      delete[] this->pbuf;
+    }
+    //- operator= (this is a deep copy)
+    FAData& operator= (const FAData& _src) 
+    {
+      if (&_src == this)
+        return *this;
+      try
+      {
+        size_t src_size = _src.size * _src.count;
+        size_t dest_size = this->size * this->count;
+        this->offset = _src.offset;
+        this->size = _src.size;
+        this->count = _src.count;
+        if ((!this->pbuf && _src.pbuf) || (src_size != dest_size) || (!_src.pbuf && this->pbuf))
+        {
+          if (this->pbuf)
+          {
+            delete[] this->pbuf;
+            this->pbuf = 0;
+          }
+          if (!_src.pbuf || !src_size) 
+          {
+            return *this;
+          }
+          this->pbuf = new char[src_size];
+          if (!this->pbuf) 
+            throw std::bad_alloc();
+        }
+        
+      }
+      catch (const std::bad_alloc&)
+      {
+        Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                        _CPTC ("memory allocation failed"),
+                                        _CPTC ("FAData::operator="));
+      }
+      ::memcpy(this->pbuf, _src.pbuf, _src.size * _src.count);
+      return *this;
+    }
+    //- (re)allocate the underlying memory space
+    void allocate (size_t _off, size_t _size, size_t _count) 
+    {
+      this->offset = _off;
+      this->size  = _size;
+      this->count = _count;
+      if (this->pbuf)
+      {
+        delete[] this->pbuf;
+        this->pbuf = 0;
+      }
+      this->pbuf = new char[this->size * this->count];
+      ::memset(this->pbuf, 0, this->size * this->count);
+    }
+  private:
+    friend class BPM;
+    //- copy from full fa data set (means src.offset == 0)
+    void copy_from_full_fa_data_set (FAData& _src) 
+    {
+      if (&_src == this)
+        return;
+      try
+      {
+        if (!this->pbuf)
+        {
+          this->pbuf = new char[this->size * this->count];
+          if (!this->pbuf) 
+            throw std::bad_alloc();
+        }
+      }
+      catch (const std::bad_alloc&)
+      {
+        Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                        _CPTC ("memory allocation failed"),
+                                        _CPTC ("FAData::copy"));
+      }
+      ::memcpy(this->pbuf, _src.pbuf + this->offset, this->size * this->count);
+    }  
+    //- dump
+    void dump ()
+    {
+      std::cout << "FAData::pbuf.....0x" << std::hex << (long)pbuf << std::dec << std::endl; 
+      std::cout << "FAData::offset..." << offset << std::endl;
+      std::cout << "FAData::size....." << size << std::endl;
+      std::cout << "FAData::count...." << count << std::endl;
+    }
+  } FAData;
+  
+  /**
+   * Time settings
+   */
+   typedef struct TimeSettings
+   { 
+      //- members
+      FPDataType mt; 
+      FPDataType st; 
+      long tp;
+      //- ctor
+      TimeSettings ()
+        : mt (0), st (0), tp (0)
+      {
+        //- noop 
+      }
+      //- copy ctor
+      TimeSettings (const TimeSettings& ts)
+        : mt (ts.mt), st (ts.st), tp (ts.tp)
+      {
+        //- noop 
+      }
+      //- dtor
+      ~TimeSettings ()
+      {
+        //- noop 
+      }
+      //- operator=
+      TimeSettings& operator= (const TimeSettings& ts)
+      {
+        if (&ts == this)
+          return *this;
+        ::memcpy(this, &ts, sizeof(TimeSettings));
+        return *this;
+      }
+   } TimeSettings;
+  
+   /**
+    * Env. params struct for Libera (re)configuration
+    */
+   typedef struct EnvParamsSpecifier
+   {
+     //- actual env. params (values)
+     CSPI_ENVPARAMS ep;
+     //- env. params flags (what to change selector)
+     int ep_flags;
+     //- default ctor
+     EnvParamsSpecifier ()
+     {
+       ::memset(this, 0, sizeof(EnvParamsSpecifier));   
+     }
+     //- explicit ctor
+     EnvParamsSpecifier (const CSPI_ENVPARAMS& ep, int flags)
+      : ep_flags(flags)
+     {
+       ::memcpy(&this->ep, &ep, sizeof(CSPI_ENVPARAMS));
+     }
+     //- copy ctor
+     EnvParamsSpecifier (const EnvParamsSpecifier& src)
+     {
+       *this = src;   
+     }
+     //- operator=
+     EnvParamsSpecifier& operator= (const EnvParamsSpecifier& src)
+     {
+       if (&src == this)
+         return *this;
+       ::memcpy(this, &src, sizeof(EnvParamsSpecifier));   
+       return *this;
+     }
+   } EnvParamsSpecifier;
+   
+  /**
+   * Constructor (no op. - see init) 
+   *
+   * \param host_device The device in which this instance runs (for logging purpose)
+   */
+  BPM (Tango::DeviceImpl * host_device);
+
+  /**
+   * Release resources.
+   */
+  virtual ~BPM (void);
+
+  /**
+   * BPM initialization
+   * \param initial_config The initial BPM configuration
+   */
+  virtual void init (const BPMConfig & initial_config) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the current BPM configuration.
+   * \return The current BPM configuration
+   */
+  const BPMConfig & configuration (void) const;
+
+  /**
+   * Reconfigures the BPM.
+   *
+   * \param config The new BPM configuration
+   */
+  void reconfigure (const BPMConfig & config) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the BPM "software" status.
+   */
+  void get_sw_status (BPMSwStatus &) const;
+  
+  /**
+   * Returns the BPM "hardware" status.
+   */
+  void get_hw_status (BPMHwStatus &) const;
+
+  /**
+   * Unfreezes the on demand data buffer
+   */
+  void unfreeze_dd_buffer (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the cache status
+   */
+  bool is_dd_buffer_freezing_enabled (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns whether or not the cache is currently frozen
+   */
+  bool is_dd_buffer_frozen (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the most recently acquired DD data
+   */
+  void get_dd_data (DDData & dest, bool force_update = false)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Returns the most recently acquired ADC data
+   */
+  void get_adc_data (ADCData & dest, bool force_update = false)
+    throw (Tango::DevFailed);
+    
+   /**
+   * Returns the most recently acquired SA data
+   */
+  void get_sa_data (SAData & dest, bool force_update = false)
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the most recently acquired PM data
+   */
+  void get_pm_data (DDData & dest, bool force_update = false)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Returns the SA history
+   */
+  SAHistory & get_sa_history (void);
+
+  /**
+   * Returns the current trigger counter value
+   */
+  long trigger_counter (void) const;
+
+  /**
+   * Resets the trigger counter
+   */
+  void reset_trigger_counter (void);
+
+  /**
+   * Return the PM status
+   */
+  bool pm_notified (void) const;
+
+  /**
+   * Return the PM event counter
+   */
+  short pm_event_counter (void) const;
+  
+  /**
+   * Resets the PM notification flag
+   */
+  void reset_pm_notification (void);
+  
+  /**
+   * Resets the Interlock notification flags
+   */
+  void reset_interlock_notification (void);
+  
+  /**
+   * Set the Libera interlock config (and only this part of the configuration) 
+   */
+  void set_interlock_configuration (const BPMConfig & new_config) 
+    throw (Tango::DevFailed);
+  
+  /**
+   * Synchronizes the Libera internal clock on next trigger  
+   */
+  void set_time_on_next_trigger (const TimeSettings& ts) 
+    throw (Tango::DevFailed);
+   
+  /**
+   * Reads "count x size" bytes from FA data block 
+   */
+   void read_fa_data (FAData & fa_data_) 
+    throw (Tango::DevFailed);
+   
+  /**
+   * Writes "count x size" bytes to FA data block 
+   */
+   void write_fa_data(const FAData & _fa_data) 
+    throw (Tango::DevFailed);
+   
+  /**
+   * Saves the DSC parameters 
+   */
+   void save_dsc_parameters (void) 
+    throw (Tango::DevFailed);
+   
+  /**
+   * Returns the incoherence 
+   */
+   bpm::FPDataType get_incoherence (void) 
+    throw (Tango::DevFailed);
+
+private:
+  /**
+   * BPM initialization
+   * \param initial_config The initial BPM configuration
+   */
+  virtual void init_i (const BPMConfig & initial_config) 
+    throw (Tango::DevFailed);
+
+   /**
+   * Close the connection then release allocated resources
+   */
+  void close_i (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * BPM task init: main task (service)
+   */
+  void init_srv_task (void)
+    throw (Tango::DevFailed);
+    
+  /**
+   * BPM task close: main task (service)
+   */
+  void close_srv_task (void)
+    throw (Tango::DevFailed);
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  /**
+   * Connection to Libera generic server (impl. retry mechanism)
+   */
+  void connect_to_generic_server (const std::string& caller)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Disconnection from Libera generic server
+   */
+  void disconnect_from_generic_server (const std::string& caller)
+    throw (Tango::DevFailed);
+#endif
+
+   /**
+   * BPM task init: DD
+   */
+  void dd_task_connect (void)
+       
+    throw (Tango::DevFailed);
+  /**
+   * BPM task close: DD
+   */
+  void dd_task_disconnect (void)
+       
+    throw (Tango::DevFailed);
+       
+  /**
+   * BPM task init: SA
+   */
+  void sa_task_connect (void)
+       
+    throw (Tango::DevFailed);
+  /**
+   * BPM task close: SA
+   */
+  void sa_task_disconnect (void)
+       
+    throw (Tango::DevFailed);
+
+  /**
+   * BPM task init: ADC
+   */
+  void adc_task_connect (void)
+       
+    throw (Tango::DevFailed);
+  /**
+   * BPM task close: ADC
+   */
+  void adc_task_disconnect (void)
+       
+    throw (Tango::DevFailed);
+
+  /**
+   * Enable CSPI notifications for a given connection
+   */
+  void enable_notifications (int cspi_events_mask)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Disable all CSPI notifications for all connections
+   */
+  void disable_notifications (void)
+    throw (Tango::DevFailed);
+  
+  /**
+   * Enables CSPI post mortem notifications
+   */
+  void enable_pm_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disables CSPI post mortem notifications
+   */
+  void disable_pm_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Enables CSPI interlock notifications
+   */
+  void enable_interlock_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disables CSPI interlock notifications
+   */
+  void disable_interlock_notifications (void) 
+    throw (Tango::DevFailed);
+    
+  /**
+   * Enables CSPI ADC notifications
+   */
+  void enable_adc_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disables CSPI ADC notifications
+   */
+  void disable_adc_notifications (void) 
+    throw (Tango::DevFailed);
+    
+  /**
+   * Enables CSPI SA notifications
+   */
+  void enable_sa_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disables CSPI SA notifications
+   */
+  void disable_sa_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Enables CSPI DD notifications
+   */
+  void enable_dd_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disables CSPI DD notifications
+   */
+  void disable_dd_notifications (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Disable DD buffer freezing
+   */
+  void disable_dd_buffer_freezing (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Read DD data source
+   */
+  void read_dd (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Read SA data source
+   */
+  void read_sa (void) 
+    throw (Tango::DevFailed);
+    
+  /**
+   * Read ADC data source
+   */
+  void read_adc (void) 
+    throw (Tango::DevFailed);
+    
+  /**
+   * Read PM data source
+   */
+  void read_pm (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Watch dog 
+   */
+  void watch_dog (void) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns true if this instance is correctly initialized, returns false 
+   * or throws an exception otherwise. 
+   */
+  bool initialized (void) const;
+  
+  /**
+   * Get the current env parmeters  
+   */
+  void get_env_parameters (CSPIHENV he, CSPI_ENVPARAMS & ep, size_t mask = kALL_PARAMS, size_t retries = 2)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Set the con. part of the configuration from hardware  
+   */
+  void set_con_parameters (CSPIHCON hc, 
+                           CSPI_CONPARAMS * cp, 
+                           int flags = kDEFAULT_CON_FLAGS) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Set the con. part of the configuration from hardware  
+   */
+  void set_con_parameters (CSPIHCON hc, 
+                           CSPI_CONPARAMS_EBPP * cp, 
+                           int flags = kDEFAULT_DD_CON_FLAGS) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Get the con. part of the configuration from hardware  
+   */
+  void get_con_parameters (CSPIHCON hc, CSPI_CONPARAMS * cp) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Get the con. part of the configuration from hardware  
+   */
+  void get_con_parameters (CSPIHCON hc, CSPI_CONPARAMS_EBPP * cp) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Updates health sensors info  
+   */
+  void update_libera_health_info ();
+  
+  /**
+   * Updates Libera sensors info  
+   */
+#if defined(_EMBEDDED_DEVICE_)
+  void update_libera_sensors_info ();
+#endif
+
+  /**
+   * The srv task periodic job: main jobs
+   */
+  void srv_periodic_job () 
+    throw (Tango::DevFailed);
+
+  /**
+   * The srv task periodic job: fat data chache update
+   */
+  void update_fa_data_cache () 
+      throw (Tango::DevFailed);
+
+  /**
+   * The BPM configuration.
+   */
+  BPMConfig config_;
+  
+  /**
+   * BPM internal state
+   */
+  BPMState state_;
+
+  /**
+   * DD data buffer (for read op).
+   */
+  DDRawBuffer dd_raw_buffer_;
+
+  /**
+   * Most recent DD data
+   */
+  DDData * last_dd_data_;
+  bool last_dd_data_updated_;
+  
+  /**
+   * Preallocated DDData (optimization)
+   */
+  DDData * dd_data_1_;
+  DDData * dd_data_2_;
+
+  /**
+   * ADC data buffer (for read op).
+   */
+  ADCRawBuffer adc_raw_buffer_;
+  
+  /**
+   * Most recent ADC data
+   */
+  ADCData * last_adc_data_;
+  bool last_adc_data_updated_;
+
+  /**
+   * Preallocated ADCData (optimization)
+   */
+  ADCData * adc_data_1_;
+  ADCData * adc_data_2_;
+  
+  /**
+   * Most recent SA data
+   */
+  SAData * last_sa_data_; 
+  bool last_sa_data_updated_;
+
+  /**
+   * Preallocated SAData (optimization)
+   */
+  SAData * sa_data_1_;
+  SAData * sa_data_2_;
+  
+  /**
+   * SA data history buffer
+   */
+  SAHistory sa_history_; 
+  
+  /**
+   * Most recent PM data
+   */
+  DDData * last_pm_data_;
+  bool last_pm_data_updated_;
+  
+  /**
+   * Trigger counter
+   */
+  long trigger_counter_;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  /**
+   * Connection flag
+   */
+  bool connected_;
+#endif
+
+  /**
+   * DD cache status
+   */
+  bool dd_buffer_frozen_ ;
+
+  /**
+   * ther service task (handles BPM config, PM, ...)
+   */
+  bpm::Task * srv_task_;
+
+  /**
+   * the DD task
+   */
+  bpm::Task * dd_task_;
+
+  /**
+   * the SA task
+   */
+  bpm::Task * sa_task_;
+
+  /**
+   * the ADC task
+   */
+  bpm::Task * adc_task_;
+  
+  /**
+   * The host TANGO device
+   */
+  Tango::DeviceImpl * host_device_;
+
+  /**
+   * PM status
+   */
+  bool pm_notified_;
+  short pm_event_counter_;
+   
+  /**
+   * HW status
+   */
+   BPMHwStatus hw_status_;
+   
+  /**
+   * FA Data for FA I/O operations
+   */
+   FAData fa_data_rd_;
+   FAData fa_data_cp_;
+   bpm::Timer fa_data_timer_;
+   bpm::Mutex fa_data_lock_;
+
+  /**
+   * Sensors
+   */
+   BPMSensors sensors_;
+   
+  /**
+   * Num of SA samples since last stats processing
+   */
+	size_t num_sa_samples_since_last_stat_proc_;
+
+  /**
+   * Some bools used to avoid double trig. notifications (one for DD & one for ADC)
+   */
+  bool dd_requires_trigger_notifications_;
+  bool adc_requires_trigger_notifications_;
+
+  /**
+   * The Libera evt manager
+   */
+#if defined(_EMBEDDED_DEVICE_)
+  LiberaEventsManager * evts_man_;
+#endif
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  /**
+   * Returns the current cspi events mask
+   */
+  int current_cspi_events_mask (void) const;
+#endif
+
+  //--------------------------------------------------------
+  //- static members
+  //--------------------------------------------------------
+  
+  /**
+   * Async. notification callbacks
+   */
+  static int libera_event_callback (CSPI_EVENT * evt);
+  
+  /**
+   * "Main" message handler
+   */
+  static void srv_message_handler (const bpm::Message& _msg);
+
+   /**
+   * "DD" message handler
+   */
+  static void dd_message_handler (const bpm::Message& _msg);
+
+   /**
+   * "SA" message handler
+   */
+  static void sa_message_handler (const bpm::Message& _msg);
+
+   /**
+   * "ADC" message handler
+   */
+  static void adc_message_handler (const bpm::Message& _msg);
+  
+  /**
+   * BPM singleton
+   */
+  static BPM * singleton;
+
+  /**
+   * BPM lock
+   */
+  static bpm::Mutex lock;
+
+  /**
+   * Closed flag
+   */
+  static bool closed;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  BPM & operator= (const BPM &);
+  BPM (const BPM &);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "BPM.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_H_
diff --git a/src/BPM.i b/src/BPM.i
new file mode 100644
index 0000000000000000000000000000000000000000..185e5ab9a850e32dbafa6c3ec4d6fb0b9dbd12a2
--- /dev/null
+++ b/src/BPM.i
@@ -0,0 +1,149 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// BPM::configuration
+// ============================================================================
+INLINE_IMPL const BPMConfig & BPM::configuration (void) const
+{
+  //- return current configuration to caller
+  //- since the local storage (i.e. config_ member) is updated each time
+  //- BPM::configure is called we can simply return it.
+  //- no need to request it from hardware
+  return this->config_;
+}
+
+// ============================================================================
+// BPM::initialized
+// ============================================================================
+INLINE_IMPL bool BPM::initialized (void) const
+{
+  return this->srv_task_ != 0;
+}
+
+#if ! defined(_EMBEDDED_DEVICE_)
+// ============================================================================
+// BPM::current_cspi_events_mask
+// ============================================================================
+INLINE_IMPL int BPM::current_cspi_events_mask (void) const
+{
+  return reinterpret_cast<const CSPI_CONPARAMS&>(this->config_.cp_srv_).event_mask;
+}
+#endif
+
+// ============================================================================
+// BPM::get_state
+// ============================================================================
+INLINE_IMPL void BPM::get_sw_status (BPMSwStatus& sw_status_) const
+{
+  sw_status_.state = this->state_;
+  
+  if (! this->initialized())
+  {
+#if ! defined(_EMBEDDED_DEVICE_)
+    sw_status_.status = std::string("BPM initialization failed [no active connection to the Libera - unreachable or embedded generic server down]"); 
+#else
+    sw_status_.status = std::string("BPM initialization failed [Libera software error]");
+#endif
+  }
+  else
+  {
+	  switch (sw_status_.state) 
+    {
+      case BPM::BPM_RUNNING:
+        sw_status_.status = "BPM is up and ready [running]";
+        break;
+      case BPM::BPM_FAULT:
+#if ! defined(_EMBEDDED_DEVICE_)
+        sw_status_.status = std::string("CSPI request failed [connection lost or Libera internal error - see device log for details]\n");
+        sw_status_.status += std::string("Be sure the Libera is reachable and all embedded services are running then execute the <Init> command on the device");
+#else
+        sw_status_.status = std::string("CSPI request failed  [Libera internal error - see device log for details]\n");
+        sw_status_.status += std::string("Be sure all Libera embedded services are running then execute the <Init> command on the device");
+#endif
+        break;
+      default:
+        sw_status_.status = std::string("unknown state");
+        break;
+    }
+  }
+}
+
+// ============================================================================
+// BPM::pm_notified
+// ============================================================================
+INLINE_IMPL bool BPM::pm_notified (void) const
+{
+  return this->pm_notified_;
+}
+
+// ============================================================================
+// BPM::pm_event_counter
+// ============================================================================
+INLINE_IMPL short BPM::pm_event_counter (void) const
+{
+  return this->pm_event_counter_;
+}
+
+// ============================================================================
+// BPM::trigger_counter
+// ============================================================================
+INLINE_IMPL long BPM::trigger_counter (void) const
+{
+  return this->trigger_counter_;
+}
+
+// ============================================================================
+// BPM::reset_trigger_counter
+// ============================================================================
+INLINE_IMPL void BPM::reset_trigger_counter (void)
+{
+  this->trigger_counter_ = 0;
+}
+
+// ============================================================================
+// BPM::get_sa_history
+// ============================================================================
+INLINE_IMPL SAHistory & BPM::get_sa_history (void)
+{
+  return this->sa_history_;
+}
+
+// ============================================================================
+// BPM::get_hw_status
+// ============================================================================
+INLINE_IMPL void BPM::get_hw_status (BPMHwStatus& _dest) const
+{
+  _dest = this->hw_status_;
+}
+
+} //- namespace bpm
diff --git a/src/BPMBuffer.cpp b/src/BPMBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dba44c10439fabee859d4307fd027cb06f150006
--- /dev/null
+++ b/src/BPMBuffer.cpp
@@ -0,0 +1,528 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_BUFFER_CPP_
+#define _BPM_BUFFER_CPP_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "BPMBuffer.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "BPMBuffer.i"
+#endif // __INLINE_IMPL__
+
+namespace bpm {
+
+// ============================================================================
+// Class : Buffer
+// ============================================================================
+
+// ============================================================================
+// Buffer::Buffer
+// ============================================================================
+template <typename T>
+Buffer<T>::Buffer (size_t _depth) throw (Tango::DevFailed) 
+ : base_(0), depth_(0)
+{
+  //- allocate the buffer 
+  if (_depth) 
+  { 
+    this->depth(_depth);
+    this->clear();
+  }
+}
+
+// ============================================================================
+// Buffer::Buffer
+// ============================================================================
+template <typename T>
+Buffer<T>::Buffer(size_t _depth, T* _base) throw (Tango::DevFailed) 
+ : base_(0), depth_(0)
+{
+  //- allocate the buffer 
+  this->depth(_depth);
+  //- copy from source to destination using <Buffer::operator=>.
+  *this = _base;
+}
+
+// ============================================================================
+// Buffer::Buffer
+// ============================================================================
+template <typename T> 
+Buffer<T>::Buffer(const Buffer<T>& _src) throw (Tango::DevFailed)
+  : base_(0), depth_(0), length_(0)
+{
+  //- allocate the buffer 
+  this->depth(_src.depth());
+  //- copy from source to destination using <Buffer::operator=>.
+  *this = _src;
+}
+
+// ============================================================================
+// Buffer::~Buffer
+// ============================================================================
+template <typename T> 
+Buffer<T>::~Buffer(void)
+{
+  if (this->base_)
+  { 
+    delete[] this->base_;
+    this->base_ = 0;
+  }
+}
+
+// ============================================================================
+// Buffer::depth
+// ============================================================================
+template <typename T>
+void Buffer<T>::depth(size_t _depth)
+  throw (Tango::DevFailed)
+{
+  //- might have nothing to do
+  if (_depth == this->depth_)
+    return;
+    
+  //- release existing buffer
+  if (this->base_)
+  {
+    delete[] this->base_;
+    this->base_ = 0;
+    this->depth_ = 0;
+  }
+  
+  //- allocate the buffer 
+  this->base_ = new T[_depth];
+  if (this->base_ == 0)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"), 
+                                    _CPTC ("memory allocation failed"), 
+                                    _CPTC ("Buffer<T>::Buffer"));
+  }
+  
+  //- set buffer depth.
+  this->depth_ = _depth;
+  
+  //- no element
+  this->length_ = 0;
+}
+
+// ============================================================================
+// Buffer::depth
+// ============================================================================
+template <typename T>
+INLINE_IMPL void Buffer<T>::force_length (size_t _len)
+{
+  this->length_ = (_len > this->depth_) ? this->depth_ : _len;
+}
+
+// ============================================================================
+// Buffer::clear
+// ============================================================================
+template <typename T>
+INLINE_IMPL void Buffer<T>::clear (void)
+{
+  ::memset(this->base_, 0,  this->depth_ * sizeof(T));
+
+  this->length_ = 0;
+}
+
+// ============================================================================
+// Buffer::elem_size
+// ============================================================================
+template <typename T>
+INLINE_IMPL size_t Buffer<T>::elem_size(void) const
+{
+  return sizeof(T);
+}
+
+// ============================================================================
+// Buffer::depth
+// ============================================================================
+template <typename T>
+INLINE_IMPL size_t Buffer<T>::depth(void) const
+{
+  return this->depth_;
+}
+
+// Buffer::depth
+// ============================================================================
+template <typename T>
+INLINE_IMPL size_t Buffer<T>::length(void) const
+{
+  return this->length_;
+}
+
+// ============================================================================
+// Buffer::base
+// ============================================================================
+template <typename T>
+INLINE_IMPL T* Buffer<T>::base(void) const
+{
+  return this->base_;
+}
+
+// ============================================================================
+// Buffer::operator[]
+// ============================================================================
+template <typename T>
+INLINE_IMPL T& Buffer<T>::operator[] (size_t _indx)
+{
+  /* !! no bound error check !!*/
+  return this->base_[_indx];
+}
+
+// ============================================================================
+// Buffer::operator[]
+// ============================================================================
+template <typename T>
+INLINE_IMPL const T& Buffer<T>::operator[] (size_t _indx) const
+{
+  /* !! no bound error check !!*/
+  return this->base_[_indx];
+}
+
+// ============================================================================
+// Buffer::size
+// ============================================================================
+template <typename T>
+INLINE_IMPL size_t Buffer<T>::size(void) const
+{
+	return this->depth_ * sizeof(T);
+}
+
+// ============================================================================
+// Buffer::fill
+// ============================================================================
+template <typename T>
+INLINE_IMPL void Buffer<T>::fill(const T& _val)
+{
+  *this = _val;
+}
+
+// ============================================================================
+// Buffer::operator=
+// ============================================================================
+template <typename T>
+INLINE_IMPL Buffer<T>& Buffer<T>::operator=(const Buffer<T>& src)
+{
+  if (&src == this)
+    return *this;
+  size_t cpy_depth = (src.depth_ < this->depth_) ? src.depth_ : this->depth_; 
+  ::memcpy(this->base_, src.base_, cpy_depth * sizeof(T));
+  this->length_ = cpy_depth;
+  return *this;
+}
+
+// ============================================================================
+// Buffer::operator=
+// ============================================================================
+template <typename T>
+INLINE_IMPL Buffer<T>& Buffer<T>::operator=(const T* _src)
+{
+  if (_src == this->base_)
+    return *this;
+  ::memcpy(this->base_, _src, this->depth_ * sizeof(T));
+  this->length_ = this->depth_;
+  return *this;
+}
+
+// ============================================================================
+// Buffer::operator=
+// ============================================================================
+template <typename T>
+INLINE_IMPL Buffer<T>& Buffer<T>::operator=(const T& _val)
+{
+  for (size_t i = 0; i < this->depth_; i++)
+     *(this->base_ + i) = _val;
+  this->length_ = this->depth_;
+  return *this;
+}
+
+// ============================================================================
+// Class : CircularBuffer
+// ============================================================================
+// ============================================================================
+// Buffer::CircularBuffer
+// ============================================================================
+template <typename T>
+CircularBuffer<T>::CircularBuffer(void) 
+  : wp_(0), 
+    frozen_(false),
+    data_ (0),
+    ordered_data_ (0),
+    num_cycles_ (0)
+{
+  //- noop
+}
+
+// ============================================================================
+// Buffer::CircularBuffer
+// ============================================================================
+template <typename T>
+CircularBuffer<T>::CircularBuffer(size_t _depth) 
+  : wp_(0), 
+    frozen_(false),
+    data_ (0),
+    ordered_data_ (0),
+    num_cycles_ (0)
+{
+  this->depth(_depth);
+}
+
+// ============================================================================
+// CircularBuffer::~CircularBuffer
+// ============================================================================
+template <typename T> 
+CircularBuffer<T>::~CircularBuffer(void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// Buffer::depth
+// ============================================================================
+template <typename T>
+INLINE_IMPL size_t CircularBuffer<T>::depth(void) const
+{
+  return this->data_.depth();
+}
+
+// ============================================================================
+// CircularBuffer::~CircularBuffer
+// ============================================================================
+template <typename T> 
+CBPastIterator<T> CircularBuffer<T>::past_iterator (size_t n) const
+{
+  size_t pi_depth = this->data_.depth();
+  size_t pi_length = this->data_.length();
+  
+  if (! pi_length)
+    return CBPastIterator<T>(0, 0, 0, 0, 0);
+    
+  size_t adapted_n = (n > pi_length) ? pi_length : n;
+
+  T * pi_base = this->data_.base();
+  
+  size_t pi_pos = 0;
+  
+  if (this->num_cycles_)
+  {
+    pi_pos = ((this->wp_ - pi_base) + (pi_length - adapted_n)) % pi_depth;
+  }
+  else
+  {
+    int tmp = this->wp_ - pi_base - adapted_n;
+    if (tmp < 0)
+      pi_pos = 0;
+    else
+      pi_pos = (size_t)tmp;
+  }
+  
+  int wp_index = this->wp_ - pi_base;  
+  
+  size_t pi_max_pos = (wp_index > 0) ? wp_index : 0;
+
+/*
+  std::cout << "n............" << n << std::endl;
+  std::cout << "adapted_n...." << adapted_n << std::endl;
+  std::cout << "wp..........." << std::hex << this->wp_ << std::dec << std::endl;
+  std::cout << "base........." << std::hex << pi_base << std::dec << std::endl;
+  std::cout << "wp - base...." << this->wp_ - pi_base << std::endl;
+  std::cout << "pi_depth....." << pi_depth << std::endl;
+  std::cout << "pi_length...." << pi_length << std::endl;
+  std::cout << "pi_pos......." << pi_pos << std::endl;
+  std::cout << "pi_max_pos..." << pi_max_pos << std::endl;
+*/
+
+  DEBUG_ASSERT(pi_max_pos <=  pi_depth);
+  
+  return CBPastIterator<T>(pi_pos, pi_max_pos, pi_base, adapted_n, pi_length);
+}
+  
+// ============================================================================
+// CircularBuffer::freeze
+// ============================================================================
+template <typename T> 
+INLINE_IMPL void CircularBuffer<T>::freeze (void)
+{
+  this->frozen_ = true;
+}
+
+// ============================================================================
+// CircularBuffer::unfreeze
+// ============================================================================
+template <typename T> 
+INLINE_IMPL void CircularBuffer<T>::unfreeze (void)
+{
+  this->frozen_ = false;
+}
+
+// ============================================================================
+// CircularBuffer::clear
+// ============================================================================
+template <typename T> 
+void CircularBuffer<T>::clear (void)
+{
+  this->wp_ = this->data_.base();
+  this->data_.clear();
+  this->num_cycles_ = 0;
+  this->ordered_data_.clear();
+}
+
+// ============================================================================
+// Buffer::depth
+// ============================================================================
+template <typename T> 
+void CircularBuffer<T>::depth (size_t _depth) throw (Tango::DevFailed)
+{
+  //- set buffer depth.
+  this->data_.depth(_depth);
+  //- update write pointer
+  this->wp_ = this->data_.base();
+  //- (re)allocate ordered data buffer
+  this->ordered_data_.depth(_depth);
+  this->ordered_data_.clear();
+  //- reset num of cycles
+  this->num_cycles_ = 0;
+}
+
+// ============================================================================
+// CircularBuffer::fill
+// ============================================================================
+template <typename T>
+INLINE_IMPL  void CircularBuffer<T>::fill(const T& _val)
+{
+  this->data_.fill(_val);
+}
+
+// ============================================================================
+// CircularBuffer::push
+// ============================================================================
+template <typename T> 
+INLINE_IMPL void CircularBuffer<T>::push(T _data)
+  throw (Tango::DevFailed)
+{
+  //- check preallocation
+  if (! this->data_.depth()) 
+  {
+    Tango::Except::throw_exception (_CPTC ("programming error"), 
+                                    _CPTC ("circular buffer was not initialized properly"),
+                                    _CPTC ("CircularBuffer::push"));
+  } 
+
+  //- store value
+  *this->wp_ = _data;
+  
+  //- update num of elements in the underlying buffer
+  this->data_.force_length(this->data_.length() + 1);
+
+  //- update write pointer
+  this->wp_++;
+  
+  //- modulo 
+  if (static_cast<size_t>(this->wp_ - this->data_.base()) >= this->data_.depth())
+  {
+  	this->num_cycles_++;
+  	this->wp_ =  this->data_.base();
+  }
+
+}
+
+// ============================================================================
+// CircularBuffer::ordered_data
+// ============================================================================
+template <typename T> 
+const Buffer<T> & CircularBuffer<T>::ordered_data (void) const 
+  throw (Tango::DevFailed)
+{
+  //- std::cout << "CircularBuffer::ordered_data <-" << std::endl;  
+ 
+  static T * last_wp = 0;
+
+  //- optimization: do nothing if write pointer pos did not change since last data ordering
+  if (! this->frozen_ && this->wp_ != last_wp && last_wp != 0)
+  {
+    //- std::cout << "CircularBuffer::ordered_data::wrt ptr pos changed - reordering data..." << std::endl;  
+    
+    //- check preallocation
+    if (this->ordered_data_.depth() != this->data_.depth())
+    {
+      Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                      _CPTC ("unexpected buffer size"),
+                                      _CPTC ("CircularBuffer::ordered_data"));
+    }
+    
+    //- clear tmp buffer
+    static_cast< bpm::Buffer<T> >(this->ordered_data_).clear();
+    
+    size_t newer_data_count = this->wp_ - this->data_.base(); 
+    size_t older_data_count = this->data_.depth() - newer_data_count;
+  
+    //- reorder the data
+    if (newer_data_count > 0 && this->num_cycles_)
+    {
+    	//- reorder the data: copy older data first
+      ::memcpy(this->ordered_data_.base(), this->wp_, older_data_count * sizeof(T));
+      //- reorder the data: copy newer data
+      ::memcpy(this->ordered_data_.base() + older_data_count,  this->data_.base(),  newer_data_count * sizeof(T));
+    }
+    else
+    {
+      ::memcpy(this->ordered_data_.base(),  this->data_.base(), this->data_.size());
+    }
+  }
+  else if (! last_wp) 
+  {
+    ::memcpy(this->ordered_data_.base(),  this->data_.base(), this->data_.size());
+  }
+
+  //- store current write pointer pos
+  last_wp = this->wp_;
+
+  //- std::cout << "CircularBuffer::ordered_data ->" << std::endl;  
+
+  //- return the reordered data
+  return this->ordered_data_;
+}
+
+// ============================================================================
+// CircularBuffer::data
+// ============================================================================
+template <typename T>
+INLINE_IMPL const Buffer<T> & CircularBuffer<T>::data (void) const
+{
+  return this->data_;
+}
+
+} // namespace bpm 
+
+#endif // _BPM_BUFFER_CPP_
+
diff --git a/src/BPMBuffer.h b/src/BPMBuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c2b8f3e9c123854d770d0a6dee49a96b239579f
--- /dev/null
+++ b/src/BPMBuffer.h
@@ -0,0 +1,373 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_BUFFER_H_
+#define _BPM_BUFFER_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+
+namespace bpm {
+
+// ============================================================================
+//! A buffer abstraction class.  
+// ============================================================================
+//!  
+//! This template class provides a buffer abstraction. 
+//! <operator=> must be defined for template parameter T.
+//! 
+// ============================================================================
+template <typename T> class Buffer 
+{
+public:
+  
+  /**
+   * Constructor. 
+   * @param  depth the maximum number of element of type T 
+   *         that can be stored into the buffer 
+   */
+  Buffer (size_t depth = 0)
+    throw (Tango::DevFailed);
+ 
+  /**
+   * Memory copy constructor. Memory is copied from _base to _base + _depth.
+   * @param  depth the maximum number of element of type T 
+   *         that can be stored into the buffer. 
+   * @param  base address of the block to copy.
+   */
+  Buffer (size_t depth, T *base)
+    throw (Tango::DevFailed);
+
+  /**
+   * Copy constructor. Use allocator associated with the source buffer.
+   * @param  buf the source buffer.
+   */
+  Buffer (const Buffer<T> &buf)
+    throw (Tango::DevFailed);
+
+  /**
+   * Destructor. Release resources.
+   */
+  virtual ~Buffer (void);
+
+  /**
+   * operator= 
+   */
+  Buffer<T>& operator= (const Buffer<T> &src);
+
+  /**
+   * operator=. Memory is copied from base to base + Buffer::depth_. 
+   * @param base address of the block to copy.
+   */
+  Buffer<T>& operator= (const T *base);
+
+  /**
+   * operator=. Fill the buffer with a specified value.
+   * @param val the value.
+   */
+  Buffer<T>& operator= (const T &val);
+   
+  /**
+   * Fills the buffer with a specified value.
+   * @param val the value.
+   */
+  void fill (const T& val);
+  
+  /**
+   * Clears buffer's content. This is a low level clear: set memory
+   * from Buffer::base_ to Buffer::base_ + Buffer::depth_ to 0.
+   */
+  void clear (void);
+
+  /**
+   * Returns a reference to the _ith element. No bound error checking.
+   * @param i index of the element to return.
+   * @return a reference to the ith element.
+   */
+  T& operator[] (size_t i);
+
+  /**
+   * Returns a reference to the _ith element. No bound error checking.
+   * @param i index of the element to return.
+   * @return a const reference to the ith element.
+   */
+  const T& operator[] (size_t i) const;
+  
+  /**
+   * Returns the size of each element in bytes.
+   * @return sizeof(T).
+   */
+  size_t elem_size (void) const;
+
+  /**
+   * Returns the actual size of the buffer in bytes. 
+   * @return the buffer size in bytes.
+   */
+  size_t size (void) const;
+
+  /**
+   * Returns the maximum number of element that can be stored into 
+   * the buffer. 
+   * @return the buffer depth. 
+   */
+  size_t depth (void) const;
+  
+  /**
+   * Set the buffer depth to _depth
+   */
+  virtual void depth (size_t _depth)
+    throw (Tango::DevFailed);
+
+  /**
+   * Set current number of element
+   */
+  void force_length (size_t len);
+  
+  /**
+   * Returns current number of element in the buffer
+   */
+  size_t length (void) const;
+  
+  /**
+   * Returns the buffer base address. 
+   * @return the buffer base address. 
+   */
+  T * base (void) const;
+
+protected:
+
+  /**
+   * the buffer base address. 
+   */
+  T * base_;
+
+  /**
+   * maximum number of element of type T.
+   */
+  size_t depth_;
+
+  /**
+   * current number of element of type T.
+   */
+  size_t length_;
+};
+
+// ============================================================================
+//! A past iterator for the circular buffer class.  
+// ============================================================================
+//!  
+//! Iterates on the last n points of a circular buffer
+//! 
+// ============================================================================
+template <typename T> class CBPastIterator 
+{
+ public:
+    //- ctor
+    CBPastIterator (size_t pos, size_t max_pos, T * base, size_t length, size_t depth)
+      : pos_(pos), 
+        max_pos_(max_pos), 
+        base_(base), 
+        length_(length), 
+        depth_(depth), 
+        pos_has_been_inc_(false)
+    {
+      //- noop     
+    }
+    
+    //- dtor
+    ~CBPastIterator ()
+    {
+      //- noop     
+    }
+    
+    //- operator++
+    inline void operator++ (int)
+    {
+      if (! length_ || (pos_has_been_inc_ && (pos_ == max_pos_)))
+        return;
+			pos_++;
+      pos_has_been_inc_ = true;
+      if (pos_ != max_pos_)
+        pos_ %= depth_; 
+    }
+    
+    //- operator*
+    inline const T& operator* () const
+    {
+      return *(this->base_ + this->pos_);
+    }
+
+    //- end of past
+    inline bool end_of_past () const
+    {
+      return (! length_) ? true : (pos_has_been_inc_ && (pos_ == max_pos_));
+    }
+    
+private:
+    size_t pos_;
+    size_t max_pos_;
+    T * base_;
+    size_t length_;
+    size_t depth_;
+    bool pos_has_been_inc_;
+};
+        
+        
+// ============================================================================
+//! A ciruclar buffer abstraction class.  
+// ============================================================================
+//!  
+//! This template class provides a  (write only) circular buffer abstraction. 
+//! <operator=> must be defined for template parameter T.
+//! 
+// ============================================================================
+template <typename T> class CircularBuffer
+{
+public:
+
+   typedef CBPastIterator<T> PastIterator;
+
+  /**
+   * Constructor. 
+   */
+  CircularBuffer (void);
+
+  /**
+   * Constructor. 
+   */
+  CircularBuffer (size_t depth);
+  
+  /**
+   * Destructor. Release resources.
+   */
+  virtual ~CircularBuffer (void);
+
+  /**
+   * Clears buffer's content.
+   */
+  virtual void clear (void);
+
+  /**
+   * Fills the buffer with a specified value.
+   * @param val the value.
+   */
+  void fill (const T& val);
+  
+  /**
+   * Pushes the specified data into the circular buffer.
+   * The data buffer must have 
+   */
+  void push (T new_element)
+    throw (Tango::DevFailed);
+
+  /**
+   * Freezes the buffer. 
+   * Any data pushed into a frozen circular buffer is silently ignored.  
+   */
+  void freeze (void);
+
+  /**
+   * Unfreeze 
+   * Data pushed into a frozen circular buffer is silently ignored (see CircularBuffer::freeze).  
+   */
+  void unfreeze (void);
+
+  /**
+   * Returns the "chronologically ordered" circular buffer's content
+   */
+  const bpm::Buffer<T> & ordered_data (void) const
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the circular buffer's content
+   */
+  const bpm::Buffer<T> & data (void) const;
+    
+  /**
+   * Set the buffer depth to _depth
+   */
+  virtual void depth (size_t _depth)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Returns buffer depth 
+   */
+  size_t depth () const;
+    
+  /**
+   * Iterate on last n points in the buffer
+   */
+  CBPastIterator<T> past_iterator (size_t n) const;
+    
+private:
+  /**
+   * The write pointer
+   */
+  T * wp_; 
+
+  /**
+   * Frozen flag
+   */
+  bool frozen_;
+
+  /**
+   * The main buffer
+   */
+  bpm::Buffer<T> data_;
+  
+  /**
+   * The ordered buffer
+   */
+  bpm::Buffer<T> ordered_data_;
+
+  /**
+   * Num of cycles
+   */
+  unsigned long num_cycles_;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  CircularBuffer& operator= (const CircularBuffer&);
+  CircularBuffer(const CircularBuffer&);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "BPMBuffer.i"
+#endif // __INLINE_IMPL__
+
+#include "BPMBuffer.cpp"
+
+#endif // _BUFFER_H_
+
+
+
diff --git a/src/BPMBuffer.i b/src/BPMBuffer.i
new file mode 100644
index 0000000000000000000000000000000000000000..a1a42c2e7ba78709c67655d618a5d05429ddc582
--- /dev/null
+++ b/src/BPMBuffer.i
@@ -0,0 +1,34 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+
+
+} // namespace asl
diff --git a/src/BPMConfig.cpp b/src/BPMConfig.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a356d9cc3bd40527253bca64ef241a65f4fcf5d8
--- /dev/null
+++ b/src/BPMConfig.cpp
@@ -0,0 +1,966 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <iostream>
+#include <limits>
+#include <string>
+#include "BPMConfig.h"
+ 
+#if !defined (__INLINE_IMPL__)
+# include "BPMConfig.i"
+#endif // __INLINE_IMPL__
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_DD_DEC_FACTOR  1
+#define kDEFAULT_DD_TRIG_OFFSET 0
+//-----------------------------------------------------------------------------
+#define kDEFAULT_LO_LIMIT kLIBERA_STARTUP_CONFIG_ILK_XLO 
+#define kDEFAULT_HI_LIMIT kLIBERA_STARTUP_CONFIG_ILK_XHI
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+//- interlock shortcuts
+enum {
+  kINTERLOCK_CONFIG_ILK_MODE_IDX = 0,
+  kINTERLOCK_CONFIG_ILK_XLO_IDX,
+  kINTERLOCK_CONFIG_ILK_XHI_IDX,
+  kINTERLOCK_CONFIG_ILK_ZLO_IDX,
+  kINTERLOCK_CONFIG_ILK_ZHI_IDX,
+  kINTERLOCK_CONFIG_ILK_OVFLL_IDX,
+  kINTERLOCK_CONFIG_ILK_OVFLD_IDX,
+  kINTERLOCK_CONFIG_ILK_GAINL_IDX
+};
+
+// ============================================================================
+// BPMConfig::BPMConfig
+// ============================================================================
+BPMConfig::BPMConfig (Tango::DeviceImpl * _d)
+  : host_device_ (_d)
+{
+#if ! defined(_EMBEDDED_DEVICE_)
+  this->ip_addr_ = "unspecified";
+  this->mcast_ip_addr_ = "unspecified";
+  this->gs_port_ = GS_DEFAULT_PORT;
+  this->mcast_port_ = GS_DEFAULT_MCAST_PORT;
+#endif
+
+  //- by default, we do not BBA offsets into account when computing 
+  //- the offsets passed to the FPGA process
+  this->pass_bba_offsets_to_fpga_ = false;
+
+  //- by default, dd buffer freezing is disabled
+  this->dd_buffer_freezing_enabled_ = false;
+  
+  //- by default, external trigger is disabled
+  this->external_trigger_enabled_ = false;
+
+  //- reset both "actual" and "requested" env. params
+  ::memset (&this->actual_ep_, 0, sizeof (CSPI_ENVPARAMS));
+  ::memset (&this->requested_ep_, 0, sizeof (CSPI_ENVPARAMS));
+
+  //- init connection params for DD
+  ::memset (&this->cp_dd_, 0, sizeof (CSPI_CONPARAMS_EBPP));
+  this->cp_dd_.mode = CSPI_MODE_DD;
+  this->cp_dd_.dec = kDEFAULT_DD_DEC_FACTOR;
+  this->dd_raw_buffer_depth_ = NB_VALUE_02;
+  this->max_dd_buffer_depth_for_dec_on_ = DD_NSAMPLES_MAX_VALUE_DECIM_ENABLED;
+  this->dd_trigger_offset_ = kDEFAULT_DD_TRIG_OFFSET;
+  
+  //- init connection params for SA
+  ::memset (&this->cp_sa_, 0, sizeof (CSPI_CONPARAMS_EBPP));
+  this->cp_sa_.mode = CSPI_MODE_SA;
+  this->cp_sa_.nonblock = 1;
+  this->sa_data_history_buffer_depth_ = kDEFAULT_SA_HISTORY_DEPTH;
+  this->sa_stats_num_samples_ = kDEFAULT_SA_STAT_SAMPLES;
+
+  //- init connection params for PM
+  ::memset (&this->cp_srv_, 0, sizeof (CSPI_CONPARAMS));
+  this->cp_srv_.mode = CSPI_MODE_PM;
+
+  //- init connection params for ADC
+  ::memset (&this->cp_adc_, 0, sizeof (CSPI_CONPARAMS));
+  this->cp_adc_.mode = CSPI_MODE_ADC;
+  this->adc_raw_buffer_depth_ = NB_VALUE_02;
+  
+  //- init offsets and parameters for beam pos computation
+  this->Kx = 1.0;
+  this->Kz = 1.0;
+
+  this->Xoffset_local = 0.0;
+  this->Zoffset_local = 0.0;
+
+  this->Xoffset_fpga = 0.0;
+  this->Zoffset_fpga = 0.0;
+
+  this->Qoffset_local = 0.0;
+  this->Qoffset_fpga = 0.0;
+
+  this->VaGainCorrection = 1.0; 
+  this->VbGainCorrection = 1.0;
+  this->VcGainCorrection = 1.0;
+  this->VdGainCorrection = 1.0;
+
+#if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_Kx = 1;
+  this->int_Kz = 1;
+  this->int_Xoffset_local = 0;
+  this->int_Zoffset_local = 0;
+  this->int_Qoffset_local = 0;
+  this->int_VaGainCorrection = 1;
+  this->int_VbGainCorrection = 1;
+  this->int_VcGainCorrection = 1;
+  this->int_VdGainCorrection = 1;
+#endif
+
+  //- bpm location
+  this->location_ = BPM_LOC_UNKNOWN;
+
+  //- block geometry
+  this->block_geometry_ = BLOCK_GEOMETRY_45;
+
+  //- data sources flags
+  this->sa_enabled_ = false;
+  this->pm_enabled_ = false;
+  this->adc_enabled_ = false;
+  this->dd_enabled_ = false;     
+  
+  //- thread periods
+  this->dd_thread_activity_period_ = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->sa_thread_activity_period_ = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->adc_thread_activity_period_ = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->fa_cache_refresh_period_ = kDEFAULT_FA_CACHE_REFRESH_PERIOD_MS;
+
+  this->enable_auto_switching_on_sa_activation_ = true;
+  this->enable_dsc_on_auto_switching_activation_ = true;
+
+  this->local_sa_pos_computation_enabled_ = true;
+  
+  this->dd_optional_data_enabled_ = false;
+  this->sa_optional_data_enabled_ = false;
+  this->adc_optional_data_enabled_ = false;
+  this->sa_history_optional_data_enabled_ = false;
+
+  this->institute_ = kTANGO_INSTITUTE;
+  this->pos_algorithm_ = kSTD_POS_ALGO;
+}
+
+// ============================================================================
+// BPMConfig::BPMConfig
+// ============================================================================
+BPMConfig::BPMConfig (const BPMConfig & _src)
+{
+  //- delegate copy to operator=
+  *this = _src;
+}
+
+// ============================================================================
+// BPMConfig::~BPMConfig
+// ============================================================================
+BPMConfig::~BPMConfig (void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// BPMConfig::operator= 
+// ============================================================================
+BPMConfig & BPMConfig::operator= (const BPMConfig & _src)
+{
+  //- avoid self copy
+  if (&_src == this)
+    return *this;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  this->ip_addr_ = _src.ip_addr_;
+  this->mcast_ip_addr_ = _src.mcast_ip_addr_;
+  this->gs_port_ = _src.gs_port_;
+  this->mcast_port_ = _src.mcast_port_;
+#endif
+
+  this->dd_buffer_freezing_enabled_ = _src.dd_buffer_freezing_enabled_;
+    
+  this->external_trigger_enabled_ = _src.external_trigger_enabled_;
+
+  //- copy all CSPI bytes...
+  ::memcpy (&this->requested_ep_, &_src.requested_ep_, sizeof (CSPI_ENVPARAMS));
+  ::memcpy (&this->actual_ep_, &_src.actual_ep_, sizeof (CSPI_ENVPARAMS));
+  ::memcpy (&this->cp_dd_, &_src.cp_dd_, sizeof (CSPI_CONPARAMS_EBPP));
+  ::memcpy (&this->cp_sa_, &_src.cp_sa_, sizeof (CSPI_CONPARAMS_EBPP));
+  ::memcpy (&this->cp_srv_, &_src.cp_srv_, sizeof (CSPI_CONPARAMS));
+  ::memcpy (&this->cp_adc_, &_src.cp_adc_, sizeof (CSPI_CONPARAMS));
+
+  this->offsets_ = _src.offsets_;
+
+  this->dd_raw_buffer_depth_ = _src.dd_raw_buffer_depth_;
+  
+  this->max_dd_buffer_depth_for_dec_on_ = _src.max_dd_buffer_depth_for_dec_on_;
+  
+  this->adc_raw_buffer_depth_ = _src.adc_raw_buffer_depth_;
+  
+  this->dd_trigger_offset_ = _src.dd_trigger_offset_;
+
+  this->Kx = _src.Kx;
+  this->Kz = _src.Kz;
+
+  this->Xoffset_local = _src.Xoffset_local;
+  this->Zoffset_local = _src.Zoffset_local;
+
+  this->Xoffset_fpga = _src.Xoffset_fpga;
+  this->Zoffset_fpga = _src.Zoffset_fpga;
+
+  this->Qoffset_local = _src.Qoffset_local;
+  this->Qoffset_fpga = _src.Qoffset_fpga;
+
+  this->VaGainCorrection = _src.VaGainCorrection;
+  this->VbGainCorrection = _src.VbGainCorrection;
+  this->VcGainCorrection = _src.VcGainCorrection;
+  this->VdGainCorrection = _src.VdGainCorrection;
+
+#if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_Kx = _src.int_Kx;
+  this->int_Kz = _src.int_Kz;
+  this->int_Xoffset_local = _src.int_Xoffset_local;
+  this->int_Zoffset_local = _src.int_Zoffset_local;
+  this->int_Qoffset_local = _src.int_Qoffset_local;
+  this->int_VaGainCorrection = _src.int_VaGainCorrection;
+  this->int_VbGainCorrection = _src.int_VbGainCorrection;
+  this->int_VcGainCorrection = _src.int_VcGainCorrection;
+  this->int_VdGainCorrection = _src.int_VdGainCorrection;
+#endif
+
+  this->location_ = _src.location_;
+
+  this->block_geometry_ = _src.block_geometry_;
+
+  this->sa_enabled_ = _src.sa_enabled_;
+  this->pm_enabled_ = _src.pm_enabled_;
+  this->adc_enabled_ = _src.adc_enabled_;
+  this->dd_enabled_ = _src.dd_enabled_;
+
+  this->dd_thread_activity_period_ = _src.dd_thread_activity_period_;
+  this->sa_thread_activity_period_ = _src.sa_thread_activity_period_;
+  this->adc_thread_activity_period_ = _src.adc_thread_activity_period_;
+  this->fa_cache_refresh_period_ = _src.fa_cache_refresh_period_;
+
+  this->sa_data_history_buffer_depth_ = _src.sa_data_history_buffer_depth_;
+  this->sa_stats_num_samples_ = _src.sa_stats_num_samples_;
+
+  this->enable_auto_switching_on_sa_activation_ = _src.enable_auto_switching_on_sa_activation_;
+  this->enable_dsc_on_auto_switching_activation_ = _src.enable_dsc_on_auto_switching_activation_;
+
+  this->local_sa_pos_computation_enabled_ = _src.local_sa_pos_computation_enabled_;
+  
+  this->dd_optional_data_enabled_ = _src.dd_optional_data_enabled_;
+  this->sa_optional_data_enabled_ = _src.sa_optional_data_enabled_;
+  this->adc_optional_data_enabled_ = _src.adc_optional_data_enabled_;
+  this->sa_history_optional_data_enabled_ = _src.sa_history_optional_data_enabled_;
+
+  this->institute_ = _src.institute_;
+  this->pos_algorithm_ = _src.pos_algorithm_;
+
+  this->host_device_ = _src.host_device_;
+  
+  this->pass_bba_offsets_to_fpga_ = _src.pass_bba_offsets_to_fpga_;
+  
+  return *this;
+}
+
+// ============================================================================
+// BPMConfig::set_offsets
+// ============================================================================
+void BPMConfig::set_offsets (const BPMOffsets & _src) 
+  throw (Tango::DevFailed)
+{
+  //- copy offsets from _src
+  this->offsets_ = _src;
+}
+
+// ============================================================================
+// BPMConfig::compute_actual_offsets
+// ============================================================================
+void BPMConfig::compute_actual_offsets (CSPI_ENVPARAMS &ep, bool auto_switching_enabled) 
+  throw (Tango::DevFailed)
+{
+  //- set Kx, Kz for DD
+  this->Kx = this->offsets_[BPMOffsets::KX];
+  this->Kz = this->offsets_[BPMOffsets::KZ];
+
+  //- compute offsets for both DD and SA
+  this->Xoffset_local = this->offsets_[BPMOffsets::X_OFFSET_1]
+                      + this->offsets_[BPMOffsets::X_OFFSET_BBA];
+                      
+                      
+  if (! auto_switching_enabled)
+  {
+    this->Xoffset_local = this->Xoffset_local
+                        + this->offsets_[BPMOffsets::X_OFFSET_3]
+                        + this->offsets_[BPMOffsets::X_OFFSET_4]
+                        + this->offsets_[BPMOffsets::X_OFFSET_5];
+  }
+
+  this->Zoffset_local = this->offsets_[BPMOffsets::Z_OFFSET_1] 
+                      + this->offsets_[BPMOffsets::Z_OFFSET_BBA];
+                      
+  if (! auto_switching_enabled)
+  {
+    this->Zoffset_local = this->Zoffset_local
+                        + this->offsets_[BPMOffsets::Z_OFFSET_3]
+                        + this->offsets_[BPMOffsets::Z_OFFSET_4]
+                        + this->offsets_[BPMOffsets::Z_OFFSET_5];
+  }
+             
+  bpm::FPDataType A, B, C, D, invA, invB, invC, invD;
+  
+  A = this->offsets_[BPMOffsets::A_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    A *= this->offsets_[BPMOffsets::A_HW_GAIN_CORRECTION];
+  invA = 1. / A;
+   
+  B = this->offsets_[BPMOffsets::B_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    B *= this->offsets_[BPMOffsets::B_HW_GAIN_CORRECTION];
+  invB = 1. / B;
+    
+  C = this->offsets_[BPMOffsets::C_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    C *= this->offsets_[BPMOffsets::C_HW_GAIN_CORRECTION];
+  invC = 1. / C;
+    
+  D = this->offsets_[BPMOffsets::D_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    D *= this->offsets_[BPMOffsets::D_HW_GAIN_CORRECTION];
+  invD = 1. / D;
+
+  bpm::FPDataType x_global_electrode_offset = 
+    this->Kx * ((invA + invD) - (invB + invC)) / (invA + invB + invC + invD);
+  
+  bpm::FPDataType z_global_electrode_offset = 
+    this->Kz * ((invA + invB) - (invC + invD)) / (invA + invB + invC + invD);
+  
+
+  this->Xoffset_fpga = this->offsets_[BPMOffsets::X_OFFSET_1] 
+                     + x_global_electrode_offset;
+                     
+  if (! auto_switching_enabled)
+  {
+    this->Xoffset_fpga  += this->offsets_[BPMOffsets::X_OFFSET_3]
+                        +  this->offsets_[BPMOffsets::X_OFFSET_4]
+                        +  this->offsets_[BPMOffsets::X_OFFSET_5];
+  }
+  
+  if (this->pass_bba_offsets_to_fpga_)
+  {
+    this->Xoffset_fpga += this->offsets_[BPMOffsets::X_OFFSET_BBA];
+  }                   
+
+  this->Zoffset_fpga = this->offsets_[BPMOffsets::Z_OFFSET_1] 
+                     + z_global_electrode_offset;
+                     
+  if (! auto_switching_enabled)
+  {
+    this->Zoffset_fpga  += this->offsets_[BPMOffsets::Z_OFFSET_3]
+                        +  this->offsets_[BPMOffsets::Z_OFFSET_4]
+                        +  this->offsets_[BPMOffsets::Z_OFFSET_5];
+  }
+
+  if (this->pass_bba_offsets_to_fpga_)
+  {
+    this->Zoffset_fpga += this->offsets_[BPMOffsets::Z_OFFSET_BBA];
+  }   
+  
+  this->Qoffset_local = this->offsets_[BPMOffsets::Q_OFFSET_1];
+  if (! auto_switching_enabled)
+    this->Qoffset_local += this->offsets_[BPMOffsets::Q_OFFSET_2];
+
+  this->Qoffset_fpga = 0;
+    
+  //- gain corrections
+  this->VaGainCorrection = this->offsets_[BPMOffsets::A_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    this->VaGainCorrection *= this->offsets_[BPMOffsets::A_HW_GAIN_CORRECTION];
+
+  this->VbGainCorrection = this->offsets_[BPMOffsets::B_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    this->VbGainCorrection *= this->offsets_[BPMOffsets::B_HW_GAIN_CORRECTION];
+
+  this->VcGainCorrection = this->offsets_[BPMOffsets::C_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    this->VcGainCorrection *= this->offsets_[BPMOffsets::C_HW_GAIN_CORRECTION];
+
+  this->VdGainCorrection = this->offsets_[BPMOffsets::D_BLOCK_GAIN_CORRECTION];
+  if (! auto_switching_enabled)
+    this->VdGainCorrection *= this->offsets_[BPMOffsets::D_HW_GAIN_CORRECTION];
+
+  //- we have to pass K and Offset values in nanometer to the Libera (FPGA processing)
+  ep.Kx      = static_cast<int>(kMILLI_TO_NANO_METERS * this->Kx);
+  ep.Ky      = static_cast<int>(kMILLI_TO_NANO_METERS * this->Kz);
+  ep.Xoffset = static_cast<int>(kMILLI_TO_NANO_METERS * this->Xoffset_fpga);
+  ep.Yoffset = static_cast<int>(kMILLI_TO_NANO_METERS * this->Zoffset_fpga);
+  ep.Qoffset = static_cast<int>(kMILLI_TO_NANO_METERS * this->Qoffset_fpga);
+
+#if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  //- Kx, Kz and offsets in nanometer
+  this->int_Kx = static_cast<bpm::IntOffsetDataType>(kMILLI_TO_NANO_METERS * this->Kx);
+  this->int_Kz = static_cast<bpm::IntOffsetDataType>(kMILLI_TO_NANO_METERS * this->Kz);
+  this->int_Xoffset_local = static_cast<bpm::IntOffsetDataType>(kMILLI_TO_NANO_METERS * this->Xoffset_local);
+  this->int_Zoffset_local = static_cast<bpm::IntOffsetDataType>(kMILLI_TO_NANO_METERS * this->Zoffset_local);
+  this->int_Qoffset_local = static_cast<bpm::IntOffsetDataType>(kMILLI_TO_NANO_METERS * this->Qoffset_local);
+  //- here we trunc the gain correction factor to 4 digits: a.bcdefghij -> abcdef   
+  this->int_VaGainCorrection = static_cast<bpm::IntOffsetDataType>(kGAIN_TRUNC_FACTOR * this->VaGainCorrection);
+  this->int_VbGainCorrection = static_cast<bpm::IntOffsetDataType>(kGAIN_TRUNC_FACTOR * this->VbGainCorrection);
+  this->int_VcGainCorrection = static_cast<bpm::IntOffsetDataType>(kGAIN_TRUNC_FACTOR * this->VcGainCorrection);
+  this->int_VdGainCorrection = static_cast<bpm::IntOffsetDataType>(kGAIN_TRUNC_FACTOR * this->VdGainCorrection);
+#endif
+
+  if (this->offsets_[BPMOffsets::GEOMETRY] == kBLOCK_GEOMETRY_45)
+  {
+    this->block_geometry_ = BLOCK_GEOMETRY_45;
+  }
+  else if (this->offsets_[BPMOffsets::GEOMETRY] == kBLOCK_GEOMETRY_90)
+  {
+    this->block_geometry_ = BLOCK_GEOMETRY_90;
+  }
+  else
+  {
+    Tango::Except::throw_exception ((const char *) "invalid block geometry specified", 
+                                    (const char *) "invalid block geometry specified - check BPM::BlockParameters property", 
+                                    (const char *) "BPMConfig::compute_actual_offsets");
+  }
+
+#if defined(_DEBUG)
+  this->dump_offsets();
+#endif
+}
+
+// ============================================================================
+// BPMConfig::dump_offsets
+// ============================================================================
+void BPMConfig::dump_offsets (void) const  
+{
+#if 0 //-TODO: remove this #if
+  std::cout << "BPMConfig::offsets::Kx................." << this->Kx << std::endl;
+  std::cout << "BPMConfig::offsets::Kz................." << this->Kz << std::endl;
+  std::cout << "BPMConfig::offsets::Xoffset_local......" << this->Xoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::Xoffset_fpga......." << this->Xoffset_fpga << std::endl;
+  std::cout << "BPMConfig::offsets::Zoffset_local......" << this->Zoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::Zoffset_fpga......." << this->Zoffset_fpga << std::endl;
+  std::cout << "BPMConfig::offsets::Qoffset_local......" << this->Qoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::Qoffset_fpga......." << this->Qoffset_fpga << std::endl;
+  std::cout << "BPMConfig::offsets::VaGainCorrection..." << this->VaGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::VbGainCorrection..." << this->VbGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::VcGainCorrection..." << this->VcGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::VdGainCorrection..." << this->VdGainCorrection << std::endl;
+# if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  std::cout << "BPMConfig::offsets::int_Kx_local..........." << this->int_Kx << std::endl;
+  std::cout << "BPMConfig::offsets::int_Kz_local..........." << this->int_Kz << std::endl;
+  std::cout << "BPMConfig::offsets::int_Xoffset_local......" << this->int_Xoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::int_Zoffset_local......" << this->int_Zoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::int_Qoffset_local......" << this->int_Qoffset_local << std::endl;
+  std::cout << "BPMConfig::offsets::int_VaGainCorrection..." << this->int_VaGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::int_VbGainCorrection..." << this->int_VbGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::int_VcGainCorrection..." << this->int_VcGainCorrection << std::endl;
+  std::cout << "BPMConfig::offsets::int_VdGainCorrection..." << this->int_VdGainCorrection << std::endl;
+# endif
+#endif
+}
+
+// ============================================================================
+// BPMConfig::dump_env_parameters
+// ============================================================================
+void BPMConfig::dump_env_parameters (void) const
+{
+#if 0 //-TODO: remove this #if
+  std::cout << std::endl;
+
+  std::cout << " Main env. parameters " << std::endl;
+  std::cout << "----------------------" << std::endl;
+
+# if ! defined(_EMBEDDED_DEVICE_)
+  std::cout << "- IP@..........................." << this->ip_addr_ << std::endl;
+  std::cout << "- GS-port......................." << this->gs_port_ << std::endl;
+  std::cout << "- MCast-IP@....................." << this->mcast_ip_addr_ << std::endl;
+  std::cout << "- MCast-port...................." << this->mcast_port_ << std::endl;
+  std::cout << "- B-Freezing...................." << this->dd_buffer_freezing_enabled_ << std::endl;
+# endif
+
+  std::cout << "- Location......................";
+  switch (this->location_)
+  {
+  case BPM_LOC_TL1:
+    std::cout << "TL1";
+    break;
+  case BPM_LOC_BOOSTER:
+    std::cout << "BOOSTER";
+    break;
+  case BPM_LOC_TL2:
+    std::cout << "TL2";
+    break;
+  case BPM_LOC_STORAGE_RING:
+    std::cout << "STORAGE RING";
+    break;
+  default:
+    std::cout << "unknown";
+    break;
+  }
+  std::cout << std::endl; 
+  std::cout << std::endl; 
+    
+  std::cout << "   Requested  env. parameters   " << std::endl;
+  std::cout << "--------------------------------" << std::endl;
+  this->dump_env_parameters(this->requested_ep_);
+  
+  std::cout << std::endl;
+  
+  std::cout << "     Actual env. parameters     " << std::endl;
+  std::cout << "--------------------------------" << std::endl;
+  this->dump_env_parameters(this->actual_ep_);
+  
+  std::cout << std::endl;
+  
+  std::cout << "Actual match requested env. parameters : " 
+            << ((this->requested_ep_ == this->actual_ep_) ? "YES" : "NO") 
+            << std::endl;
+
+  std::cout << std::endl;
+#endif
+}
+ 
+// ============================================================================
+// BPMConfig::dump_env_parameters
+// ============================================================================
+void BPMConfig::dump_env_parameters (const CSPI_ENVPARAMS &ep) const
+{
+  std::cout << "- Feature.customer..............0x" << std::hex << ep.feature.customer << std::dec << std::endl;
+  std::cout << "- Feature.itech.................0x" << std::hex << ep.feature.itech << std::dec << std::endl;
+  std::cout << "- Trigger mode.................." << ep.trig_mode << std::endl;
+  std::cout << "- Kx............................" << ep.Kx << std::endl;
+  std::cout << "- Kz............................" << ep.Ky << std::endl;
+  std::cout << "- Xoffset......................." << ep.Xoffset << std::endl;
+  std::cout << "- Zoffset......................." << ep.Yoffset << std::endl;
+  std::cout << "- Qoffset......................." << ep.Qoffset << std::endl;
+  std::cout << "- Switches......................" << ep.switches << std::endl;
+  std::cout << "- Gain.........................." << ep.gain << std::endl;
+  std::cout << "- AGC..........................." << ep.agc << std::endl;
+  std::cout << "- DSC..........................." << ep.dsc << std::endl;
+  std::cout << "- Interlocks.Mode..............." << ep.ilk.mode << std::endl;
+  std::cout << "- Interlocks.Xlow..............." << ep.ilk.Xlow << std::endl;
+  std::cout << "- Interlocks.Xhigh.............." << ep.ilk.Xhigh << std::endl;
+  std::cout << "- Interlocks.Zlow..............." << ep.ilk.Ylow << std::endl;
+  std::cout << "- Interlocks.Zhigh.............." << ep.ilk.Yhigh << std::endl;
+  std::cout << "- Interlocks.OverflowLimit......" << ep.ilk.overflow_limit << std::endl;
+  std::cout << "- Interlocks.OverflowDuration..." << ep.ilk.overflow_dur << std::endl;
+  std::cout << "- Interlocks.GainLimit.........." << ep.ilk.gain_limit << std::endl;
+  std::cout << "- External Switching ..........." << ep.external_switching << std::endl;
+  std::cout << "- Switching Delay..............." << ep.switching_delay << std::endl;  
+  std::cout << "- Tune Compensation ............" << ep.pll_status.mt_stat.nco_shift << std::endl;
+  std::cout << "- Tune Offset .................." << ep.pll_status.mt_stat.vcxo_offset << std::endl;
+  std::cout << "- External Trigger Delay........" << ep.trig_delay << std::endl;
+  std::cout << "- Post Mortem Offset............" << ep.PMoffset << std::endl;
+  std::cout << "- Has MAF support..............." << LIBERA_IS_MAF(ep.feature.itech) << std::endl;
+  if (LIBERA_IS_MAF(ep.feature.itech))
+  {
+    std::cout << "- MAF Length...................." << ep.ddc_maflength << std::endl;
+    std::cout << "- MAF Delay....................." << ep.ddc_mafdelay << std::endl;
+  } 
+}
+
+// ============================================================================
+// BPMConfig::dump_con_parameters
+// ============================================================================
+void BPMConfig::dump_con_parameters (void) const
+{
+  std::cout << std::endl;
+  //- DD --
+  std::cout << "Current DD Connection Parameters:" << std::endl;
+  std::cout << "\t-async.notif.handler..." << std::hex << (unsigned int) this->cp_dd_.handler << std::endl;
+  std::cout << "\t-user data............." << std::hex << (unsigned int) this->cp_dd_.user_data << std::endl;
+  std::cout << "\t-event mask............" << std::hex << (unsigned int) this->cp_dd_.event_mask << std::endl;
+  std::cout << "\t-decimation factor....." << std::hex << (unsigned int) this->cp_dd_.dec << std::endl;
+  std::cout << std::endl;
+  //- SA --
+  std::cout << "Current SA Connection Parameters:" << std::endl;
+  std::cout << "\t-async.notif.handler..." << std::hex << (unsigned int) this->cp_sa_.handler << std::endl;
+  std::cout << "\t-user data............." << std::hex << (unsigned int) this->cp_sa_.user_data << std::endl;
+  std::cout << "\t-event mask............" << std::hex << (unsigned int) this->cp_sa_.event_mask << std::endl;
+  std::cout << std::endl;
+  //- PM --
+  std::cout << "Current PM Connection Parameters:" << std::endl;
+  std::cout << "\t-async.notif.handler..." << std::hex << (unsigned int) this->cp_srv_.handler << std::endl;
+  std::cout << "\t-user data............." << std::hex << (unsigned int) this->cp_srv_.user_data << std::endl;
+  std::cout << "\t-event mask............" << std::hex << (unsigned int) this->cp_srv_.event_mask << std::endl;
+  std::cout << std::endl;
+  //- ADC --
+  std::cout << "Current ADC Connection Parameters:" << std::endl;
+  std::cout << "\t-async.notif.handler..." << std::hex << (unsigned int) this->cp_adc_.handler << std::endl;
+  std::cout << "\t-user data............." << std::hex << (unsigned int) this->cp_adc_.user_data << std::endl;
+  std::cout << "\t-event mask............" << std::hex << (unsigned int) this->cp_adc_.event_mask << std::dec << std::endl;
+  std::cout << std::endl;
+}
+
+// ============================================================================
+// BPMConfig::set_location
+// ============================================================================
+void BPMConfig::set_location (BPMLocation _loc) 
+  throw (Tango::DevFailed)
+{
+  switch (_loc)
+  {
+    case BPM_LOC_TL1:
+    case BPM_LOC_BOOSTER:
+    case BPM_LOC_TL2:
+    case BPM_LOC_STORAGE_RING:
+      break;
+    default:
+      this->location_ = BPM_LOC_UNKNOWN;
+      Tango::Except::throw_exception ((const char *) "invalid BPM location specified", 
+                                      (const char *) "invalid BPM location specified", 
+                                      (const char *) "BPMConfig::set_location");
+      break;
+  }
+
+  this->location_ = _loc;
+}
+
+// ============================================================================
+// BPMConfig::set_switches_mode
+// ============================================================================
+void BPMConfig::set_switches_mode (short _mode) 
+  throw (Tango::DevFailed)
+{ 
+  if ((_mode < kMIN_SWITCHES_MODE || _mode > kMAX_SWITCHES_MODE) && _mode != kAUTO_SWITCHING_MODE)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid Libera switch mode",
+                                    (const char *) "invalid switches mode specified - valid range is [0...15] or 255 for auto-switching",
+                                    (const char *) "BPMConfig::set_switches_mode");
+  }
+  
+  this->requested_ep_.switches = _mode;
+
+  if (this->enable_dsc_on_auto_switching_activation_ && _mode == kAUTO_SWITCHING_MODE)
+    this->set_dsc_mode(CSPI_DSC_AUTO);
+}
+
+// ============================================================================
+// BPMConfig::set_interlock_configuration
+// ============================================================================
+void BPMConfig::set_interlock_configuration (const std::vector<bpm::FPDataType>& vd) 
+  
+  throw (Tango::DevFailed)
+{
+  if (vd.size() != kINTERLOCK_CONFIG_FIELDS)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid parameters",
+                                    (const char *) "InterlockConfiguration property: vector size mismatch - too few or too much parameters passed",
+                                    (const char *) "BPMConfig::set_interlock_configuration");
+  }
+  
+  this->requested_ep_.ilk.mode           = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_MODE_IDX]);
+  this->requested_ep_.ilk.Xlow           = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_XLO_IDX] * kMILLI_TO_NANO_METERS);
+  this->requested_ep_.ilk.Xhigh          = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_XHI_IDX] * kMILLI_TO_NANO_METERS);
+  this->requested_ep_.ilk.Ylow           = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_ZLO_IDX] * kMILLI_TO_NANO_METERS);
+  this->requested_ep_.ilk.Yhigh          = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_ZHI_IDX] * kMILLI_TO_NANO_METERS);
+  this->requested_ep_.ilk.overflow_limit = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_OVFLL_IDX]);
+  this->requested_ep_.ilk.overflow_dur   = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_OVFLD_IDX]);
+  this->requested_ep_.ilk.gain_limit     = static_cast<int>(vd[kINTERLOCK_CONFIG_ILK_GAINL_IDX]);
+}
+
+// ============================================================================
+// BPMConfig::check_env_parameters
+// ============================================================================
+void BPMConfig::check_env_parameters (const CSPI_ENVPARAMS& ep) const 
+  
+  throw (Tango::DevFailed)
+{
+  //------------------------------------------
+  //- TODO: rewrite this using the CSPI consts
+  //------------------------------------------
+  
+  if (ep.trig_mode < kMIN_TRG_MODE || ep.trig_mode > kMAX_TRG_MODE)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid trigger mode specified - valid range is [1,2]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+  
+  if (
+      (ep.switches < kMIN_SWITCHES_MODE || ep.switches > kMAX_SWITCHES_MODE) 
+        &&
+      (ep.switches !=  kAUTO_SWITCHING_MODE)
+     ) 
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid switches mode specified - valid range is [0..15] or 255",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+ 
+  if (ep.gain < kMIN_GAIN || ep.gain > kMAX_GAIN)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid gain specified - valid range is [-100, 0] dBm",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+  
+  if (ep.agc < kMIN_AGC || ep.agc > kMAX_AGC)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid AGC mode specified - valid range is [0, 1]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+  
+  if (ep.dsc < kMIN_DSC || ep.dsc > kMAX_DSC)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid DSC mode specified - valid range is [0, 2]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+ 
+  if (ep.ilk.mode != 0 && ep.ilk.mode != 1 && ep.ilk.mode != 3)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid interlock mode  - valid range is [0,1,3]",
+                                    (const char *) "BPMConfig::set_startup_env_parameters");
+  }
+
+  if (ep.ilk.gain_limit < kMIN_GAIN || ep.ilk.gain_limit > kMAX_GAIN)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid interlock gain limit specified - valid range is [-100, 0] dBm",
+                                    (const char *) "BPMConfig::set_startup_env_parameters");
+  }
+ 
+  if (ep.external_switching < kMIN_SWITCHING_EXT || ep.external_switching > kMAX_SWITCHING_EXT)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid external switching flag value - valid range is [0(internal), 1(external)]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  } 
+
+  if (ep.switching_delay < kMIN_SWITCHING_DELAY )
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid switching delay - valid range is [>0]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }   
+  
+  if (ep.mtncoshft < kMIN_TUNE_COMP || ep.mtncoshft > kMAX_TUNE_COMP)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid tune compensation flag value - valid range is [0(no), 1(yes)]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  } 
+
+  if (ep.mtvcxoffs < kMIN_TUNE_OFFSET || ep.mtvcxoffs > kMAX_TUNE_OFFSET)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid tune compensation offset - valid range is [-500, 500]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  } 
+  
+  if (ep.trig_delay < kMIN_EXT_TRIGGER_DELAY )
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid external trigger delay - valid range is [>0]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+  
+  if (ep.PMoffset < kMIN_PM_OFFSET || ep.PMoffset > kMAX_PM_OFFSET)
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid post mortem offset - valid range is [-512, 512]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }
+  
+  /*
+  if (ep.ddc_maflength < kMIN_MAF_LENGTH )
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid moving average filter length - valid range is [>1]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  }  
+
+  if (ep.ddc_mafdelay < kMIN_MAF_DELAY )
+  {
+    Tango::Except::throw_exception ((const char *) "invalid env. parameter",
+                                    (const char *) "invalid moving averafe filter delay - valid range is [>0]",
+                                    (const char *) "BPMConfig::check_env_parameters");
+  } 
+  */ 
+}
+
+// ============================================================================
+// BPMConfig::compare
+// ============================================================================
+int BPMConfig::compare (const BPMConfig& _cfg)
+{
+  int flags = 0;
+
+  if (this->offsets_ != _cfg.offsets_)
+    flags |= GAINS_OR_OFFSETS_CHANGED;
+  
+  if (this->dd_enabled() != _cfg.dd_enabled())
+    flags |= DD_SOURCE_CHANGED;
+
+  if (this->sa_enabled() != _cfg.sa_enabled())
+    flags |= SA_SOURCE_CHANGED;
+
+  if (this->adc_enabled() != _cfg.adc_enabled())
+    flags |= ADC_SOURCE_CHANGED;
+    
+  //- if (this->get_dd_raw_buffer_depth() != const_cast<BPMConfig&>(_cfg).get_dd_raw_buffer_depth())
+  //-   flags |= DD_RAW_BUFFER_SIZE_CHANGED;
+    
+  //- if (this->get_adc_raw_buffer_depth() != _cfg.get_adc_raw_buffer_depth())
+  //-   flags |= ADC_RAW_BUFFER_SIZE_CHANGED;
+    
+  //- if (this->get_dd_trigger_offset() != _cfg.get_dd_trigger_offset())
+  //-   flags |= DD_TRIGGER_OFFSET_CHANGED;
+  
+  if (this->get_decimation_factor() != _cfg.get_decimation_factor())
+    flags |= DD_DECIMATION_CHANGED;
+  
+  if (this->get_switches_mode() != _cfg.requested_ep_.switches)
+    flags |= SWITCHES_CHANGED; 
+
+  if (this->agc_enabled() != _cfg.requested_ep_.agc)
+    flags |= AGC_CHANGED;
+
+  if (this->get_dsc_mode() != _cfg.requested_ep_.dsc)
+    flags |= DSC_CHANGED;
+    
+  if (! this->agc_enabled() && (this->actual_ep_.gain != _cfg.requested_ep_.gain))
+    flags |= GAIN_CHANGED;
+    
+#if ! defined(_EMBEDDED_DEVICE_)
+  if (this->dd_buffer_freezing_enabled() != _cfg.dd_buffer_freezing_enabled_)
+    flags |= DD_CACHE_STATUS_CHANGED; 
+#endif
+    
+  if (this->external_switching_enabled() != _cfg.requested_ep_.external_switching)
+    flags |= EXT_SWITCHING_CHANGED;
+    
+  if (this->get_switching_delay() != _cfg.requested_ep_.switching_delay)
+    flags |= SWITCHING_DELAY_CHANGED;
+    
+  bool requested_ep_mtncoshft = _cfg.requested_ep_.mtncoshft ? true : false;
+  if (this->tune_compensation_enabled() != requested_ep_mtncoshft)
+    flags |= TUNE_COMPENSATION_CHANGED;
+	
+  if (this->get_tune_offset() != _cfg.requested_ep_.mtvcxoffs)
+    flags |= TUNE_OFFSET_CHANGED;
+
+  if (this->get_external_trigger_delay() != _cfg.requested_ep_.trig_delay)
+    flags |= EXT_TRIGGER_DELAY_CHANGED;
+	 
+  if (this->get_pm_offset() != _cfg.requested_ep_.PMoffset)
+    flags |= PM_OFFSET_CHANGED;	 	 
+        
+  if (this->get_maf_length() != _cfg.requested_ep_.ddc_maflength)
+    flags |= MAF_LENGTH_CHANGED;
+
+  if (this->get_maf_delay() != _cfg.requested_ep_.ddc_mafdelay) 
+    flags |= MAF_DELAY_CHANGED;
+    
+  if (this->get_pos_algorithm() != _cfg.pos_algorithm_)
+    flags |= POS_COMP_ALGO_CHANGED;
+    
+#if 0
+  std::cout << "DD_SOURCE_CHANGED............." << ((flags & DD_SOURCE_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "SA_SOURCE_CHANGED............." << ((flags & SA_SOURCE_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "ADC_SOURCE_CHANGED............" << ((flags & ADC_SOURCE_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "DD_RAW_BUFFER_SIZE_CHANGED...." << ((flags & DD_RAW_BUFFER_SIZE_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "ADC_RAW_BUFFER_SIZE_CHANGED..." << ((flags & ADC_RAW_BUFFER_SIZE_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "DD_TRIGGER_OFFSET_CHANGED....." << ((flags & DD_TRIGGER_OFFSET_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "DD_DECIMATION_CHANGED........." << ((flags & DD_DECIMATION_CHANGED) ? "yes" : "no") << std::endl;
+#if ! defined(_EMBEDDED_DEVICE_)
+  std::cout << "DD_CACHE_STATUS_CHANGED......." << ((flags & DD_CACHE_STATUS_CHANGED) ? "yes" : "no") << std::endl;
+#endif
+  std::cout << "SWITCHES_CHANGED.............." << ((flags & SWITCHES_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "AGC_CHANGED..................." << ((flags & AGC_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "DSC_CHANGED..................." << ((flags & DSC_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "GAIN_CHANGED.................." << ((flags & GAIN_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "GAINS_OR_OFFSETS_CHANGED......" << ((flags & GAINS_OR_OFFSETS_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "EXT_SWITCHING_CHANGED........." << ((flags & EXT_SWITCHING_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "SWITCHING_DELAY_CHANGED......." << ((flags & SWITCHING_DELAY_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "COMPENSATION_TUNE_CHANGED....." << ((flags & TUNE_COMPENSATION_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "OFFSET_TUNE_CHANGED..........." << ((flags & TUNE_OFFSET_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "EXT_TRIGGER_DELAY_CHANGED....." << ((flags & EXT_TRIGGER_DELAY_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "PM_OFFSET_CHANGED............." << ((flags & PM_OFFSET_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "MAF_LENGTH_CHANGED............" << ((flags & MAF_LENGTH_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "MAF_DELAY_CHANGED............." << ((flags & MAF_DELAY_CHANGED) ? "yes" : "no") << std::endl;
+  std::cout << "POS_COMP_ALGO_CHANGED........." << ((flags & POS_COMP_ALGO_CHANGED) ? "yes" : "no") << std::endl;
+#endif
+
+  return flags;
+}
+
+// ============================================================================
+// BPMConfig::actual_to_requested_ep
+// ============================================================================
+void BPMConfig::actual_to_requested_ep (void)
+{
+  this->actual_ep_.mtvcxoffs = this->actual_ep_.pll_status.mt_stat.vcxo_offset;
+  this->actual_ep_.mtncoshft = this->actual_ep_.pll_status.mt_stat.nco_shift;
+  ::memcpy(&this->requested_ep_, &this->actual_ep_, sizeof(CSPI_ENVPARAMS));
+} 
+             
+// ============================================================================
+// bool operator!= (const CSPI_ENVPARAMS&, const CSPI_ENVPARAMS&)
+// ============================================================================
+bool operator!= (const CSPI_ENVPARAMS &env_params_1, const CSPI_ENVPARAMS &env_params_2)
+{
+  size_t cspi_env_base_size = sizeof(cspi_health_t)
+                            + sizeof(cspi_pll_t) 
+                            + sizeof(int)
+                            + sizeof(cspi_feature_t);
+                            
+  size_t size_to_cmp = sizeof(CSPI_ENVPARAMS) - cspi_env_base_size;
+  
+  bool c1 = ::memcmp (&env_params_1.trig_mode, &env_params_2.trig_mode, size_to_cmp) != 0;
+
+  bool c2 = env_params_1.trig_mode != env_params_2.trig_mode;
+
+  return c1 || c2;
+}
+
+// ============================================================================
+// bool operator== (const CSPI_ENVPARAMS&, const CSPI_ENVPARAMS&)
+// ============================================================================
+bool operator== (const CSPI_ENVPARAMS &env_params_1, const CSPI_ENVPARAMS &env_params_2)
+{
+  return ! (env_params_1 != env_params_2);
+}
+
+} // namespace bpm
diff --git a/src/BPMConfig.h b/src/BPMConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..5199e553112d110c036fd54b3486034e0b0793c9
--- /dev/null
+++ b/src/BPMConfig.h
@@ -0,0 +1,653 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_CONFIG_H_
+#define _BPM_CONFIG_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "BPMLocation.h"
+#include "Offsets.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+//- libera default port (generic server and multicast notifications)
+#define GS_DEFAULT_PORT       23271
+#define GS_DEFAULT_MCAST_PORT 0
+//-----------------------------------------------------------------------------
+//- BPM block geometry
+#define kBLOCK_GEOMETRY_45 45.0
+#define kBLOCK_GEOMETRY_90 90.0
+//-----------------------------------------------------------------------------
+//- BPM tasks activity period
+#define kMIN_THREAD_ACTIVITY_PERIOD_MS     75
+#define kDEFAULT_THREAD_ACTIVITY_PERIOD_MS 1000
+#define kMAX_THREAD_ACTIVITY_PERIOD_MS     5000
+//-----------------------------------------------------------------------------
+//- FA cache refresh period
+#define kMIN_FA_CACHE_REFRESH_PERIOD_MS     100
+#define kDEFAULT_FA_CACHE_REFRESH_PERIOD_MS 500
+#define kMAX_FA_CACHE_REFRESH_PERIOD_MS     750
+//-----------------------------------------------------------------------------
+//- max number of DD samples that can be read with/without DD cache enabled
+#define DD_NSAMPLES_MAX_VALUE_CACHE_ENABLED  16384
+#define DD_NSAMPLES_MAX_VALUE_CACHE_DISABLED 250000
+#define DD_NSAMPLES_MAX_VALUE_DECIM_ENABLED  10000
+//-----------------------------------------------------------------------------
+//- min/max number of ADC samples that can be read
+#define kMIN_ADC_RAW_BUFFER_SIZE    8
+#define kMAX_ADC_RAW_BUFFER_SIZE 1024
+//-----------------------------------------------------------------------------
+//- params flag for cspi_[get/set]_env_params function  
+#define kALL_PARAMS ~0
+//-----------------------------------------------------------------------------
+#define kALL_PARAMS_EXCEPT_HEALTH kALL_PARAMS & ~CSPI_ENV_HEALTH
+//-----------------------------------------------------------------------------
+//- number of possible values for "Nb" in booster normal mode
+#define MAX_NB_VALUES 4
+//-----------------------------------------------------------------------------
+//- minimum number of samples that can be read from "data on demand buffer"
+#define NSAMPLES_MIN_VALUE 32
+//-----------------------------------------------------------------------------
+//- default number of samples that can be read from "data on demand buffer"
+#define NSAMPLES_DEFAULT_VALUE 1024
+//-----------------------------------------------------------------------------
+//- default SA history buffer depth
+#define kDEFAULT_SA_HISTORY_DEPTH 1024
+//-----------------------------------------------------------------------------
+//- default num of samples to use for SA pos statistics computation
+#define kDEFAULT_SA_STAT_SAMPLES  256
+//-----------------------------------------------------------------------------
+//- valid range for switches 
+#define kMIN_SWITCHES_MODE   static_cast<int>(0)
+#define kMAX_SWITCHES_MODE   static_cast<int>(15) 
+#define kAUTO_SWITCHING_MODE static_cast<int>(255) 
+//-----------------------------------------------------------------------------
+//- valid range for gain 
+#define kMIN_GAIN static_cast<int>(-100)
+#define kMAX_GAIN static_cast<int>(0)
+//-----------------------------------------------------------------------------
+//- valid range for agc
+#define kMIN_AGC static_cast<int>(0)
+#define kMAX_AGC static_cast<int>(1)
+//-----------------------------------------------------------------------------
+//- valid range for dsc
+#define kMIN_DSC static_cast<int>(0)
+#define kMAX_DSC static_cast<int>(2)
+//-----------------------------------------------------------------------------
+//- valid range for trigger mode
+#define kMIN_TRG_MODE static_cast<int>(1)
+#define kMAX_TRG_MODE static_cast<int>(2)
+//-----------------------------------------------------------------------------
+//- valid range for external source switching
+#define kMIN_SWITCHING_EXT static_cast<int>(0)
+#define kMAX_SWITCHING_EXT static_cast<int>(1)
+//-----------------------------------------------------------------------------
+//- valid range switching delay
+#define kMIN_SWITCHING_DELAY static_cast<int>(0)
+//-----------------------------------------------------------------------------
+//- valid range for compensation tune
+#define kMIN_TUNE_COMP static_cast<int>(0)
+#define kMAX_TUNE_COMP static_cast<int>(1)
+//-----------------------------------------------------------------------------
+//- valid range for offset tune
+#define kMIN_TUNE_OFFSET static_cast<int>(-500)
+#define kMAX_TUNE_OFFSET static_cast<int>(500)
+//-----------------------------------------------------------------------------
+//- valid range for the external trigger delay
+#define kMIN_EXT_TRIGGER_DELAY static_cast<int>(0)
+//-----------------------------------------------------------------------------
+//- valid range for post mortem offset
+#define kMIN_PM_OFFSET static_cast<int>(-512)
+#define kMAX_PM_OFFSET static_cast<int>(512)
+//-----------------------------------------------------------------------------
+#define kLIBERA_STARTUP_CONFIG_FIELDS   18 
+#define kUSER_DEFINED_ENV_PARAMS_FIELDS 4   
+#define kINTERLOCK_CONFIG_FIELDS        8 
+//-----------------------------------------------------------------------------
+//- trunc the gain correction factors to 4 digits: a.bcdefghij -> abcdef 
+#define kGAIN_TRUNC_FACTOR     1000.
+#define kGAIN_TRUNC_FACTOR_INV (1. / kGAIN_TRUNC_FACTOR)
+//-----------------------------------------------------------------------------
+#define kMILLI_TO_NANO_METERS 1000000
+#define kNANO_TO_MILLI_METERS 1.e-6
+//-----------------------------------------------------------------------------
+#define kMIN_MAF_LENGTH static_cast<int>(1)
+#define kMAX_MAF_LENGTH static_cast<int>(129)
+#define kMIN_MAF_DELAY  static_cast<int>(0)
+#define kMAX_MAF_DELAY  static_cast<int>(128)
+//-----------------------------------------------------------------------------
+  
+namespace bpm
+{
+
+// ============================================================================
+//! BPM configuration abstraction class.
+// ============================================================================
+//!
+//! detailed description to be defined
+//!
+// ============================================================================
+class BPMConfig
+{
+  friend class BPM;
+  friend class DataProcessing;
+
+public:
+  // Institute
+  typedef enum
+  {
+    kTANGO_INSTITUTE = 0,
+    kALBA,
+    kESRF,
+    kELETTRA,
+    kSOLEIL,
+  } Institute;
+
+  // Position computation algorithm
+  typedef enum
+  {
+    //- standard algorithm (depends on block geometry)
+    kSTD_POS_ALGO = 0,
+    //- ESRF (very) specific atanh algorithm for its SR
+    kESRF_SR_POS_ALGO,
+    //- invalid identitifer (!!must stay the last in enum!!)
+    kINVALID_POS_ALGO_ID
+  } Algorithm;
+  
+  // BPM block geometry
+  typedef enum
+  {
+    BLOCK_GEOMETRY_45,
+    BLOCK_GEOMETRY_90,
+    BLOCK_GEOMETRY_UNKNOWN
+  } BlockGeometry;
+  
+  //-  possible values for "Nb" in booster normal mode
+  typedef enum
+  {
+    NB_VALUE_00 = 158,
+    NB_VALUE_01 = 632,
+    NB_VALUE_02 = 2528,
+    NB_VALUE_03 = 10112
+  } NbValues;
+
+  // BPMConfig default ctor 
+  BPMConfig (Tango::DeviceImpl * host_device = 0);
+
+  // BPMConfig copy ctor
+  // \param src The source configuration.
+  BPMConfig (const BPMConfig & src);
+
+  // BPMConfig operator=
+  // \param src The source configuration.
+  BPMConfig & operator= (const BPMConfig & src);
+
+  // Dtor
+  virtual ~BPMConfig (void);
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  // Set the Libera IP configuration
+  // \param ip_addr The Libera IP address
+  // \param mcast_ip_addr The client multicast IP address for asynch notification
+  // \param gs_port The generic server port
+  // \param mcast_port The client multicast port for asynch notification
+  void set_ip_config (const std::string & ip_addr, 
+                      int port, 
+                      const std::string & mcast_ip_addr, 
+                      int mcast_port = GS_DEFAULT_MCAST_PORT);
+#endif //- _EMBEDDED_DEVICE_
+
+  // Enable/Disable buffer freezing
+  void enable_dd_buffer_freezing (void);
+  void disable_dd_buffer_freezing (void);
+  bool dd_buffer_freezing_enabled (void) const;
+
+  // Set/Get the BPM offsets and parameters 
+  void set_offsets (const BPMOffsets & _src) throw (Tango::DevFailed);
+  const BPMOffsets & get_offsets (void) const;
+
+  //- Controls wether or not the BBA offsets are taken into account when 
+  //- computing the offsets passed to the FPGA process
+  void pass_bba_offsets_to_fpga (bool yes_or_no);
+  
+  // Set/Get BPM location 
+  void set_location (BPMLocation bpm_loc) throw (Tango::DevFailed);
+  BPMLocation get_location (void) const;
+
+  // Set/Get block geometry
+  void set_block_geometry (BlockGeometry bg);
+  BlockGeometry get_block_geometry (void) const;
+
+  // Set/get switches mode P[0..15]
+  void set_switches_mode (short mode) throw (Tango::DevFailed);
+  short get_switches_mode (void) const;
+  bool auto_switching_enabled (void) const;
+  
+  // Set interlock configuration
+  void set_interlock_configuration (const std::vector<bpm::FPDataType>& vd) 
+    throw (Tango::DevFailed);
+    
+  // Dump offsets, env. & con. parameters
+  void dump_offsets(void) const;
+  void dump_env_parameters (void) const;
+  void dump_env_parameters (const CSPI_ENVPARAMS &ep) const;
+  void dump_con_parameters (void) const;
+
+  // Set/Get the dd-data buffer depth
+  void set_dd_raw_buffer_depth (size_t depth);
+  size_t get_dd_raw_buffer_depth (void);
+
+  // Set/Get the adc-data buffer depth
+  void set_adc_raw_buffer_depth (size_t depth);
+  size_t get_adc_raw_buffer_depth (void) const;
+  
+  // Enable/Disable external trigger 
+  // Influences the TANGO device behaviour not the Libera itself
+  void enable_external_trigger (void);
+  void disable_external_trigger (void);
+  bool external_trigger_enabled (void) const;
+
+  // Set/Get DD thread activity period 
+  void set_dd_thread_activity_period (size_t period);
+  size_t get_dd_thread_activity_period (void) const;
+
+  // Set/Get the SA thread activity period 
+  void set_sa_thread_activity_period (size_t period);
+  size_t get_sa_thread_activity_period (void) const;
+  
+  // Set/Get the ADC thread activity period 
+  void set_adc_thread_activity_period (size_t period);
+  size_t get_adc_thread_activity_period (void) const;
+  
+  // Set/Get the FA cache refresh period in msecs 
+  void set_fa_cache_refresh_period (size_t period);
+  size_t get_fa_cache_refresh_period (void) const;
+
+  // Enables/disables SA 
+  void enable_sa (void);
+  void disable_sa (void);
+  bool sa_enabled (void) const;
+
+  // Enables/disables PM
+  void enable_pm (void);
+  void disable_pm (void);
+  bool pm_enabled (void) const;
+
+  // Enables/disables ADC
+  void enable_adc (void);
+  void disable_adc (void);
+  bool adc_enabled (void) const;
+
+  // Enables/disables DD
+  void enable_dd (void);
+  void disable_dd (void);
+  bool dd_enabled (void) const;
+
+  // Set/get X low limit (for beam position interlock)
+  void set_x_low_limit (bpm::FPDataType xlo);
+  bpm::FPDataType get_x_low_limit (void) const;
+
+  // Set/get X hi limit (for beam position interlock)
+  void set_x_high_limit (bpm::FPDataType xlo);
+  bpm::FPDataType get_x_high_limit (void) const;
+
+  // Set/Get Z low limit (for beam position interlock)
+  void set_z_low_limit (bpm::FPDataType xlo);
+  bpm::FPDataType get_z_low_limit (void) const;
+
+  // Set/Get Z hi limit (for beam position interlock)
+  void set_z_high_limit (bpm::FPDataType xlo);
+  bpm::FPDataType get_z_high_limit (void) const;
+
+  // Set/Get the DD decimation factor
+  void set_decimation_factor (int df);
+  int get_decimation_factor (void) const;
+
+  // Set/Get the max DD buffer size for "decimation on"
+  void set_max_dd_buffer_depth_for_dec_on (size_t depth);
+  size_t get_max_dd_buffer_depth_for_dec_on  (void) const;
+  
+  // Set/Get the SA history depth (in num of samples)
+  void set_sa_history_depth (size_t depth);
+  size_t get_sa_history_depth (void) const;
+
+  // Set/Get the SA RMS num samples
+  void set_sa_stats_num_samples (size_t nsamples);
+  size_t get_sa_rms_num_samples (void) const;
+ 
+  // Set/Get the DD trigger offset (in num of samples (i.e. turns))
+  void set_dd_trigger_offset (unsigned long);
+  unsigned long get_dd_trigger_offset (void) const;
+    
+  // Enable auto switching on sa activation ?
+  void enable_auto_switching_on_sa_activation (bool behaviour);
+  bool enable_auto_switching_on_sa_activation (void) const;
+  
+  // Enable DSC activation vs SA activation ?
+  void enable_dsc_on_auto_switching_activation (bool behaviour);
+  bool enable_dsc_on_auto_switching_activation (void) const;
+   
+  // Set/Get the Libera input gain
+  void set_gain (int g);
+  int get_gain (void) const;
+ 
+  // Enables/disables AGC
+  void enable_agc (void);
+  void disable_agc (void);
+  bool agc_enabled (void) const;
+
+  // DSC mode
+  void set_dsc_mode (const short mode);
+  short get_dsc_mode (void) const;
+  bool dsc_enabled (void) const;
+
+  // Enable/disable external switching
+  void enable_external_switching (void);
+  void disable_external_switching (void);
+  bool external_switching_enabled (void) const;   
+  
+  // Set/Get the switching delay
+  void set_switching_delay (int sd);
+  int get_switching_delay (void) const;   
+  
+  // Enable/disable tune compensation
+  void enable_tune_compensation (void);
+  void disable_tune_compensation (void);
+  bool tune_compensation_enabled (void) const;   
+  
+  /**
+   * get/Set the offset tune (mtncoshft, mtcxoffs)
+   */
+  void set_tune_offset (int t);
+  int  get_tune_offset (void) const;   
+
+  // Set/Get the external trigger delay
+  void set_external_trigger_delay (int etd);
+  int get_external_trigger_delay (void) const;  
+
+  // Set/Get post mortem offset
+  void set_pm_offset (int pmo);
+  int get_pm_offset (void) const;  
+
+  // Returns the Libera model (0:e-, 1:br, 2:ph)
+  unsigned short libera_model () const;
+
+  // Does the Libera have MAF support (on FPGA side)
+  bool has_maf_support () const;
+  
+  // Set/Get moving average filter length
+  void set_maf_length (int mafl);
+  int get_maf_length (void) const; 
+
+  // Set/Get moving average filterdelay
+  void set_maf_delay (int mafd);
+  int  get_maf_delay (void) const;    
+
+  // Enable/Disable optional data
+  void enable_dd_optional_data ();
+  void disable_dd_optional_data ();
+  bool dd_optional_data_enabled () const;
+
+  void enable_sa_optional_data ();
+  void disable_sa_optional_data ();
+  bool sa_optional_data_enabled () const;
+
+  void enable_adc_optional_data ();
+  void disable_adc_optional_data ();
+  bool adc_optional_data_enabled () const;
+  
+  void enable_sa_history_optional_data ();
+  void disable_sa_history_optional_data ();
+  bool sa_history_optional_data_enabled () const;
+
+  //- set/get institute
+  void set_institute (int i);
+  int get_institute (void) const;
+  
+  //- set/get position computation algorithm
+  void set_pos_algorithm (int i);
+  int get_pos_algorithm (void) const;
+
+  
+  //- enable/diable local SA pos computation
+  void enable_local_sa_pos_computation ();
+  void disable_local_sa_pos_computation ();
+  bool local_sa_pos_computation_enabled () const;
+  
+  // returns the current Libera env. params
+  const CSPI_ENVPARAMS& get_current_env_parameters (void) const;
+    
+  //- tricky copy of actual env. params into requested params
+  //- why such an ugly method? ask ITech please! 
+  void actual_to_requested_ep (void);
+   
+private:
+
+  // Modifiactions on the configuration
+  typedef enum
+  {
+    DD_RAW_BUFFER_SIZE_CHANGED  = BIT(0),
+    DD_TRIGGER_OFFSET_CHANGED   = BIT(1),
+    DD_DECIMATION_CHANGED       = BIT(2),
+    DD_SOURCE_CHANGED           = BIT(3),
+    SA_SOURCE_CHANGED           = BIT(4),
+    SWITCHES_CHANGED            = BIT(5),
+    AGC_CHANGED                 = BIT(6),
+    DSC_CHANGED                 = BIT(7),
+    GAIN_CHANGED                = BIT(8),
+    ADC_RAW_BUFFER_SIZE_CHANGED = BIT(9),
+    ADC_SOURCE_CHANGED          = BIT(10),
+    GAINS_OR_OFFSETS_CHANGED    = BIT(11),
+    EXT_TRIGGER_DELAY_CHANGED   = BIT(12),
+	  PM_OFFSET_CHANGED           = BIT(13),
+	  MAF_LENGTH_CHANGED				  = BIT(14),
+    MAF_DELAY_CHANGED           = BIT(15),
+	  EXT_SWITCHING_CHANGED       = BIT(16),
+    SWITCHING_DELAY_CHANGED     = BIT(17),
+	  TUNE_COMPENSATION_CHANGED   = BIT(18),
+	  TUNE_OFFSET_CHANGED         = BIT(19),
+    POS_COMP_ALGO_CHANGED       = BIT(20)
+#if ! defined(_EMBEDDED_DEVICE_)
+    , DD_CACHE_STATUS_CHANGED   = BIT(31)
+#endif
+  } Modifications;
+
+  // Check any modifiaction on this configuration
+  int compare (const BPMConfig& _cfg);
+
+  // Computes actual offsets from both BLOCK and HW offsets
+  void compute_actual_offsets (CSPI_ENVPARAMS &ep, bool auto_switching_enabled)
+    throw (Tango::DevFailed); 
+
+  // Validate the env. params value. Throws an exception in case of problem!
+  void check_env_parameters (const CSPI_ENVPARAMS& ep) const 
+    throw (Tango::DevFailed);
+  
+  // The BPM offsets and parameters
+  BPMOffsets offsets_;
+  
+  // Should the BBA offsets be passed to the FPGA process
+  bool pass_bba_offsets_to_fpga_;
+ 
+  // The requested CPSI environment parameters
+  CSPI_ENVPARAMS requested_ep_;
+
+  // The actual CPSI environment parameters
+  CSPI_ENVPARAMS actual_ep_;
+
+  // The CPSI connection parameters for SA mode
+  CSPI_CONPARAMS_EBPP cp_sa_;
+
+  // The CPSI connection parameters for the service task
+  CSPI_CONPARAMS cp_srv_;
+
+  // The CPSI connection parameters for ADC mode
+  CSPI_CONPARAMS cp_adc_;
+
+  // The CPSI connection parameters for DD mode
+  CSPI_CONPARAMS_EBPP cp_dd_;
+
+  // The DD data buffer depth
+  size_t dd_raw_buffer_depth_;
+  size_t max_dd_buffer_depth_for_dec_on_;
+
+  // The ADC data buffer depth
+  size_t adc_raw_buffer_depth_; 
+
+  // The SA data history buffer depth
+  size_t sa_data_history_buffer_depth_;
+ 
+  // The num of SA samples use for RMS pos computation
+  size_t sa_stats_num_samples_;
+
+#if ! defined(_EMBEDDED_DEVICE_)
+  // The Libera IP addr
+  std::string ip_addr_;
+
+  // The generic server port
+  int gs_port_;
+
+  // The Libera Multicast IP addr
+  std::string mcast_ip_addr_;
+
+  // The multicast port
+  int mcast_port_;
+#endif
+
+  // Buffer freezing 
+  bool dd_buffer_freezing_enabled_;
+
+  // External trigger   
+  bool external_trigger_enabled_;
+
+  // DD trigger offset
+  unsigned long dd_trigger_offset_;
+
+  // "DD" thread activity period in ms   
+  size_t dd_thread_activity_period_;
+
+  // "SA" thread activity period in ms   
+  size_t sa_thread_activity_period_;
+
+  // "ADC" thread activity period in ms   
+  size_t adc_thread_activity_period_;
+
+  // "FA" cache refresh period  
+  size_t fa_cache_refresh_period_;
+
+  // Pre-computed offsets values
+  bpm::FPDataType Kx;
+  bpm::FPDataType Kz;
+
+  bpm::FPDataType Xoffset_local;
+  bpm::FPDataType Xoffset_fpga;
+
+  bpm::FPDataType Zoffset_local;
+  bpm::FPDataType Zoffset_fpga;
+
+  bpm::FPDataType Qoffset_local;
+  bpm::FPDataType Qoffset_fpga;
+
+  bpm::FPDataType VaGainCorrection;
+  bpm::FPDataType VbGainCorrection;
+  bpm::FPDataType VcGainCorrection;
+  bpm::FPDataType VdGainCorrection;
+
+#if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  IntOffsetDataType int_Kx;
+  IntOffsetDataType int_Kz;
+  
+  IntOffsetDataType int_Xoffset_local;
+  IntOffsetDataType int_Zoffset_local;
+  IntOffsetDataType int_Qoffset_local;
+  
+  IntOffsetDataType int_VaGainCorrection;
+  IntOffsetDataType int_VbGainCorrection;
+  IntOffsetDataType int_VcGainCorrection;
+  IntOffsetDataType int_VdGainCorrection;
+#endif
+
+  // BPM location
+  BPMLocation location_;
+
+  // BPM's block geometry
+  BlockGeometry block_geometry_;
+
+  // Data sources flag
+  bool sa_enabled_;
+  bool pm_enabled_;
+  bool adc_enabled_;
+  bool dd_enabled_;
+
+  // Optional data
+  bool dd_optional_data_enabled_;
+  bool sa_optional_data_enabled_;
+  bool adc_optional_data_enabled_;
+  bool sa_history_optional_data_enabled_;
+  
+  // Auto-switching activation vs SA activation 
+  bool enable_auto_switching_on_sa_activation_;
+
+  // DSC activation vs SA activation 
+  bool enable_dsc_on_auto_switching_activation_;
+  
+  //- enable/disable local SA computation
+  bool local_sa_pos_computation_enabled_;
+  
+  // where are we running?
+  int institute_;
+
+  // which pos. computation algorithm should we use?
+  int pos_algorithm_;
+
+  //- host device for logging
+  Tango::DeviceImpl * host_device_;
+};
+
+// Standalone operator!= - compares two env. parameters structs
+// \param env_params_1 The CSPI_ENVPARAMS to be compared to this->env_params_2
+// \param env_params_2 The CSPI_ENVPARAMS to be compared to this->env_params_1
+bool operator!= (const CSPI_ENVPARAMS &env_params_1, const CSPI_ENVPARAMS &env_params_2);
+
+// Standalone operator== - compares two env. parameters structs
+// \param env_params_1 The CSPI_ENVPARAMS to be compared to this->env_params_2
+// \param env_params_2 The CSPI_ENVPARAMS to be compared to this->env_params_1
+bool operator== (const CSPI_ENVPARAMS &env_params_1, const CSPI_ENVPARAMS &env_params_2);
+  
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "BPMConfig.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_CONFIG_H_
diff --git a/src/BPMConfig.i b/src/BPMConfig.i
new file mode 100644
index 0000000000000000000000000000000000000000..38938d2b2383f0a44df2d0130ab076859a162eef
--- /dev/null
+++ b/src/BPMConfig.i
@@ -0,0 +1,980 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// BPMConfig::enable_dd_buffer_freezing
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_dd_buffer_freezing (void)
+{
+  this->dd_buffer_freezing_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_dd_buffer_freezing
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_dd_buffer_freezing (void)
+{
+  this->dd_buffer_freezing_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::dd_buffer_freezing_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::dd_buffer_freezing_enabled (void) const
+{
+  return this->dd_buffer_freezing_enabled_;
+}
+
+
+#if ! defined(_EMBEDDED_DEVICE_)
+// ============================================================================
+// BPMConfig::set_ip_config
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_ip_config (const std::string & _ip_addr, 
+                                           int _gs_port, 
+                                           const std::string & _mcast_ip_addr, 
+                                           int _mcast_port)
+{
+  this->ip_addr_ = _ip_addr;
+  this->mcast_ip_addr_ = _mcast_ip_addr;
+  this->gs_port_ = _gs_port;
+  this->mcast_port_ = _mcast_port;
+}
+#endif //- _EMBEDDED_DEVICE_
+
+// ============================================================================
+// BPMConfig::enable_external_trigger
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_external_trigger (void)
+{
+  this->external_trigger_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_external_trigger
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_external_trigger (void)
+{
+  this->external_trigger_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::external_trigger_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::external_trigger_enabled (void) const
+{
+  return this->external_trigger_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::set_dd_thread_activity_period
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_dd_thread_activity_period (size_t _period)
+{
+  if (_period < kMIN_THREAD_ACTIVITY_PERIOD_MS)
+    this->dd_thread_activity_period_ = kMIN_THREAD_ACTIVITY_PERIOD_MS;
+  else if (_period > kMAX_THREAD_ACTIVITY_PERIOD_MS)
+    this->dd_thread_activity_period_ = kMAX_THREAD_ACTIVITY_PERIOD_MS;
+  else
+    this->dd_thread_activity_period_ = _period;
+}
+
+// ============================================================================
+// BPMConfig::get_dd_thread_activity_period
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_dd_thread_activity_period (void) const
+{
+  return this->dd_thread_activity_period_;
+}
+
+// ============================================================================
+// BPMConfig::set_sa_thread_activity_period
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_sa_thread_activity_period (size_t _period)
+{
+  if (_period < kMIN_THREAD_ACTIVITY_PERIOD_MS)
+    this->sa_thread_activity_period_ = kMIN_THREAD_ACTIVITY_PERIOD_MS;
+  else if (_period > kMAX_THREAD_ACTIVITY_PERIOD_MS)
+    this->sa_thread_activity_period_ = kMAX_THREAD_ACTIVITY_PERIOD_MS;
+  else
+    this->sa_thread_activity_period_ = _period;
+}
+
+// ============================================================================
+// BPMConfig::get_sa_thread_activity_period
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_sa_thread_activity_period (void) const
+{
+  return this->sa_thread_activity_period_;
+}
+
+// ============================================================================
+// BPMConfig::set_adc_thread_activity_period
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_adc_thread_activity_period (size_t _period)
+{
+  if (_period < kMIN_THREAD_ACTIVITY_PERIOD_MS)
+    this->adc_thread_activity_period_ = kMIN_THREAD_ACTIVITY_PERIOD_MS;
+  else if (_period > kMAX_THREAD_ACTIVITY_PERIOD_MS)
+    this->adc_thread_activity_period_ = kMAX_THREAD_ACTIVITY_PERIOD_MS;
+  else
+    this->adc_thread_activity_period_ = _period;
+}
+
+// ============================================================================
+// BPMConfig::get_adc_thread_activity_period
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_adc_thread_activity_period (void) const
+{
+  return this->adc_thread_activity_period_;
+}
+
+// ============================================================================
+// BPMConfig::set_fa_cache_refresh_period
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_fa_cache_refresh_period (size_t _period)
+{
+  if (_period < kMIN_FA_CACHE_REFRESH_PERIOD_MS)
+    this->fa_cache_refresh_period_ = kMIN_FA_CACHE_REFRESH_PERIOD_MS;
+  else if (_period > kMAX_FA_CACHE_REFRESH_PERIOD_MS)
+    this->fa_cache_refresh_period_ = kMAX_FA_CACHE_REFRESH_PERIOD_MS;
+  else
+    this->fa_cache_refresh_period_ = _period;
+}
+
+// ============================================================================
+// BPMConfig::get_fa_cache_refresh_period
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_fa_cache_refresh_period (void) const
+{
+  return this->fa_cache_refresh_period_;
+}
+
+// ============================================================================
+// BPMConfig::get_offsets
+// ============================================================================
+INLINE_IMPL const BPMOffsets & BPMConfig::get_offsets (void) const
+{
+  return this->offsets_;
+}
+
+// ============================================================================
+// BPMConfig::pass_bba_offsets_to_fpga
+// ============================================================================
+INLINE_IMPL void BPMConfig::pass_bba_offsets_to_fpga (bool yes_or_no)
+{
+  this->pass_bba_offsets_to_fpga_ = yes_or_no;
+}
+  
+// ============================================================================
+// BPMConfig::get_location
+// ============================================================================
+INLINE_IMPL BPMLocation BPMConfig::get_location (void) const
+{
+  return this->location_;
+}
+
+// ============================================================================
+// BPMConfig::set_dd_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_dd_raw_buffer_depth (size_t _depth)
+{
+  size_t max_dd_samples = DD_NSAMPLES_MAX_VALUE_CACHE_DISABLED;
+  
+#if ! defined(_EMBEDDED_DEVICE_)
+  if (this->dd_buffer_freezing_enabled_)
+    max_dd_samples = DD_NSAMPLES_MAX_VALUE_CACHE_ENABLED;
+#endif
+
+  if (this->get_decimation_factor() == 64)
+    max_dd_samples = this->get_max_dd_buffer_depth_for_dec_on();  
+      
+  this->dd_raw_buffer_depth_ = (_depth <= max_dd_samples) 
+                             ? _depth 
+                             : max_dd_samples;
+}
+
+// ============================================================================
+// BPMConfig::get_dd_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_dd_raw_buffer_depth (void)
+{
+  if (   
+        this->get_decimation_factor() == 64 
+      && 
+        this->dd_raw_buffer_depth_ > this->get_max_dd_buffer_depth_for_dec_on()
+     )
+  {
+     this->dd_raw_buffer_depth_ = this->get_max_dd_buffer_depth_for_dec_on();
+  }
+  
+  return this->dd_raw_buffer_depth_;
+}
+
+// ============================================================================
+// BPMConfig::set_dd_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_max_dd_buffer_depth_for_dec_on (size_t _depth)
+{
+  this->max_dd_buffer_depth_for_dec_on_ = _depth;
+}
+
+// ============================================================================
+// BPMConfig::get_dd_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_max_dd_buffer_depth_for_dec_on (void) const
+{
+  return this->max_dd_buffer_depth_for_dec_on_;
+}
+
+// ============================================================================
+// BPMConfig::set_adc_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_adc_raw_buffer_depth (size_t _depth)
+{
+  if (_depth < kMIN_ADC_RAW_BUFFER_SIZE)
+     _depth = kMIN_ADC_RAW_BUFFER_SIZE;
+  else if (_depth > kMAX_ADC_RAW_BUFFER_SIZE)
+     _depth = kMAX_ADC_RAW_BUFFER_SIZE;
+  this->adc_raw_buffer_depth_ = _depth;
+}
+
+// ============================================================================
+// BPMConfig::get_adc_raw_buffer_depth
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_adc_raw_buffer_depth (void) const
+{
+  return this->adc_raw_buffer_depth_;
+}
+
+// ============================================================================
+// BPMConfig::set_sa_history_depth
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_sa_history_depth (size_t _depth)
+{
+  this->sa_data_history_buffer_depth_ = _depth;
+}
+
+// ============================================================================
+// BPMConfig::get_sa_history_depth
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_sa_history_depth (void) const
+{
+  return this->sa_data_history_buffer_depth_;
+}
+
+// ============================================================================
+// BPMConfig::set_sa_stats_num_samples
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_sa_stats_num_samples (size_t _n)
+{
+  if (_n > this->sa_data_history_buffer_depth_)
+    this->sa_stats_num_samples_ = this->sa_data_history_buffer_depth_;
+  else
+    this->sa_stats_num_samples_ = _n;
+}
+
+// ============================================================================
+// BPMConfig::get_sa_rms_num_samples
+// ============================================================================
+INLINE_IMPL size_t BPMConfig::get_sa_rms_num_samples (void) const
+{
+  return this->sa_stats_num_samples_; 
+}
+
+// ============================================================================
+// BPMConfig::get_block_geometry
+// ============================================================================
+INLINE_IMPL BPMConfig::BlockGeometry BPMConfig::get_block_geometry (void) const
+{
+  return this->block_geometry_;
+}
+
+// ============================================================================
+// BPMConfig::set_block_geometry
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_block_geometry (BPMConfig::BlockGeometry _bg)
+{
+  this->block_geometry_ = _bg;
+}
+
+// ============================================================================
+// BPMConfig::enable_sa
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_sa (void)
+{
+  this->sa_enabled_ = true;
+  if (this->enable_auto_switching_on_sa_activation_)
+    this->set_switches_mode(kAUTO_SWITCHING_MODE);
+}
+
+// ============================================================================
+// BPMConfig::disable_sa
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_sa (void)
+{
+  this->sa_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::sa_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::sa_enabled (void) const
+{
+  return this->sa_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_pm
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_pm (void)
+{
+  this->pm_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_pm
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_pm (void)
+{
+  this->pm_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::pm_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::pm_enabled (void) const
+{
+  return this->pm_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_adc
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_adc (void)
+{
+  this->adc_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_adc
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_adc (void)
+{
+  this->adc_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::adc_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::adc_enabled (void) const
+{
+  return this->adc_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_dd
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_dd (void)
+{
+  this->dd_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_dd
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_dd (void)
+{
+  this->dd_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::dd_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::dd_enabled (void) const
+{
+  return this->dd_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::set_gain
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_gain (int g)
+{
+  this->requested_ep_.gain = g;
+}
+
+// ============================================================================
+// BPMConfig::get_gain
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_gain (void) const
+{
+  return this->actual_ep_.gain;
+}
+
+// ============================================================================
+// BPMConfig::set_x_low_limit
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_x_low_limit (bpm::FPDataType _v)
+{
+  this->requested_ep_.ilk.Xlow = static_cast < int >(_v);
+}
+
+// ============================================================================
+// BPMConfig::get_x_low_limit
+// ============================================================================
+INLINE_IMPL bpm::FPDataType BPMConfig::get_x_low_limit (void) const
+{
+  return static_cast < bpm::FPDataType >(this->actual_ep_.ilk.Xlow);
+}
+
+// ============================================================================
+// BPMConfig::set_x_high_limit
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_x_high_limit (bpm::FPDataType _v)
+{
+  this->requested_ep_.ilk.Xhigh = static_cast < int >(_v);
+}
+
+// ============================================================================
+// BPMConfig::get_x_high_limit
+// ============================================================================
+INLINE_IMPL bpm::FPDataType BPMConfig::get_x_high_limit (void) const
+{
+  return static_cast < bpm::FPDataType >(this->actual_ep_.ilk.Xhigh);
+}
+
+// ============================================================================
+// BPMConfig::set_z_low_limit
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_z_low_limit (bpm::FPDataType _v)
+{
+  this->requested_ep_.ilk.Ylow = static_cast < int >(_v);
+}
+
+// ============================================================================
+// BPMConfig::get_z_low_limit
+// ============================================================================
+INLINE_IMPL bpm::FPDataType BPMConfig::get_z_low_limit (void) const
+{
+  return static_cast < bpm::FPDataType >(this->actual_ep_.ilk.Ylow);
+}
+
+// ============================================================================
+// BPMConfig::set_z_high_limit
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_z_high_limit (bpm::FPDataType _v)
+{
+  this->requested_ep_.ilk.Yhigh = static_cast < int >(_v);
+}
+
+// ============================================================================
+// BPMConfig::get_z_high_limit
+// ============================================================================
+INLINE_IMPL bpm::FPDataType BPMConfig::get_z_high_limit (void) const
+{
+  return static_cast < bpm::FPDataType >(this->actual_ep_.ilk.Yhigh);
+}
+
+// ============================================================================
+// BPMConfig::set_decimation_factor
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_decimation_factor (int _df)
+{
+  this->cp_dd_.dec = (_df <= 1) ? 1 : 64;
+}
+
+// ============================================================================
+// BPMConfig::get_decimation_factor
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_decimation_factor (void) const
+{
+  return this->cp_dd_.dec;
+}
+
+// ============================================================================
+// BPMConfig::set_dd_trigger_offset
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_dd_trigger_offset (unsigned long _toff)
+{
+  this->dd_trigger_offset_ = _toff;
+}
+
+// ============================================================================
+// BPMConfig::get_dd_trigger_offset
+// ============================================================================
+INLINE_IMPL unsigned long BPMConfig::get_dd_trigger_offset (void) const
+{
+  return this->dd_trigger_offset_;
+}
+
+// ============================================================================
+// BPMConfig::get_switches_mode
+// ============================================================================
+INLINE_IMPL short BPMConfig::get_switches_mode (void) const
+{
+  return static_cast<short>(this->actual_ep_.switches);
+}
+
+// ============================================================================
+// BPMConfig::auto_switching_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::auto_switching_enabled (void) const
+{
+  return this->actual_ep_.switches == kAUTO_SWITCHING_MODE;
+}
+
+// ============================================================================
+// BPMConfig::enable_auto_switching_on_sa_activation
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_auto_switching_on_sa_activation (bool behaviour)
+{
+  this->enable_auto_switching_on_sa_activation_ = behaviour;
+}
+
+// ============================================================================
+// BPMConfig::enable_auto_switching_on_sa_activation
+// ============================================================================
+INLINE_IMPL bool BPMConfig::enable_auto_switching_on_sa_activation (void) const
+{
+  return this->enable_auto_switching_on_sa_activation_;
+}
+   
+// ============================================================================
+// BPMConfig::enable_dsc_on_auto_switching_activation
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_dsc_on_auto_switching_activation (bool behaviour)
+{
+  this->enable_dsc_on_auto_switching_activation_ = behaviour;
+}
+
+// ============================================================================
+// BPMConfig::enable_dsc_on_auto_switching_activation
+// ============================================================================
+INLINE_IMPL bool BPMConfig::enable_dsc_on_auto_switching_activation (void) const
+{
+  return this->enable_dsc_on_auto_switching_activation_;
+}
+
+// ============================================================================
+// BPMConfig::get_current_env_parameters
+// ============================================================================
+INLINE_IMPL const CSPI_ENVPARAMS& BPMConfig::get_current_env_parameters (void) const
+{
+  return this->actual_ep_;
+}
+
+// ============================================================================
+// BPMConfig::enable_agc
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_agc (void)
+{
+  this->requested_ep_.agc = 1;
+}
+
+// ============================================================================
+// BPMConfig::disable_agc
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_agc (void)
+{
+   this->requested_ep_.agc = 0;
+}
+
+// ============================================================================
+// BPMConfig::agc_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::agc_enabled (void) const
+{
+  return this->actual_ep_.agc;
+}
+
+// ============================================================================
+// BPMConfig::set_dsc_mode
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_dsc_mode (const short _mode)
+{
+  switch (_mode)
+  {
+    case CSPI_DSC_OFF:
+    case CSPI_DSC_UNITY:
+    case CSPI_DSC_AUTO:
+    case CSPI_DSC_SAVE_LASTGOOD:
+      this->requested_ep_.dsc = static_cast<int>(_mode);
+      break;
+    default:
+      break;
+  }     
+}
+
+// ============================================================================
+// BPMConfig::get_dsc_mode
+// ============================================================================
+INLINE_IMPL short BPMConfig::get_dsc_mode (void) const
+{
+  return static_cast<short>(this->actual_ep_.dsc);
+}
+
+// ============================================================================
+// BPMConfig::dsc_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::dsc_enabled (void) const
+{
+  return this->actual_ep_.dsc != static_cast<short>(CSPI_DSC_OFF);
+}
+
+// ============================================================================
+// BPMConfig::enable_external_switching
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_external_switching (void)
+{
+  this->requested_ep_.external_switching = 1;
+}
+
+// ============================================================================
+// BPMConfig::disable_external_switching
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_external_switching (void)
+{
+   this->requested_ep_.external_switching = 0;
+}
+
+// ============================================================================
+// BPMConfig::external_switching
+// ============================================================================
+INLINE_IMPL bool BPMConfig::external_switching_enabled (void) const
+{
+  return this->actual_ep_.external_switching;
+}
+
+// ============================================================================
+// BPMConfig::enable_dd_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_dd_optional_data (void)
+{
+  this->dd_optional_data_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_dd_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_dd_optional_data (void)
+{
+  this->dd_optional_data_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::dd_optional_data_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::dd_optional_data_enabled (void) const
+{
+  return this->dd_optional_data_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_sa_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_sa_optional_data (void)
+{
+  this->sa_optional_data_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_sa_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_sa_optional_data (void)
+{
+  this->sa_optional_data_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::sa_optional_data_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::sa_optional_data_enabled (void) const
+{
+  return this->sa_optional_data_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_adc_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_adc_optional_data (void)
+{
+  this->adc_optional_data_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_adc_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_adc_optional_data (void)
+{
+  this->adc_optional_data_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::adc_optional_data_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::adc_optional_data_enabled (void) const
+{
+  return this->adc_optional_data_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::enable_sa_history_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_sa_history_optional_data (void)
+{
+  this->sa_history_optional_data_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_sa_history_optional_data
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_sa_history_optional_data (void)
+{
+  this->sa_history_optional_data_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::sa_history_optional_data_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::sa_history_optional_data_enabled (void) const
+{
+  return this->sa_history_optional_data_enabled_;
+}
+ 
+// ============================================================================
+// BPMConfig::enable_local_sa_pos_computation
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_local_sa_pos_computation (void)
+{
+  this->local_sa_pos_computation_enabled_ = true;
+}
+
+// ============================================================================
+// BPMConfig::disable_local_sa_pos_computation
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_local_sa_pos_computation (void)
+{
+  this->local_sa_pos_computation_enabled_ = false;
+}
+
+// ============================================================================
+// BPMConfig::local_sa_pos_computation_enabled
+// ============================================================================
+INLINE_IMPL bool BPMConfig::local_sa_pos_computation_enabled (void) const
+{
+  return this->local_sa_pos_computation_enabled_;
+}
+
+// ============================================================================
+// BPMConfig::set_switching_delay
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_switching_delay (int t)
+{
+  this->requested_ep_.switching_delay = t;
+}
+
+// ============================================================================
+// BPMConfig::get_switching_delay
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_switching_delay (void) const
+{
+  return this->actual_ep_.switching_delay;
+}
+
+// ============================================================================
+// BPMConfig::enable_tune_compensation
+// ============================================================================
+INLINE_IMPL void BPMConfig::enable_tune_compensation (void)
+{
+  // mtncoshft is write only! To read nco_shift has to be used.
+  this->requested_ep_.mtncoshft = 1;
+}
+
+// ============================================================================
+// BPMConfig::disable_tune_compensation
+// ============================================================================
+INLINE_IMPL void BPMConfig::disable_tune_compensation (void)
+{
+	// mtncoshft is write only! To read nco_shift has to be used.
+  this->requested_ep_.mtncoshft = 0;
+}
+
+// ============================================================================
+// BPMConfig::compensation_tune
+// ============================================================================
+INLINE_IMPL bool BPMConfig::tune_compensation_enabled (void) const
+{
+  return this->actual_ep_.pll_status.mt_stat.nco_shift ? true : false;
+}
+
+// ============================================================================
+// BPMConfig::set_tune_offset
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_tune_offset (int t)
+{
+  //- mtvcxoffs is write only! 
+  //- to read pll_status.mt_stat.vcxo_offset has to be used.
+  this->requested_ep_.mtvcxoffs = t;
+}
+
+// ============================================================================
+// BPMConfig::get_tune_offset
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_tune_offset (void) const
+{
+  return this->actual_ep_.pll_status.mt_stat.vcxo_offset;
+}
+
+// ============================================================================
+// BPMConfig::set_external_trigger_delay
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_external_trigger_delay (int t)
+{
+  this->requested_ep_.trig_delay = t;
+}
+
+// ============================================================================
+// BPMConfig::get_external_trigger_delay
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_external_trigger_delay (void) const
+{
+  return this->actual_ep_.trig_delay;
+}
+
+// ============================================================================
+// BPMConfig::set_pm_offset
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_pm_offset (int t)
+{
+  this->requested_ep_.PMoffset = t;
+}
+
+// ============================================================================
+// BPMConfig::get_pm_offset
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_pm_offset (void) const
+{
+  return this->actual_ep_.PMoffset;
+}
+
+// ============================================================================
+// BPMConfig::libera_model
+// ============================================================================
+INLINE_IMPL unsigned short BPMConfig::libera_model () const
+{
+  return LIBERA_IS_BRILLIANCE(this->actual_ep_.feature.itech) ? 1 : 0;
+}
+
+// ============================================================================
+// BPMConfig::has_maf_support
+// ============================================================================
+INLINE_IMPL bool BPMConfig::has_maf_support () const
+{
+  return LIBERA_IS_MAF(this->actual_ep_.feature.itech);
+}
+  
+// ============================================================================
+// BPMConfig::set_maf_length
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_maf_length (int ml)
+{
+  if (ml < kMIN_MAF_LENGTH || ml> kMAX_MAF_LENGTH)
+    Tango::Except::throw_exception(_CPTC("INVALID_PARAMETER"), 
+                                   _CPTC("MAF delay must be in [1, 129]"), 
+                                   _CPTC("Libera::set_maf_length"));
+                                   
+  this->requested_ep_.ddc_maflength = ml;
+}
+
+// ============================================================================
+// BPMConfig::get_maf_length
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_maf_length (void) const
+{
+  return this->actual_ep_.ddc_maflength; 
+}
+
+// ============================================================================
+// BPMConfig::set_maf_delay
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_maf_delay (int md)
+{
+  if (md < kMIN_MAF_DELAY || md > kMAX_MAF_DELAY)
+    Tango::Except::throw_exception(_CPTC("INVALID_PARAMETER"), 
+                                   _CPTC("MAF delay must be in [0, 128]"), 
+                                   _CPTC("Libera::set_maf_delay"));
+                                   
+  this->requested_ep_.ddc_mafdelay = md; 
+}
+
+// ============================================================================
+// BPMConfig::get_maf_delay
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_maf_delay (void) const
+{
+  return this->actual_ep_.ddc_mafdelay;
+}
+
+// ============================================================================
+// BPMConfig::set_institute
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_institute (int i)
+{
+  this->institute_ = i;
+}
+
+// ============================================================================
+// BPMConfig::get_institute
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_institute (void) const
+{
+  return this->institute_;
+}
+
+// ============================================================================
+// BPMConfig::set_pos_algorithm
+// ============================================================================
+INLINE_IMPL void BPMConfig::set_pos_algorithm (int a)
+{
+  this->pos_algorithm_ = a;
+}
+
+// ============================================================================
+// BPMConfig::get_pos_algorithm
+// ============================================================================
+INLINE_IMPL int BPMConfig::get_pos_algorithm (void) const
+{
+  return this->pos_algorithm_;
+}
+
+} //- namespace bpm
diff --git a/src/BPMData.cpp b/src/BPMData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16ca74b8b727a8634e62c68b3f311d2ce913613a
--- /dev/null
+++ b/src/BPMData.cpp
@@ -0,0 +1,667 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#include "BPMData.h"
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# include "ArmOptimization.h"
+#endif
+
+#if !defined (__INLINE_IMPL__)
+# include "BPMData.i"
+#endif // __INLINE_IMPL___
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# define kINV_NM_TO_MICRON_POW2   1000000ULL
+#else
+# define kMM_TO_MICRON        1.e3
+# define kMM_TO_MICRON_POW2   1.e6
+#endif
+
+namespace bpm
+{
+
+// ============================================================================
+// optional data flags
+// ============================================================================
+bool DDData::m_optional_data_enabled = false;
+bool SAData::m_optional_data_enabled = false;
+bool ADCData::m_optional_data_enabled = false;
+bool SAHistory::m_optional_data_enabled = false;
+
+// ============================================================================
+// DDData::DDData
+// ============================================================================
+DDData::DDData (void)
+  : SharedObject (),
+    x_ (0), 
+    z_ (0),
+    q_ (0),
+    sum_ (0), 
+    va_ (0), 
+    vb_ (0), 
+    vc_ (0), 
+    vd_ (0),
+    sin_va_ (0),
+    cos_va_ (0),
+    sin_vb_ (0),
+    cos_vb_ (0),
+    sin_vc_ (0),
+    cos_vc_ (0),
+    sin_vd_ (0),
+    cos_vd_ (0)
+{
+  //- noop
+}
+
+// ============================================================================
+// DDData::allocate
+// ============================================================================
+void DDData::allocate (size_t num_samples, bool init_to_nan) 
+  throw (Tango::DevFailed)
+{
+  try
+  {
+    this->x_.depth(num_samples);
+    if (init_to_nan) this->x_.fill(_NAN_);
+    
+    this->z_.depth(num_samples);
+    if (init_to_nan) this->z_.fill(_NAN_);
+    
+    this->q_.depth(num_samples);
+    if (init_to_nan) this->q_.fill(_NAN_);
+    
+    this->sum_.depth(num_samples);
+    if (init_to_nan) this->sum_.fill(_NAN_);
+    
+    this->va_.depth(num_samples);
+    if (init_to_nan) this->va_.fill(_NAN_);
+    
+    this->vb_.depth(num_samples);
+    if (init_to_nan) this->vb_.fill(_NAN_);
+    
+    this->vc_.depth(num_samples);
+    if (init_to_nan) this->vc_.fill(_NAN_);
+    
+    this->vd_.depth(num_samples);
+    if (init_to_nan) this->vd_.fill(_NAN_);
+
+    if (DDData::m_optional_data_enabled)
+    {
+      this->sin_va_.depth(num_samples);
+      if (init_to_nan) this->sin_va_.fill(_NAN_);
+      this->cos_va_.depth(num_samples);
+      if (init_to_nan) this->cos_va_.fill(_NAN_);
+
+      this->sin_vb_.depth(num_samples);
+      if (init_to_nan) this->sin_vb_.fill(_NAN_);
+      this->cos_vb_.depth(num_samples);
+      if (init_to_nan) this->cos_vb_.fill(_NAN_);
+
+      this->sin_vc_.depth(num_samples);
+      if (init_to_nan) this->sin_vc_.fill(_NAN_);
+      this->cos_vc_.depth(num_samples);
+      if (init_to_nan) this->cos_vc_.fill(_NAN_);
+
+      this->sin_vd_.depth(num_samples);
+      if (init_to_nan) this->sin_vd_.fill(_NAN_);
+      this->cos_vd_.depth(num_samples);
+      if (init_to_nan) this->cos_vd_.fill(_NAN_);
+    }
+  }
+  catch (const std::bad_alloc &)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"), 
+                                    _CPTC ("memory allocation failed"), 
+                                    _CPTC ("DDData::allocate"));
+  }
+  catch (const Tango::DevFailed& df)
+  {
+    Tango::Except::re_throw_exception (const_cast<Tango::DevFailed&>(df),
+                                       _CPTC ("OUT_OF_MEMORY"), 
+                                       _CPTC ("memory allocation failed"), 
+                                       _CPTC ("DDData::allocate"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception (_CPTC ("UNKNOWN_ERROR"), 
+                                    _CPTC ("unknown exception caught"), 
+                                    _CPTC ("DDData::allocate"));
+  }
+}
+
+// ============================================================================
+// DDData::DDData
+// ============================================================================
+DDData::~DDData (void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// DDData::operator=
+// ============================================================================
+DDData & DDData::operator= (const DDData& src)
+{
+  if (this == &src)
+    return *this;
+    
+  if (this->current_buffers_depth() != src.current_buffers_depth())
+    this->allocate(src.current_buffers_depth(), false);
+
+  this->x_ = src.x_;
+  this->z_ = src.z_;
+  this->q_ = src.q_;
+  
+  this->sum_ = src.sum_;
+  
+  this->va_ = src.va_;
+  this->vb_ = src.vb_;
+  this->vc_ = src.vc_;
+  this->vd_ = src.vd_;
+    
+  if (DDData::m_optional_data_enabled)
+  {
+    this->sin_va_ = src.sin_va_;
+    this->cos_va_ = src.cos_va_;
+    
+    this->sin_vb_ = src.sin_vb_;
+    this->cos_vb_ = src.cos_vb_;
+    
+    this->sin_vc_ = src.sin_vc_;
+    this->cos_vc_ = src.cos_vc_;
+    
+    this->sin_vd_ = src.sin_vd_;
+    this->cos_vd_ = src.cos_vd_;
+  }
+
+  return *this;
+}
+
+// ============================================================================
+// SAData::SAData
+// ============================================================================
+SAData::SAData ()
+  : SharedObject (), 
+    x_ (0), 
+    z_ (0),
+    q_ (0),
+    sum_ (0), 
+    va_ (0), 
+    vb_ (0), 
+    vc_ (0), 
+    vd_ (0), 
+    cx_ (0), 
+    cz_ (0)
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  , int_va_ (0),
+    int_vb_ (0),
+    int_vc_ (0),
+    int_vd_ (0),
+    int_sum_(0) 
+#endif
+{
+  ::memset(this->user_data_, 0, sizeof(UserData));
+}
+
+// ============================================================================
+// SAData::SAData
+// ============================================================================
+SAData::SAData (const CSPI_SA_ATOM & _saa)
+  : SharedObject (), 
+    x_ (_saa.X), 
+    z_ (_saa.Y),
+    q_ (_saa.Q),
+    sum_ (_saa.Sum),
+    va_ (_saa.Va), 
+    vb_ (_saa.Vb), 
+    vc_ (_saa.Vc), 
+    vd_ (_saa.Vd), 
+    cx_ (_saa.Cx), 
+    cz_ (_saa.Cy)
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  , int_va_ (_saa.Va),
+    int_vb_ (_saa.Vb),
+    int_vc_ (_saa.Vc),
+    int_vd_ (_saa.Vd),
+    int_sum_ (_saa.Sum)
+#endif
+{  
+	for (size_t i = 0, j = 0; i < 6; i++)
+	{
+		this->user_data_[j++] = 
+			static_cast<short>(_saa.reserved[i] & 0x0000FFFF);
+		
+		this->user_data_[j++] = 
+			static_cast<short>((_saa.reserved[i] & 0xFFFF0000) / 0x10000);
+	}
+}
+
+
+// ============================================================================
+// SAData::~SAData
+// ============================================================================
+SAData::~SAData (void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// SAHistory::SAHistory
+// ============================================================================
+SAHistory::SAHistory (void) 
+  : frozen_ (false),
+    x_mean_ (_NAN_),
+    z_mean_ (_NAN_),
+    x_rms_ (_NAN_),
+    z_rms_ (_NAN_),
+    x_peak_ (_NAN_),
+    z_peak_ (_NAN_),
+    s_mean_ (_NAN_),
+    actual_num_samples_(0)
+{
+  //- noop
+}
+
+// ============================================================================
+// SAHistory::SAHistory
+// ============================================================================
+SAHistory::SAHistory (size_t _depth) 
+  : frozen_ (false),
+    x_mean_ (_NAN_),
+    z_mean_ (_NAN_),
+    x_rms_ (_NAN_),
+    z_rms_ (_NAN_),
+    x_peak_ (_NAN_),
+    z_peak_ (_NAN_),
+    s_mean_ (_NAN_),
+    actual_num_samples_(0)
+{
+  this->depth (_depth);
+}
+
+// ============================================================================
+// SAHistory::~SAHistory
+// ============================================================================
+SAHistory::~SAHistory (void)
+{
+  //- noop dtor 
+}
+
+// ============================================================================
+// SAHistory::depth
+// ============================================================================
+void SAHistory::depth (size_t _depth) 
+  throw (Tango::DevFailed)
+{
+  bpm::MutexLock guard(this->lock_);
+  
+  if (this->frozen_)
+    this->unfreeze_i();
+   
+  this->x_.depth (_depth);
+  this->x_.fill (_NAN_);
+  this->x_rms_ = _NAN_;
+  this->x_mean_ = _NAN_;
+  this->x_peak_ = _NAN_;
+
+  this->z_.depth (_depth);
+  this->z_.fill (_NAN_); 
+  this->z_rms_ = _NAN_;
+  this->z_mean_ = _NAN_;
+  this->z_peak_ = _NAN_;
+
+  if (SAHistory::m_optional_data_enabled)
+  {
+    this->s_.depth (_depth);
+    this->s_.fill (_NAN_);
+    this->s_mean_ = _NAN_;
+  }
+  
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_x_.depth (_depth);
+  this->int_z_.depth (_depth);
+  if (SAHistory::m_optional_data_enabled)
+    this->int_s_.depth (_depth);
+#endif
+
+  this->actual_num_samples_ = 0;
+}
+
+// ============================================================================
+// SAHistory::compute_statistics
+// ============================================================================
+void SAHistory::compute_statistics (size_t _n)
+{  
+  bpm::MutexLock guard(this->lock_);
+
+  if (! this->actual_num_samples_)
+    return;
+  
+// bpm::Timer t;
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+  //- optimized alofo for the ARM platform
+  //-----------------------------------------------------------
+  i64 x_sum  = 0;
+  i64 z_sum  = 0;
+  i64 s_sum  = 0;
+  u64 xx_sum = 0;
+  u64 zz_sum = 0;
+
+  const SAData::I32Buffer & x_data = this->int_x_.data();
+  i32 x_lo_peak = x_data[0];
+  i32 x_hi_peak = x_data[0];
+  
+  const SAData::I32Buffer & z_data = this->int_z_.data();
+  i32 z_lo_peak = z_data[0];
+  i32 z_hi_peak = z_data[0];
+
+  //- get an iterator on the last <max_i> samples in the history
+  I32HistoryIterator x_it = this->int_x_.past_iterator(_n);
+  I32HistoryIterator z_it = this->int_z_.past_iterator(_n);
+  I32HistoryIterator s_it = this->int_s_.past_iterator(SAHistory::m_optional_data_enabled ? _n : 0);
+  
+  size_t sample_counter = 0;
+
+  //- x and z have same depth, so checking x.end_of_past() is enough  
+  //- to control the number of iterations in the while loop 
+  while (! x_it.end_of_past())
+  {
+    i32 xd = *x_it;
+    i32 zd = *z_it;
+    
+    if (x_lo_peak > xd)
+      x_lo_peak = xd;
+    else if (xd > x_hi_peak)
+      x_hi_peak = xd;
+ 
+    x_sum += xd;
+    xx_sum += (i64)xd * xd;
+    
+    if (z_lo_peak > zd)
+      z_lo_peak = zd;
+    else if (zd > z_hi_peak)
+      z_hi_peak = zd;
+      
+    z_sum += zd;
+    zz_sum += (i64)zd * zd;
+    
+    x_it++;
+    z_it++;
+    
+    if (SAHistory::m_optional_data_enabled)
+    {
+      s_sum += *s_it; 
+      s_it++;
+    }
+
+    ++sample_counter;
+  }
+
+  if (sample_counter)
+  {
+    i32 x_mean = x_sum / (i64)sample_counter;
+    NM_TO_MM(x_mean, &this->x_mean_);
+
+    i32 z_mean = z_sum / (i64)sample_counter;
+    NM_TO_MM(z_mean, &this->z_mean_);
+
+    if (SAHistory::m_optional_data_enabled)
+    {
+      i32 s_mean = s_sum / (i64)sample_counter;
+      NM_TO_MM(s_mean, &this->s_mean_); 
+    }
+
+    //TODO: THIS IS PARTIAL OPTIMIZATION - TO BE IMPROVED IN A NEAR FUTURE
+    //---------------------------------------------------------------------
+    i64 x_rms_pow2 = (xx_sum - ((i64)x_mean * x_mean)) / (((i64)sample_counter - 1) * kINV_NM_TO_MICRON_POW2);
+    i64 z_rms_pow2 = (zz_sum - ((i64)z_mean * z_mean)) / (((i64)sample_counter - 1) * kINV_NM_TO_MICRON_POW2);
+
+    this->x_rms_ = static_cast<bpm::FPDataType>(::sqrt((double)x_rms_pow2));
+    this->z_rms_ = static_cast<bpm::FPDataType>(::sqrt((double)z_rms_pow2));
+  }
+  else
+  {
+    this->x_mean_ = 0; 
+    this->z_mean_ = 0; 
+    this->s_mean_ = 0; 
+    this->x_rms_  = 0;  
+    this->z_rms_  = 0; 
+  }
+  
+  NM_TO_UM(x_hi_peak - x_lo_peak, &this->x_peak_);
+  NM_TO_UM(z_hi_peak - z_lo_peak, &this->z_peak_); 
+
+  //- std::cout << "SAHistory::compute_statistics::optimized::x_mean: " << this->x_mean_ << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::z_mean: " << this->z_mean_ << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::s_mean: " << this->s_mean_ << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::x_peak: " << this->x_peak_ << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::z_peak: " << this->z_peak_ << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::x_rms : " << this->x_rms_  << std::endl;
+  //- std::cout << "SAHistory::compute_statistics::optimized::z_rms : " << this->z_rms_  << std::endl;
+  
+#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm
+  //-----------------------------------------------------------
+  bpm::FPDataType x_sum  = 0.;
+  bpm::FPDataType z_sum  = 0.;
+  bpm::FPDataType s_sum  = 0.;
+  bpm::FPDataType xx_sum = 0.;
+  bpm::FPDataType zz_sum = 0.;
+  
+  const SAData::Buffer & x_data = this->x_.data();
+  bpm::FPDataType x_lo_peak = x_data[0]; 
+  bpm::FPDataType x_hi_peak = x_data[0];
+  
+  const SAData::Buffer & z_data = this->z_.data();
+  bpm::FPDataType z_lo_peak = z_data[0];
+  bpm::FPDataType z_hi_peak = z_data[0];
+  
+  //- get an iterator on the last <max_i> samples in the history
+  HistoryIterator x_it = this->x_iterator(_n);
+  HistoryIterator z_it = this->z_iterator(_n);
+  HistoryIterator s_it = this->sum_iterator(SAHistory::m_optional_data_enabled ? _n : 0);
+  
+  size_t sample_counter = 0;
+
+  //- x and z have same depth, so checking x.end_of_past() is enough  
+  //- to control the number of iterations in the while loop...
+  while (! x_it.end_of_past())
+  {
+    bpm::FPDataType xd = *x_it;
+    bpm::FPDataType zd = *z_it;
+    
+    if (x_lo_peak > xd)
+      x_lo_peak = xd;
+    else if (xd > x_hi_peak)
+      x_hi_peak = xd;
+ 
+    x_sum += xd;
+    xx_sum += xd * xd;
+    
+    if (z_lo_peak > zd)
+      z_lo_peak = zd;
+    else if (zd > z_hi_peak)
+      z_hi_peak = zd; 
+      
+    z_sum += zd;
+    zz_sum += zd * zd;
+    
+    x_it++;
+    z_it++; 
+    
+    if (SAHistory::m_optional_data_enabled)
+    {
+      s_sum += *s_it; 
+      s_it++;
+    }
+    
+    ++sample_counter;
+  }
+ 
+  if (sample_counter)
+  {
+    this->x_mean_ = x_sum / sample_counter; 
+
+    this->z_mean_ = z_sum / sample_counter; 
+
+    this->s_mean_ = SAHistory::m_optional_data_enabled
+                  ? s_sum / sample_counter
+                  : 0;
+    
+    this->x_rms_ = 
+    ::sqrt(kMM_TO_MICRON_POW2 
+         * (1. / (static_cast<bpm::FPDataType>(sample_counter) - 1.))  
+         * (xx_sum - (this->x_mean_ * this->x_mean_)));  
+     
+    this->z_rms_ = 
+    ::sqrt(kMM_TO_MICRON_POW2 
+         * (1. / (static_cast<bpm::FPDataType>(sample_counter) - 1.)) 
+         * (zz_sum - (this->z_mean_ * this->z_mean_)));
+  }
+  else
+  {
+    this->x_mean_ = 0; 
+    this->z_mean_ = 0; 
+    this->s_mean_ = 0; 
+    this->x_rms_  = 0;  
+    this->z_rms_  = 0; 
+  }
+  
+  this->x_peak_ = kMM_TO_MICRON * (x_hi_peak - x_lo_peak);
+  this->z_peak_ = kMM_TO_MICRON * (z_hi_peak - z_lo_peak); 
+  
+/*
+  std::cout << "SAHistory::compute_statistics::---std---::x_mean: " << this->x_mean_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::z_mean: " << this->z_mean_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::s_mean: " << this->s_mean_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::x_peak: " << this->x_peak_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::z_peak: " << this->z_peak_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::x_rms : " << this->x_rms_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::z_rms : " << this->z_rms_ << std::endl;
+  std::cout << "SAHistory::compute_statistics::---std---::smpls : " << sample_counter << std::endl;
+*/
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_ 
+
+//  std::cout << "BPM::SAHistory::compute_statistics::took " 
+//            << t.elapsed_msec()
+//            << " msecs" 
+//            << std::endl;
+}
+
+// ============================================================================
+// ADData::ADCData
+// ============================================================================
+ADCData::ADCData (void)
+  : SharedObject (),
+    a_ (0), 
+    b_ (0),
+    c_ (0),
+    d_ (0)
+{
+  //- noop
+}
+
+// ============================================================================
+// ADCData::allocate
+// ============================================================================
+void ADCData::allocate (size_t num_samples, bool init_to_zero) 
+  throw (Tango::DevFailed)
+{
+  try
+  {
+    this->a_.depth(num_samples);
+    if (init_to_zero) this->a_.fill(0);
+    
+    this->b_.depth(num_samples);
+    if (init_to_zero) this->b_.fill(0);
+    
+    this->c_.depth(num_samples);
+    if (init_to_zero) this->c_.fill(0);
+    
+    this->d_.depth(num_samples);
+    if (init_to_zero) this->d_.fill(0);
+  }
+  catch (const std::bad_alloc &)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"), 
+                                    _CPTC ("memory allocation failed"), 
+                                    _CPTC ("ADCData::allocate"));
+  }
+  catch (const Tango::DevFailed& df)
+  {
+    Tango::Except::re_throw_exception (const_cast<Tango::DevFailed&>(df),
+                                       _CPTC ("OUT_OF_MEMORY"), 
+                                       _CPTC ("memory allocation failed"), 
+                                       _CPTC ("ADCData::allocate"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception (_CPTC ("UNKNOWN_ERROR"), 
+                                    _CPTC ("unknown exception caught"), 
+                                    _CPTC ("ADCData::allocate"));
+  }
+}
+
+// ============================================================================
+// ADCData::ADCData
+// ============================================================================
+ADCData::~ADCData (void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// DDData::operator=
+// ============================================================================
+ADCData & ADCData::operator= (const ADCData& src)
+{
+  if (this == &src)
+    return *this;
+    
+  if (this->current_buffers_depth() != src.current_buffers_depth())
+    this->allocate(src.current_buffers_depth(), false);
+
+  this->a_ = src.a_;
+  this->b_ = src.b_;
+  this->c_ = src.c_;
+  this->d_ = src.d_;
+  
+  ::memcpy(&(this->timestamp_), &(src.timestamp_), sizeof(timespec));
+  
+  return *this;
+}
+} //- namespace bpm
diff --git a/src/BPMData.h b/src/BPMData.h
new file mode 100644
index 0000000000000000000000000000000000000000..59cf816938c32191ac9a137541739d0609d25632
--- /dev/null
+++ b/src/BPMData.h
@@ -0,0 +1,560 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_DATA_H_
+#define _BPM_DATA_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/SharedObject.h"
+#include "BPMBuffer.h"
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# include "ArmOptimization.h"
+#endif
+
+#define kNUM_USER_DATA 12
+
+namespace bpm
+{
+// ============================================================================
+//! DDRawData
+// ============================================================================
+typedef bpm::Buffer<CSPI_DD_RAWATOM> DDRawBuffer;
+typedef bpm::Buffer<CSPI_ADC_ATOM> ADCRawBuffer;
+
+// ============================================================================
+//! DDData abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class DDData : private bpm::SharedObject
+{
+  friend class BPM;
+  friend class DataProcessing;
+
+public:
+
+  typedef bpm::Buffer<bpm::FPDataType> Buffer;
+  
+  /**
+   * Ctor
+   */
+  DDData ();
+  
+  /**
+   * Duplicate (shallow copy) this shared object 
+   */
+  DDData * duplicate (void);
+
+  /**
+   * Release this shared object 
+   */
+  void release (void);
+
+  /**
+   * The data buffers accessors
+   */
+
+  //- mandatory data acessors (always available)
+  //----------------------------------------------------
+  const DDData::Buffer& x (void) const;
+  const DDData::Buffer& z (void) const;
+  const DDData::Buffer& q (void) const;
+  
+  const DDData::Buffer& va (void) const;
+  const DDData::Buffer& vb (void) const;
+  const DDData::Buffer& vc (void) const;
+  const DDData::Buffer& vd (void) const;
+  
+  const DDData::Buffer& sum (void) const;
+
+  //- optional data acessors (may be disabled)
+  //----------------------------------------------------
+  //- the following methods may throw an exception if
+  //- requested data is not available (feature disabled)
+  
+  const DDData::Buffer& sin_va (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& cos_va (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& sin_vb (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& cos_vb (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& sin_vc (void) const 
+      throw (Tango::DevFailed);
+        
+  const DDData::Buffer& cos_vc (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& sin_vd (void) const 
+      throw (Tango::DevFailed);
+      
+  const DDData::Buffer& cos_vd (void) const 
+      throw (Tango::DevFailed);
+  
+  /**
+   * The data timestamp
+   */
+  const struct timespec & timestamp (void) const;
+  
+  /**
+   * is optional data enabled?
+   */
+  inline static bool optional_data_enabled (void)
+  {
+    return DDData::m_optional_data_enabled;
+  }
+  
+private:
+
+  virtual ~DDData ();
+
+  DDData & operator= (const DDData &);
+
+  DDData (const DDData &);
+
+  void allocate (size_t num_samples, bool init_to_nan = false) 
+      throw (Tango::DevFailed);
+
+  void actual_num_samples (size_t num_samples);
+
+  size_t current_buffers_depth () const;
+
+  //- common data
+  //-----------------------
+  DDData::Buffer x_;
+  DDData::Buffer z_;
+  DDData::Buffer q_;
+  DDData::Buffer sum_;
+  DDData::Buffer va_;
+  DDData::Buffer vb_;
+  DDData::Buffer vc_;
+  DDData::Buffer vd_;
+  
+  //- optional data
+  //-----------------------
+  DDData::Buffer sin_va_;
+  DDData::Buffer cos_va_;
+  DDData::Buffer sin_vb_;
+  DDData::Buffer cos_vb_;
+  DDData::Buffer sin_vc_;
+  DDData::Buffer cos_vc_;
+  DDData::Buffer sin_vd_;
+  DDData::Buffer cos_vd_;
+  
+  struct timespec timestamp_;
+
+  static bool m_optional_data_enabled;
+};
+
+// ============================================================================
+//! SAData abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class SAData : private bpm::SharedObject
+{
+  friend class BPM;
+  friend class DataProcessing;
+
+public:
+
+  typedef bpm::Buffer<bpm::FPDataType> Buffer;
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  typedef bpm::Buffer<i32> I32Buffer;
+  typedef bpm::Buffer<i64> I64Buffer;
+#endif
+
+  typedef short UserData[kNUM_USER_DATA];
+  
+  /**
+   * Ctor
+   */
+  SAData ();
+
+  /**
+   * Duplicate (shallow copy) this shared object 
+   */
+  SAData * duplicate (void);
+
+  /**
+   * Release this shared object 
+   */
+  void release (void);
+
+  /**
+   * The fp data accessors
+   */
+  const bpm::FPDataType& x (void) const;
+  const bpm::FPDataType& z (void) const;
+  const bpm::FPDataType& q (void) const;
+
+  const bpm::FPDataType& va (void) const;
+  const bpm::FPDataType& vb (void) const;
+  const bpm::FPDataType& vc (void) const;
+  const bpm::FPDataType& vd (void) const;
+
+  const bpm::FPDataType& sum (void) const;
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  /**
+   * The int data accessors
+   */
+  i32 int_x (void) const;
+  i32 int_z (void) const;
+  i32 int_sum (void) const;
+#endif
+
+	const long& cx (void) const;
+	const long& cz (void) const;
+
+	const UserData & user_data (void) const;
+  
+  /**
+   * The data timestamp
+   */
+  const struct timespec & timestamp (void) const;
+
+  /**
+   * is optional data enabled?
+   */
+  inline static bool optional_data_enabled (void)
+  {
+    return SAData::m_optional_data_enabled;
+  }
+  
+private:
+  SAData (const CSPI_SA_ATOM &);
+  SAData (const SAData &);
+  SAData & operator= (const SAData &);
+  SAData & operator= (const CSPI_SA_ATOM &);
+  
+  virtual ~SAData ();
+
+  bpm::FPDataType x_;
+  bpm::FPDataType z_;
+  bpm::FPDataType q_;
+
+  bpm::FPDataType sum_;
+
+  bpm::FPDataType va_;
+  bpm::FPDataType vb_;
+  bpm::FPDataType vc_;
+  bpm::FPDataType vd_;
+  
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  i32 int_va_;
+  i32 int_vb_;
+  i32 int_vc_;
+  i32 int_vd_;
+  i32 int_x_;
+  i32 int_z_;
+  i32 int_sum_;
+#endif
+
+  long cx_;
+  long cz_;
+
+	UserData user_data_;   
+
+  struct timespec timestamp_;
+
+  static bool m_optional_data_enabled;
+};
+
+// ============================================================================
+//! class: SAHistory
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class SAHistory
+{
+  friend class BPM;
+  
+public:
+  //- define what is a circular buffer of SA data (fp)
+  typedef CircularBuffer<bpm::FPDataType> SACircularBuffer;
+  
+  //- define what is an history iterator
+  typedef SACircularBuffer::PastIterator HistoryIterator;
+  
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  //- define what is a circular buffer of SA data (for i32) 
+  typedef CircularBuffer<i32> SAI32CircularBuffer; 
+
+  //- define what is an history iterator (for i32)
+  typedef SAI32CircularBuffer::PastIterator I32HistoryIterator;
+#endif
+
+  /**
+   * Freeze history
+   */ 
+  void freeze (void); 
+  
+  /**
+   * Unfreeze history
+   */ 
+  void unfreeze (void);
+
+  /**
+   * Reset history content
+   */
+  void reset ();
+  
+  /**
+   * The X data buffer accessor
+   */
+  const SAData::Buffer & x (void)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Iterate on the last n history points 
+   */
+  inline HistoryIterator x_iterator (size_t n) const
+  {
+    return x_.past_iterator(n);
+  }  
+
+  /**
+   * The Z data buffer accessor
+   */
+  const SAData::Buffer & z (void)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Iterate on the last n history points 
+   */
+  inline HistoryIterator z_iterator (size_t n) const
+  {
+    return z_.past_iterator(n);
+  }
+
+  /**
+   * The sum ordered data buffer accessor (optional data)
+   */
+  const SAData::Buffer & sum (void)
+    throw (Tango::DevFailed);
+    
+  /**
+   * Iterate on the last n history points  (optional data)
+   */
+  inline HistoryIterator sum_iterator (size_t n) const
+    throw (Tango::DevFailed)
+  {
+    return s_.past_iterator(n);
+  }
+  
+  /**
+   * X and Z Mean Pos. values
+   */
+  const bpm::FPDataType& x_mean (void) const;
+  const bpm::FPDataType& z_mean (void) const;
+  
+  /**
+   * X and Z RMS Pos. values
+   */
+  const bpm::FPDataType& x_rms (void) const;
+  const bpm::FPDataType& z_rms (void) const;
+
+  /**
+   * X and Z Peak Pos. values
+   */
+  const bpm::FPDataType& x_peak (void) const;
+  const bpm::FPDataType& z_peak (void) const;
+
+  /**
+   *  Mean Sum (optional data)
+   */
+  const bpm::FPDataType& sum_mean (void) const
+    throw (Tango::DevFailed);
+  
+  /**
+   * computes X and Z pos statistics from last <n> samples in history
+   */
+  void compute_statistics (size_t n);
+
+  /**
+   * returns the actual number of samples currently stored in the Buffer
+   */
+  size_t actual_num_samples (void) const;
+
+  /**
+   * are optional data enabled?
+   */
+  inline static bool optional_data_enabled (void)
+  {
+    return SAHistory::m_optional_data_enabled;
+  }
+  
+private:
+  SAHistory (void);
+  SAHistory (size_t depth);
+
+  virtual ~SAHistory (void);
+  
+  void depth (size_t depth) 
+    throw (Tango::DevFailed);
+    
+  void push (const SAData & sa) 
+    throw (Tango::DevFailed);
+  
+  void unfreeze_i (void); 
+
+  //- mandatory data
+  SACircularBuffer x_;
+  SACircularBuffer z_;
+  //- optional sum history
+  SACircularBuffer s_;
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  //- mandatory data
+  SAI32CircularBuffer int_x_;
+  SAI32CircularBuffer int_z_;
+  //- optional sum history
+  SAI32CircularBuffer int_s_;
+#endif
+ 
+  bpm::Mutex lock_;
+  
+  bool frozen_;
+
+  bpm::FPDataType x_mean_;
+  bpm::FPDataType z_mean_;  
+  bpm::FPDataType x_rms_;
+  bpm::FPDataType z_rms_;
+  bpm::FPDataType x_peak_;
+  bpm::FPDataType z_peak_;
+  bpm::FPDataType s_mean_;
+  
+  size_t actual_num_samples_;
+  
+  //- Undefined methods and ops
+  SAHistory & operator= (const SAHistory &);
+  SAHistory (const SAHistory &);
+
+  static bool m_optional_data_enabled;
+};
+
+// ============================================================================
+//! ADCData abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class ADCData : private bpm::SharedObject
+{
+  friend class BPM;
+
+public:
+
+  typedef bpm::Buffer<short> Buffer;
+  
+  /**
+   * Ctor
+   */
+  ADCData ();
+  
+  /**
+   * Duplicate (shallow copy) this shared object 
+   */
+  ADCData * duplicate (void);
+
+  /**
+   * Release this shared object 
+   */
+  void release (void);
+
+  /**
+   * The data buffers accessors
+   */
+  const ADCData::Buffer& a (void) const;
+  const ADCData::Buffer& b (void) const;
+  const ADCData::Buffer& c (void) const;
+  const ADCData::Buffer& d (void) const;
+
+  /**
+   * The data timestamp
+   */
+  const struct timespec & timestamp (void) const;
+  
+  /**
+   * is optional data enabled?
+   */
+  inline static bool optional_data_enabled (void)
+  {
+    return ADCData::m_optional_data_enabled;
+  }
+  
+private:
+
+  virtual ~ADCData ();
+
+  ADCData & operator= (const ADCData &);
+
+  ADCData (const ADCData &);
+
+  void allocate (size_t num_samples, bool init_to_zero = false) 
+      throw (Tango::DevFailed);
+
+  void actual_num_samples (size_t num_samples);
+  
+  size_t current_buffers_depth () const;
+      
+  ADCData::Buffer a_;
+  ADCData::Buffer b_;
+  ADCData::Buffer c_;
+  ADCData::Buffer d_;
+  
+  struct timespec timestamp_;
+
+  static bool m_optional_data_enabled;
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "BPMData.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_DATA_H_
diff --git a/src/BPMData.i b/src/BPMData.i
new file mode 100644
index 0000000000000000000000000000000000000000..c190dc6ea65a8e78c3d011d21d48cf545a33fb11
--- /dev/null
+++ b/src/BPMData.i
@@ -0,0 +1,748 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// DDData::duplicate
+// ============================================================================
+INLINE_IMPL DDData *DDData::duplicate (void)
+{
+  return reinterpret_cast < DDData * >(SharedObject::duplicate ());
+}
+
+// ============================================================================
+// DDData::release
+// ============================================================================
+INLINE_IMPL void DDData::release (void)
+{
+  SharedObject::release ();
+}
+
+// ============================================================================
+// DDData::current_buffers_depth
+// ============================================================================
+INLINE_IMPL size_t DDData::current_buffers_depth (void) const
+{
+  return this->x_.depth();
+}
+
+// ============================================================================
+// DDData::x
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::x (void) const
+{
+  return this->x_;
+}
+
+// ============================================================================
+// DDData::z
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::z (void) const
+{
+  return this->z_;
+}
+
+// ============================================================================
+// DDData::q
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::q (void) const
+{
+  return this->q_;
+}
+
+// ============================================================================
+// DDData::sum
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::sum (void) const
+{
+  return this->sum_;
+}
+
+// ============================================================================
+// DDData::va
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::va (void) const
+{
+  return this->va_;
+}
+
+// ============================================================================
+// DDData::vb
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::vb (void) const
+{
+  return this->vb_;
+}
+
+// ============================================================================
+// DDData::vc
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::vc (void) const
+{
+  return this->vc_;
+}
+
+// ============================================================================
+// DDData::vd
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::vd (void) const
+{
+  return this->vd_;
+}
+
+// ============================================================================
+// DDData::cos_va
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::cos_va (void) const 
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::cos_va");
+  return this->cos_va_;
+}
+
+// ============================================================================
+// DDData::cos_vb
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::cos_vb (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::cos_vb");
+  return this->cos_vb_;
+}
+
+// ============================================================================
+// DDData::cos_vc
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::cos_vc (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::cos_vc");
+  return this->cos_vc_;
+}
+
+// ============================================================================
+// DDData::cos_vd
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::cos_vd (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::cos_vd");
+  return this->cos_vd_;
+}
+
+// ============================================================================
+// DDData::sin_va
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::sin_va (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::sin_va");
+  return this->sin_va_;
+}
+
+// ============================================================================
+// DDData::sin_vb
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::sin_vb (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::sin_vb");
+  return this->sin_vb_;
+}
+
+// ============================================================================
+// DDData::sin_vc
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::sin_vc (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::sin_vc");
+  return this->sin_vc_;
+}
+
+// ============================================================================
+// DDData::sin_vd
+// ============================================================================
+INLINE_IMPL const DDData::Buffer& DDData::sin_vd (void) const
+  throw (Tango::DevFailed)  
+{
+  if (! DDData::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "DDData::sin_vd");
+  return this->sin_vd_;
+}
+
+// ============================================================================
+// DDData::timestamp
+// ============================================================================
+INLINE_IMPL const struct timespec &DDData::timestamp (void) const
+{
+  return this->timestamp_;
+}
+
+// ============================================================================
+// DDData::actual_num_samples
+// ============================================================================
+INLINE_IMPL void DDData::actual_num_samples (size_t _num_samples)
+{
+  this->x_.force_length(_num_samples);
+  this->z_.force_length(_num_samples);
+  this->q_.force_length(_num_samples);
+
+  this->sum_.force_length(_num_samples);
+
+  this->va_.force_length(_num_samples);
+  this->vb_.force_length(_num_samples);
+  this->vc_.force_length(_num_samples);
+  this->vd_.force_length(_num_samples);
+
+  if (DDData::m_optional_data_enabled)
+  {
+    this->sin_va_.force_length(_num_samples);
+    this->cos_va_.force_length(_num_samples);
+    this->sin_vb_.force_length(_num_samples);
+    this->cos_vb_.force_length(_num_samples);
+    this->sin_vc_.force_length(_num_samples);
+    this->cos_vc_.force_length(_num_samples);
+    this->sin_vd_.force_length(_num_samples);
+    this->cos_vd_.force_length(_num_samples);
+  }
+}
+
+// ============================================================================
+// SAData::duplicate
+// ============================================================================
+INLINE_IMPL SAData *SAData::duplicate (void)
+{
+  return reinterpret_cast < SAData * >(SharedObject::duplicate ());
+}
+
+// ============================================================================
+// SAData::release
+// ============================================================================
+INLINE_IMPL void SAData::release (void)
+{
+  SharedObject::release ();
+}
+
+// ============================================================================
+// SAData::operator=
+// ============================================================================
+INLINE_IMPL SAData & SAData::operator= (const SAData & _sad)
+{
+  if (this == &_sad)
+    return *this;
+    
+  ::memcpy(this, &_sad, sizeof(SAData));
+  
+  return *this;
+}
+
+// ============================================================================
+// SAData::operator=
+// ============================================================================
+INLINE_IMPL SAData & SAData::operator= (const CSPI_SA_ATOM & _saa)
+{
+  this->x_ = _saa.X;
+  this->z_ = _saa.Y;
+  this->q_ = _saa.Q;
+  this->sum_ = _saa.Sum; 
+  
+  this->va_ = _saa.Va; 
+  this->vb_ = _saa.Vb; 
+  this->vc_ = _saa.Vc;
+  this->vd_ = _saa.Vd; 
+       
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_va_ = _saa.Va; 
+  this->int_vb_ = _saa.Vb; 
+  this->int_vc_ = _saa.Vc;
+  this->int_vd_ = _saa.Vd; 
+  this->int_sum_ = _saa.Sum; 
+#endif
+
+  this->cx_ = _saa.Cx;
+  this->cz_ = _saa.Cy; 
+  
+  for (size_t i = 0, j = 0; i < 6; i++)
+  {
+    this->user_data_[j++] = 
+      static_cast<short>(_saa.reserved[i] & 0x0000FFFF);
+    
+    this->user_data_[j++] = 
+      static_cast<short>((_saa.reserved[i] & 0xFFFF0000) / 0x10000);
+  }
+  
+  return *this;
+}
+
+// ============================================================================
+// SAData::x
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::x (void) const
+{
+  return this->x_;
+}
+
+// ============================================================================
+// SAData::z
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::z (void) const
+{
+  return this->z_;
+}
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+// ============================================================================
+// SAData::int_x
+// ============================================================================
+INLINE_IMPL i32 SAData::int_x (void) const
+{
+  return this->int_x_;
+}
+
+// ============================================================================
+// SAData::int_z
+// ============================================================================
+INLINE_IMPL i32 SAData::int_z (void) const
+{
+  return this->int_z_;
+}
+
+// ============================================================================
+// SAData::int_sum
+// ============================================================================
+INLINE_IMPL i32 SAData::int_sum (void) const
+{
+  return this->int_sum_;
+}
+#endif
+
+// ============================================================================
+// SAData::q
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::q (void) const
+{
+  return this->q_;
+}
+
+// ============================================================================
+// SAData::sum
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::sum (void) const
+{
+  return this->sum_;
+}
+
+// ============================================================================
+// SAData::va
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::va (void) const
+{
+  return this->va_;
+}
+
+// ============================================================================
+// SAData::vb
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::vb (void) const
+{
+  return this->vb_;
+}
+
+// ============================================================================
+// SAData::vc
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::vc (void) const
+{
+  return this->vc_;
+}
+
+// ============================================================================
+// SAData::vd
+// ============================================================================
+INLINE_IMPL const FPDataType & SAData::vd (void) const
+{
+  return this->vd_;
+}
+
+// ============================================================================
+// SAData::cx
+// ============================================================================
+INLINE_IMPL const long & SAData::cx (void) const
+{
+  return this->cx_;
+}
+
+// ============================================================================
+// SAData::cz
+// ============================================================================
+INLINE_IMPL const long & SAData::cz (void) const
+{
+  return this->cz_;
+}
+
+// ============================================================================
+// SAData::user_data
+// ============================================================================
+INLINE_IMPL const SAData::UserData & SAData::user_data (void) const
+{
+  return this->user_data_;
+}
+
+// ============================================================================
+// SAData::timestamp
+// ============================================================================
+INLINE_IMPL const struct timespec &SAData::timestamp (void) const
+{
+  return this->timestamp_;
+}
+
+// ============================================================================
+// SAHistory::x
+// ============================================================================
+INLINE_IMPL const SAData::Buffer & SAHistory::x (void)
+  throw (Tango::DevFailed)
+{
+  bpm::MutexLock guard(this->lock_);
+  return this->x_.ordered_data();
+}
+
+// ============================================================================
+// SAHistory::z
+// ============================================================================
+INLINE_IMPL const SAData::Buffer & SAHistory::z (void)
+  throw (Tango::DevFailed)
+{
+  bpm::MutexLock guard(this->lock_);
+  return this->z_.ordered_data();
+}
+
+// ============================================================================
+// SAHistory::sum
+// ============================================================================
+INLINE_IMPL const SAData::Buffer & SAHistory::sum (void)
+  throw (Tango::DevFailed)
+{
+  if (! SAHistory::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "SAHistory::sum");
+                      
+  bpm::MutexLock guard(this->lock_);
+  return this->s_.ordered_data();
+}
+
+// ============================================================================
+// SAHistory::push
+// ============================================================================
+INLINE_IMPL void SAHistory::push (const SAData & _sad) 
+  throw (Tango::DevFailed)
+{
+  bpm::MutexLock guard(this->lock_);
+  
+  this->x_.push(_sad.x());
+  this->z_.push(_sad.z());
+  
+  if (SAHistory::m_optional_data_enabled)
+    this->s_.push(_sad.sum());
+  
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_x_.push(_sad.int_x());
+  this->int_z_.push(_sad.int_z());
+
+  if (SAHistory::m_optional_data_enabled)
+    this->int_s_.push(_sad.int_sum());
+#endif
+
+  if (this->actual_num_samples_ < this->x_.data().depth())
+    this->actual_num_samples_++;
+}
+
+// ============================================================================
+// SAHistory::actual_num_samples
+// ============================================================================
+INLINE_IMPL size_t SAHistory::actual_num_samples (void) const
+{
+  return this->actual_num_samples_;
+}
+
+// ============================================================================
+// SAHistory::freeze
+// ============================================================================
+INLINE_IMPL void SAHistory::freeze (void) 
+{
+  bpm::MutexLock guard(this->lock_);
+
+  //- std::cout << "SAHistory::freeze <-" << std::endl;
+
+  this->x_.freeze();
+  this->z_.freeze();
+  this->s_.freeze();
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_x_.freeze();
+  this->int_z_.freeze();
+  this->int_s_.freeze();
+#endif
+
+  this->frozen_ = true;
+
+  //- std::cout << "SAHistory::freeze ->" << std::endl;
+}
+
+// ============================================================================
+// SAHistory::unfreeze
+// ============================================================================
+INLINE_IMPL void SAHistory::unfreeze (void) 
+{
+  bpm::MutexLock guard(this->lock_);
+
+  //- std::cout << "SAHistory::unfreeze <-" << std::endl;
+
+  this->unfreeze_i();
+
+  //- std::cout << "SAHistory::unfreeze ->" << std::endl;
+}
+
+// ============================================================================
+// SAHistory::unfreeze_i
+// ============================================================================
+INLINE_IMPL void SAHistory::unfreeze_i (void) 
+{
+  this->x_.unfreeze();
+  this->z_.unfreeze();
+  this->s_.unfreeze();
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_x_.unfreeze();
+  this->int_z_.unfreeze();
+  this->int_s_.unfreeze();
+#endif
+
+  this->frozen_ = false;
+}
+
+// ============================================================================
+// SAHistory::x_mean
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::x_mean (void) const
+{
+  return this->x_mean_;
+}
+
+// ============================================================================
+// SAHistory::z_mean
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::z_mean (void) const
+{
+  return this->z_mean_;
+}
+
+// ============================================================================
+// SAHistory::sum
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::sum_mean (void) const
+  throw (Tango::DevFailed)
+{
+  if (! SAHistory::m_optional_data_enabled)
+      THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+                      "no data available - feature disabled",
+                      "SAHistory::sum_mean");
+                      
+  return this->s_mean_;
+}
+
+// ============================================================================
+// SAHistory::x_rms
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::x_rms (void) const
+{
+  return this->x_rms_;
+}
+
+// ============================================================================
+// SAHistory::z_rms
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::z_rms (void) const
+{
+  return this->z_rms_;
+}
+
+// ===========================================================================
+// SAHistory::x_peak
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::x_peak (void) const
+{
+  return this->x_peak_;
+}
+
+// ============================================================================
+// SAHistory::z_peak
+// ============================================================================
+INLINE_IMPL const FPDataType & SAHistory::z_peak (void) const
+{
+  return this->z_peak_;
+}
+
+// ============================================================================
+// SAHistory::void
+// ============================================================================
+INLINE_IMPL void SAHistory::reset (void)
+{
+  bpm::MutexLock guard(this->lock_);
+  
+  this->actual_num_samples_ = 0;
+
+  this->frozen_ = 0;
+
+  this->x_mean_ = _NAN_;
+  this->z_mean_ = _NAN_;
+  this->x_rms_  = _NAN_;
+  this->z_rms_  = _NAN_;
+  this->x_peak_ = _NAN_;
+  this->z_peak_ = _NAN_;
+  this->s_mean_ = _NAN_;
+  
+  this->x_.clear();
+  this->x_.fill(_NAN_);
+  
+  this->z_.clear();
+  this->z_.fill(_NAN_);
+  
+  this->s_.clear();
+  this->s_.fill(_NAN_);
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+  this->int_x_.clear();
+  this->int_z_.clear();
+  this->int_s_.clear();
+#endif
+}
+
+// ============================================================================
+// ADCData::duplicate
+// ============================================================================
+INLINE_IMPL ADCData * ADCData::duplicate (void)
+{
+  return reinterpret_cast < ADCData * >(SharedObject::duplicate ());
+}
+
+// ============================================================================
+// ADCData::release
+// ============================================================================
+INLINE_IMPL void ADCData::release (void)
+{
+  SharedObject::release ();
+}
+
+// ============================================================================
+// ADCData::a
+// ============================================================================
+INLINE_IMPL const ADCData::Buffer& ADCData::a (void) const
+{
+  return this->a_;
+}
+
+// ============================================================================
+// ADCData::b
+// ============================================================================
+INLINE_IMPL const ADCData::Buffer& ADCData::b (void) const
+{
+  return this->b_;
+}
+
+// ============================================================================
+// ADCData::c
+// ============================================================================
+INLINE_IMPL const ADCData::Buffer& ADCData::c (void) const
+{
+  return this->c_;
+}
+
+// ============================================================================
+// ADCData::d
+// ============================================================================
+INLINE_IMPL const ADCData::Buffer& ADCData::d (void) const
+{
+  return this->d_;
+}
+
+// ============================================================================
+// ADCData::timestamp
+// ============================================================================
+INLINE_IMPL const struct timespec & ADCData::timestamp (void) const
+{
+  return this->timestamp_;
+}
+
+// ============================================================================
+// ADCData::current_buffers_depth
+// ============================================================================
+INLINE_IMPL size_t ADCData::current_buffers_depth (void) const
+{
+  return this->a_.depth();
+}
+
+// ============================================================================
+// ADCData::actual_num_samples
+// ============================================================================
+INLINE_IMPL void ADCData::actual_num_samples (size_t _num_samples)
+{
+  this->a_.force_length(_num_samples);
+  this->b_.force_length(_num_samples);
+  this->c_.force_length(_num_samples);
+  this->d_.force_length(_num_samples);
+}
+
+} // namespace bpm
diff --git a/src/BPMLocation.h b/src/BPMLocation.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a99172293f9e299a549756644a4b412479e4d7d
--- /dev/null
+++ b/src/BPMLocation.h
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_LOCATION_H_
+#define _BPM_LOCATION_H_
+
+// ============================================================================
+// LOCATION STRINGS
+// ============================================================================
+#define LOCATION_UNKNOWN          "UNKNOWN"
+#define LOCATION_TL1              "TL1"
+#define LOCATION_BOOSTER          "BOOSTER"
+#define LOCATION_TL2              "TL2"
+#define LOCATION_STORAGE_RING     "STORAGE_RING"
+
+namespace bpm
+{
+
+// ============================================================================
+//- BPMLocation
+// ============================================================================
+typedef enum _BPMLocation
+{
+  BPM_LOC_UNKNOWN,
+  BPM_LOC_TL1,
+  BPM_LOC_BOOSTER,
+  BPM_LOC_TL2,
+  BPM_LOC_STORAGE_RING
+}
+BPMLocation;
+
+}                               // namespace bpm
+
+#endif                          // _BPM_LOCATION_H_
diff --git a/src/BPMSensors.cpp b/src/BPMSensors.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..493d39d3db5b35a8a39ae09dbfa5d4cdcf0558a5
--- /dev/null
+++ b/src/BPMSensors.cpp
@@ -0,0 +1,233 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+// = INITIAL AUTHOR
+//    Dr. Michael Abbott - Diamond - EPICS driver 
+//
+// = ADAPTOR/THIEF/HACKER/
+//    Nicolas Leclercq - SOLEIL
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fts.h>
+#include <math.h>
+#include "CommonHeader.h"
+#include "BPMSensors.h"
+
+namespace bpm {
+
+// ============================================================================
+// BPMSensors::BPMSensors
+// ============================================================================
+BPMSensors::BPMSensors ()
+ : memory_free (0),
+   ram_fs_usage (0),
+   uptime (0),
+   cpu_usage (0)
+{
+
+}
+
+// ============================================================================
+// BPMSensors::~BPMSensors
+// ============================================================================
+BPMSensors::~BPMSensors ()
+{
+
+}
+
+// ============================================================================
+// parse_file
+// ============================================================================
+bool parse_file (const char * filename, int count, const char * fmt, ...)
+                 __attribute__((format(scanf, 3, 4)));
+                   
+bool parse_file (const char * filename, int count, const char * fmt, ...)
+{
+  bool ok = false;
+  FILE * input = fopen(filename, "r");
+  if (input != NULL)
+  {
+    va_list args;
+    va_start(args, fmt);
+    ok = vfscanf(input, fmt, args) == count;
+    fclose(input);
+  }
+  else
+  {
+    //- std::cout << "parse_file error: " << filename << std::endl;
+  }
+  return ok;
+}
+
+// ============================================================================
+// BPMSensors::update_uptime
+// ============================================================================
+// Total uptime and idle time can be read directly from /proc/uptime, and by
+// keeping track of the cumulative idle time we can report percentage CPU
+// usage over the scan period.
+// ============================================================================
+void BPMSensors::update_uptime ()
+{
+  double db_uptime;
+  if (parse_file("/proc/uptime", 1, "%lf", &db_uptime))
+  {
+    this->uptime = int(db_uptime);
+    
+    //- std::cout << "BPMSensors::update_uptime:up_time..." << db_uptime << std::endl;
+  }
+}
+
+// ============================================================================
+// BPMSensors::update_cpu_usage
+// ============================================================================
+void BPMSensors::update_cpu_usage ()
+{
+  static long last_user = 0;
+  static long last_nice = 0;
+  static long last_sys  = 0;
+  static long last_idle = 0;
+  
+  char ignored[16];
+  long user, nice, sys, idle;
+  if (parse_file("/proc/stat", 
+                  5, 
+                  "%s %ld %ld %ld %ld", 
+                  ignored, 
+                  &user, 
+                  &nice, 
+                  &sys, 
+                  &idle))
+  {
+    long d_user = user - last_user;
+    long d_nice = nice - last_nice; 
+    long d_idle = idle - last_idle;
+    long d_sys  = sys  - last_sys;
+    
+    double db_cpu_usage = 
+      100. * ( double(d_user + d_sys) / double(d_user + d_sys + d_nice + d_idle));
+    
+    this->cpu_usage = int(::nearbyint(db_cpu_usage));
+    
+    if (this->cpu_usage == 0)
+      ++this->cpu_usage;
+    
+    //- std::cout << "BPMSensors::update_cpu_usage:user........" << user << std::endl;
+    //- std::cout << "BPMSensors::update_cpu_usage:nice........" << nice << std::endl;
+    //- std::cout << "BPMSensors::update_cpu_usage:sys........." << sys << std::endl;
+    //- std::cout << "BPMSensors::update_cpu_usage:idle........" << idle << std::endl;
+    //- std::cout << "BPMSensors::update_cpu_usage:cpu_usage..." << db_cpu_usage << "%" << std::endl;
+    //- std::cout << "BPMSensors::update_cpu_usage:cpu_usage..." << this->cpu_usage << "%" << std::endl << std::endl;
+
+    last_user = user;
+    last_nice = nice;
+    last_sys  = sys;
+    last_idle = idle;
+  }
+}
+
+// ============================================================================
+// BPMSensors::update_ramfs_usage
+// ============================================================================
+// This discovers how many bytes of space are being consumed by the ramfs:
+// this needs to be subtracted from the "cached" space.
+// We do this by walking all of the file syss mounted as ramfs -- the
+// actual set of mount points is hard-wired here.
+// ===========================================================================
+void BPMSensors::update_ramfs_usage ()
+{
+  //- the following mount points all contain ram file sys
+  //- the (char* const) cast makes gcc-4.2 happy!
+  static char * const ram_fs[] =
+  {
+      (char* const)"/var/log",
+      (char* const)"/var/lock",
+      (char* const)"/var/run",
+      (char* const)"/tmp",
+      (char* const)NULL
+  };
+  
+  this->ram_fs_usage = 0;
+  
+  FTS * fts = fts_open(ram_fs, FTS_PHYSICAL | FTS_XDEV, NULL);
+  if (fts == NULL)
+  {
+    //- std::cout << "BPMSensors::update_ramfs_usage:fts_open error" << std::endl;
+    return;
+  }
+  
+  FTSENT *ftsent;
+  while (ftsent = fts_read(fts),  ftsent != NULL)
+      if (ftsent->fts_info != FTS_D)
+          this->ram_fs_usage += ftsent->fts_statp->st_size;
+
+  fts_close(fts);
+}
+
+// ============================================================================
+// BPMSensors::update_ramfs_usage
+// ============================================================================
+// Free memory processing is a little tricky.  By reading /proc/meminfo we can 
+// discover "free" and "cached" memory, but turning this into a true free memory 
+// number is more difficult.
+// In general, the cached memory is effectively free ... but unfortunately, 
+// files in the RAM file sys also appear as "cached" and are NOT free. Even 
+// more unfortunately, it appears to be particularly difficult to how much space
+// is used by the RAM file sys!
+// ============================================================================
+void BPMSensors::update_free_memory()
+{
+  int free, cached;
+  if (parse_file("/proc/meminfo", 2, "%*[^\n]\nMem: %*d %*d %d %*d %*d %d", &free, &cached))
+  {
+    this->update_ramfs_usage();
+    this->memory_free = free + cached - this->ram_fs_usage;
+  }
+}
+
+// ============================================================================
+// BPMSensors::update_all
+// ============================================================================
+void BPMSensors::update_all ()
+{
+  this->update_cpu_usage ();
+  this->update_uptime ();
+  //- this->update_free_memory ();
+}
+
+} //- namespace bpm
+
diff --git a/src/BPMSensors.h b/src/BPMSensors.h
new file mode 100644
index 0000000000000000000000000000000000000000..030dce2796defb6fadf928a295a4cccb6f20ba68
--- /dev/null
+++ b/src/BPMSensors.h
@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+// = INITIAL AUTHOR
+//    Dr. Michael Abbott - Diamond - EPICS driver 
+//
+// = ADAPTOR/THIEF/HACKER/
+//    Nicolas Leclercq - SOLEIL
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_SENSORS_H_
+#define _BPM_SENSORS_H_
+
+namespace bpm
+{
+
+// ============================================================================
+//! BPM sensors abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class BPMSensors  //-: public Tango::LogAdapter
+{
+  friend class BPM;
+
+private:
+  //- ctor
+  BPMSensors ();
+  
+  //-dtor
+  ~BPMSensors ();
+  
+  //- update all sensors values
+  void update_all ();
+  
+  //- update both uptime and idle
+  void update_uptime ();
+  
+  //- update ramfs usage
+  void update_ramfs_usage ();
+  
+  //- update memory usage 
+  void update_free_memory ();
+ 
+  //- update cpu usage 
+  void update_cpu_usage ();
+
+  //- nominal memory free (free + cached - ramfs)
+  int memory_free;  
+  
+  //- number of bytes allocated in ram filesystems
+  int ram_fs_usage;
+  
+  //- libera uptime in seconds
+  int uptime; 
+  
+  //- % CPU usage over the last sample interval
+  int cpu_usage;
+};
+
+} // namespace bpm
+
+#endif //- _BPM_SENSORS_H_
diff --git a/src/COPYING b/src/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..6e99dea31bc43157d6b13d0e964c295f6b8316bf
--- /dev/null
+++ b/src/COPYING
@@ -0,0 +1,709 @@
+------------------------------------------------------------------------------
+ Libera Tango Device
+------------------------------------------------------------------------------
+
+ Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+
+ Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+ Diamond Light Source Ltd. See ./ma/README for details. 
+
+ Contributors form the TANGO community:
+ Jens Meyer (ESRF), Francis Epaud (ERSF), Jairo Moldes (ALBA)
+ 
+ The Libera Tango Device 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.
+
+ The Libera Tango Device 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.
+
+ A copy of the GPL version 2 is available below. 
+
+ Contact:
+      Nicolas Leclercq
+      Synchrotron SOLEIL
+      libera-sofware<AT>esrf<DOT>fr
+------------------------------------------------------------------------------
+
+
+------------------------------------------------------------------------------
+  GNU GENERAL PUBLIC LICENSE - Version 2, June 1991
+------------------------------------------------------------------------------
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+
diff --git a/src/ClassFactory.cpp b/src/ClassFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..00dac720d3ef74b5f7ebd3f59c90690e763e5860
--- /dev/null
+++ b/src/ClassFactory.cpp
@@ -0,0 +1,52 @@
+//+=============================================================================
+//
+// file :        ClassFactory.cpp
+//
+// description : C++ source for the class_factory method of the DServer
+//               device class. This method is responsible to create
+//               all class singletin for a device server. It is called
+//               at device server startup
+//
+// project :     TANGO Device Server
+//
+// $Author: nleclercq $
+//
+// $Revision: 1.2.2.4 $
+//
+// $Log: ClassFactory.cpp,v $
+// Revision 1.2.2.4  2006/06/19 14:24:40  nleclercq
+// Sync with SOLEIL prod version
+//
+// Revision 1.3  2006/06/13 12:33:11  nleclercq
+// Added support for CSPI 1.03
+//
+// Revision 1.2.2.3  2006/03/20 15:01:47  nleclercq
+// Restored all src files
+//
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+#include <tango.h>
+#include <LiberaClass.h>
+
+/**
+ *	Create LiberaClass singleton and store it in DServer object.
+ */
+
+void Tango::DServer::class_factory()
+{
+
+	add_class(Libera_ns::LiberaClass::init("Libera"));
+
+}
diff --git a/src/CommonHeader.h b/src/CommonHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5443e4c8b25b646c343e78f6733f282ee074317
--- /dev/null
+++ b/src/CommonHeader.h
@@ -0,0 +1,128 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+//-----------------------------------------------------------------------------
+// ARM TARGET
+//-----------------------------------------------------------------------------
+#if defined(__arm__)
+# define _EMBEDDED_DEVICE_
+#else
+# undef _EMBEDDED_DEVICE_
+#endif
+
+//-----------------------------------------------------------------------------
+// DEPENDENCIES
+//-----------------------------------------------------------------------------
+#include <stdint.h>
+#include <tango.h>
+#if defined (_DEBUG)
+# include <debug.h>
+#endif
+#if ! defined(_EMBEDDED_DEVICE_)
+# include <error.h>
+# include <client-lib.h>
+#else
+# include <cspi.h>
+#endif
+#include "Inline.h"
+#include "TimeUtils.h"
+
+//-----------------------------------------------------------------------------
+// ASSERTION
+//-----------------------------------------------------------------------------
+#if defined (_DEBUG) || defined (DEBUG)
+# include <assert.h>
+# define DEBUG_ASSERT(BOOL_EXP) assert(BOOL_EXP)
+#else
+# define DEBUG_ASSERT(BOOL_EXP)
+#endif
+
+//-----------------------------------------------------------------------------
+// MISC MACROS
+//-----------------------------------------------------------------------------
+#define _CPTC(X) static_cast<const char*>(X)
+
+//=============================================================================
+// THROW_DEVFAILED MACRO
+//=============================================================================
+#define THROW_DEVFAILED(p, q, r) \
+  Tango::Except::throw_exception(_CPTC(p), _CPTC(q), _CPTC(r))
+
+//=============================================================================
+// RETHROW_DEVFAILED
+//=============================================================================
+#define RETHROW_DEVFAILED(ex, p, q, r) \
+  Tango::Except::re_throw_exception(ex, _CPTC(p), _CPTC(q), _CPTC(r))
+  
+//-----------------------------------------------------------------------------
+// TIME MACROS
+//-----------------------------------------------------------------------------
+#define TIME_VAL struct timeval
+#define	GET_TIME(T) gettimeofday(&T, 0)
+#if defined(_ELAPSED_SEC)
+# undef ELAPSED_SEC
+#endif
+#define	ELAPSED_SEC(B, A) \
+  static_cast<FPDataType>((A.tv_sec - B.tv_sec) + (1.E-6 * (A.tv_usec - B.tv_usec)))
+#define	ELAPSED_MSEC(B, A) ELAPSED_SEC(B, A) * 1.E3
+#if defined(_IS_VALID_TIME)
+# undef IS_VALID_TIME
+#endif
+#define IS_VALID_TIME(T) T.tv_sec
+
+namespace bpm {
+//-----------------------------------------------------------------------------
+// IMPL OPTIONS
+//-----------------------------------------------------------------------------
+#if defined (_USE_FLOAT_FP_DATA_)
+  typedef float FPDataType;
+# define DEV_DOUBLE DEV_FLOAT
+#else
+  typedef double FPDataType;
+#endif
+
+#if defined(__arm__) && defined(_USE_ARM_OPTIMIZATION_)
+  typedef int IntOffsetDataType; 
+#endif
+} 
+
+//-----------------------------------------------------------------------------
+// NAN
+//-----------------------------------------------------------------------------
+#include <math.h>
+#if defined (NAN)
+# define _NAN_ NAN
+#else
+# define _NAN_ ::sqrt(-1)
+#endif
+
+#endif // __COMMON_H_
diff --git a/src/Condition.h b/src/Condition.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b39232b57bef1a0ac79d3f91305128fa9eec2f2
--- /dev/null
+++ b/src/Condition.h
@@ -0,0 +1,130 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_CONDITION_H_
+#define _BPM_CONDITION_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+
+// ----------------------------------------------------------------------------
+// Implementation-specific header file.
+// ----------------------------------------------------------------------------
+#if ! defined(__CONDITION_IMPLEMENTATION)
+# error "implementation header file incomplete [no condition implementation]"
+#endif
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// FORWARD DECL
+// ----------------------------------------------------------------------------
+class Mutex;
+
+// ----------------------------------------------------------------------------
+//! \class Condition
+//! \brief The BPM Condition variable class
+//!
+//! The Windows implementation is based on D.C.Schmidt & Al solution describes
+//! in the following article: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+//!
+//! Under Linux (and any other \c POSIX platforms), the code relies on the local
+//! \c pthread implementation.
+//!
+//! \remarks
+//! While its destructor is virtual, this class is not supposed to be derived.\n
+//! Be sure to clearly understand the internal behaviour before trying to do so.
+// ----------------------------------------------------------------------------
+class Condition
+{
+public:
+  //! Constructor.
+  //!
+  //! Each condition must be associated to a mutex that must be hold while
+  //! evaluating the condition. It means that \a external_mutex must be locked
+  //! prior to any to call to the Condition interface. See \link
+  //! http://www.cs.wustl.edu/~schmidt/win32-cv-1.html D.C.Schmidt and I.Pyarali
+  //! \endlink article for details.
+  Condition (bpm::Mutex& external_mutex);
+
+  //! Destructor.
+  //!
+  //! While this destructor is virtual, this class is not supposed to be derived.
+  //! Be sure to understand the internal behaviour before trying to do so.
+  virtual ~Condition (void);
+
+  //! Wait until the condition is either \link Condition::signal signaled\endlink
+  //! or \link Condition::broadcast broadcasted\endlink by another thread.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void wait (void);
+
+  //! Wait for the condition to be \link Condition::signal signaled\endlink
+  //! or \link Condition::broadcast broadcasted\endlink by another thread.
+  //! Returns \c false in case the specified timeout expired before the condition 
+  //! was notified. Returns \c true otherwise.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  //!
+  //! \param tmo_msecs The timeout in milliseconds
+  //! \return \c false [timeout expired] or \c true [condition notified]
+  bool timed_wait (unsigned long tmo_msecs);
+
+  //! Signals the condition by notifying \b one of the waiting threads.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void signal (void);
+
+  //! Broadcasts the condition by notifying \b all waiting threads.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void broadcast (void);
+
+private:
+  //! The so called "external mutex" (see D.Schmidt's article)
+  Mutex & m_external_lock;
+  
+  //! Not implemented private member
+  Condition (const Condition&);
+  //! Not implemented private member
+  Condition & operator= (const Condition&);
+  
+  //! hidden/abstract platform specific implementation
+  __CONDITION_IMPLEMENTATION;
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+#  include <threading/impl/PosixConditionImpl.i>
+#endif
+
+#endif //- _BPM_CONDITION_H_
diff --git a/src/DataProcessing.cpp b/src/DataProcessing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0a23e90fb6f3fa1c1c2b6954739e2e7855622cf
--- /dev/null
+++ b/src/DataProcessing.cpp
@@ -0,0 +1,905 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#include "DataProcessing.h"
+#include "TimeUtils.h"
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+# include "ArmOptimization.h"
+#endif
+
+// ============================================================================
+//- select cordic algorithm implementation
+// ============================================================================
+#if defined(_EMBEDDED_DEVICE_) &&  defined(_USE_ARM_OPTIMIZATION_)
+//- arm optimization: use M. Abbott's asm cordic algorithm implementation
+#   define CORDIC_MAG ::CordicMagnitude
+#else
+//- no arm optimization: use the CSPI ordic algorithm implementation 
+#   define CORDIC_MAG bpm::cspi_cordic_amp 
+#endif
+
+namespace bpm
+{
+
+// ============================================================================
+// DataProcessing::compute_pos for Turn-by-Turn data (DD)
+// ============================================================================
+void DataProcessing::compute_pos (DDData & _dd_data,
+                                  const DDRawBuffer & _dd_raw_buffer,
+                                  size_t _actual_num_samples,
+                                  const BPMConfig & _config)
+{
+  switch (_config.get_pos_algorithm())
+  {
+    //------------------------------------------------------------------------------
+    //- use std algorithms
+    case BPMConfig::kSTD_POS_ALGO:
+      {
+        switch(_config.get_block_geometry())
+        {
+          case BPMConfig::BLOCK_GEOMETRY_45:
+            DataProcessing::compute_pos_block_45 (_dd_data,
+                                                  _dd_raw_buffer,
+                                                  _actual_num_samples,
+                                                  _config);
+            break;
+          case BPMConfig::BLOCK_GEOMETRY_90:
+            DataProcessing::compute_pos_block_90 (_dd_data,
+                                                  _dd_raw_buffer,
+                                                  _actual_num_samples,
+                                                  _config);
+            break;
+          case BPMConfig::BLOCK_GEOMETRY_UNKNOWN:
+            Tango::Except::throw_exception(_CPTC("unexpected configuration"),
+                                           _CPTC("unknown BPM buttons configuration"),
+                                           _CPTC("DataProcessing::compute_pos"));
+            break;
+        }
+      }
+      break;
+    //------------------------------------------------------------------------------
+    //- use ESRF SR algorithm
+    case BPMConfig::kESRF_SR_POS_ALGO:
+      {
+        DataProcessing::compute_pos_esrf_sr (_dd_data,
+                                             _dd_raw_buffer,
+                                             _actual_num_samples,
+                                             _config);
+      }
+      break;
+    //------------------------------------------------------------------------------
+    //- ohoh!
+    default:
+      Tango::Except::throw_exception(_CPTC("unexpected configuration"),
+                                     _CPTC("unknown position computation algorithm"),
+                                     _CPTC("DataProcessing::compute_pos"));
+      break;
+  }
+}
+
+// ============================================================================
+// DataProcessing::compute_pos for slow acquisition data (SA)
+// ============================================================================
+void DataProcessing::compute_pos (SAData & _data, const BPMConfig & _config)
+{
+  //- compute pos or use FPGA data?
+  if (! _config.local_sa_pos_computation_enabled())
+  {
+    //- just convert from nm to mm
+    _data.x_ *= 1.e-6;
+    _data.z_ *= 1.e-6;
+    _data.q_ *= 1.e-6; 
+    return;
+  }
+
+  switch (_config.get_pos_algorithm())
+  {
+    //------------------------------------------------------------------------------
+    //- use std algorithms
+    case BPMConfig::kSTD_POS_ALGO:
+      {
+        switch(_config.get_block_geometry())
+        {
+          case BPMConfig::BLOCK_GEOMETRY_45:
+            DataProcessing::compute_pos_block_45 (_data, _config);
+            break;
+          case BPMConfig::BLOCK_GEOMETRY_90:
+            DataProcessing::compute_pos_block_90 (_data, _config);
+            break;
+          case BPMConfig::BLOCK_GEOMETRY_UNKNOWN:
+            Tango::Except::throw_exception(_CPTC("unexpected configuration"),
+                                           _CPTC("unknown BPM buttons configuration"),
+                                           _CPTC("DataProcessing::compute_pos"));
+            break;
+        }
+      }
+      break;
+    //------------------------------------------------------------------------------
+    //- use ESRF SR algorithm
+    case BPMConfig::kESRF_SR_POS_ALGO:
+      {
+        DataProcessing::compute_pos_esrf_sr (_data, _config);
+      }
+      break;
+    //------------------------------------------------------------------------------
+    //- ohoh!
+    default:
+      Tango::Except::throw_exception(_CPTC("unexpected configuration"),
+                                     _CPTC("unknown position computation algorithm"),
+                                     _CPTC("DataProcessing::compute_pos"));
+      break;
+  }
+}
+
+#if ! defined(_EMBEDDED_DEVICE_) || ! defined(_USE_ARM_OPTIMIZATION_)
+// ============================================================================
+// cspi_cordic_amp
+// ============================================================================
+// we include our own version of the cspi <cordic_amp> function in order to
+// to avoid cspi library compil option dependency. 
+// ============================================================================
+//               Table of CORDIC gain (CG) corrections:
+// ----------------------------------------------------------------------------
+// L             CG                      1/CG           (1/CG)<<32
+// ----------------------------------------------------------------------------
+// 0  : 1.41421356237310000000   0.70710678118654700    3037000500
+// 1  : 1.58113883008419000000   0.63245553203367600    2716375826
+// 2  : 1.62980060130066000000   0.61357199107789600    2635271635
+// 3  : 1.64248406575224000000   0.60883391251775200    2614921743
+// 4  : 1.64568891575726000000   0.60764825625616800    2609829388
+// 5  : 1.64649227871248000000   0.60735177014129600    2608555990
+// 6  : 1.64669325427364000000   0.60727764409352600    2608237621
+// 7  : 1.64674350659690000000   0.60725911229889300    2608158028
+// 8  : 1.64675607020488000000   0.60725447933256200    2608138129
+// 9  : 1.64675921113982000000   0.60725332108987500    2608133154
+// 10 : 1.64675999637562000000   0.60725303152913400    2608131911
+// 11 : 1.64676019268469000000   0.60725295913894500    2608131600 (!)
+// 12 : 1.64676024176197000000   0.60725294104139700    2608131522
+// 13 : 1.64676025403129000000   0.60725293651701000    2608131503
+// 14 : 1.64676025709862000000   0.60725293538591400    2608131498
+// 15 : 1.64676025786545000000   0.60725293510313900    2608131497
+// 16 : 1.64676025805716000000   0.60725293503244600    2608131496
+// 17 : 1.64676025810509000000   0.60725293501477200    2608131496
+// 18 : 1.64676025811707000000   0.60725293501035400    2608131496
+// 19 : 1.64676025812007000000   0.60725293500925000    2608131496
+// 20 : 1.64676025812082000000   0.60725293500897300    2608131496
+// ----------------------------------------------------------------------------
+#define CORDIC_IGNORE_GAIN
+// ----------------------------------------------------------------------------
+static inline int cspi_cordic_amp ( int  I, int  Q )
+{
+	//- The number of iterations = CORDIC_MAXLEVEL + 1
+	static const int CORDIC_MAXLEVEL = 11;
+  
+  //- CORDIC gain correction factor associated with the CORDIC_MAXLEVEL.
+  static const long long CORDIC_GAIN64 = 2608131600LL; // (1/CG)<<32
+  
+	int  tmp_I;
+	int  L = 0;
+	
+	if ( I < 0 ) 
+	{
+		tmp_I = I;
+		if ( Q > 0 ) 
+		{
+		  I = Q;
+		  Q = -tmp_I;     // Rotate by -90 degrees
+		}
+		else 
+		{
+		  I = -Q;
+		  Q = tmp_I;      // Rotate by +90 degrees
+		}
+	}
+	for( ; L <= CORDIC_MAXLEVEL; ++L  ) 
+	{
+		tmp_I = I;
+		if ( Q >= 0 )
+		{
+			// Positive phase; do negative rotation
+			I += (Q >> L); 
+      Q -= (tmp_I >> L);
+		}
+		else 
+		{
+			// Negative phase; do positive rotation
+			I -= (Q >> L); 
+      Q += (tmp_I >> L);
+		}
+	}
+  
+#if defined(CORDIC_IGNORE_GAIN)
+  return I;
+#else
+  return (int)((CORDIC_GAIN64 * I) >> 32);
+#endif
+}
+# endif  // ! _USE_ARM_OPTIMIZATION_
+
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+// ============================================================================
+// bpm::delta_to_position                   ** written by M.Abbott - DIAMOND **
+// ============================================================================
+// Computes K * M / S without loss of precision.  We use
+// our knowledge of the arguments to do this work as efficiently as possible.
+// 
+// Firstly we know that InvS = 2^(60-shift)/S and that S < 2^(31-shift).
+// However, we also know that |M| <= S (this is a simple consequence of S
+// being a sum of non-negative values and M being a sum of differences), so
+// in particular also |M| < 2^(31-shift) and so we can safely get rid of the
+// shift in InvS by giving it to M!
+// 
+// We have now transformed K * M / S to 2^(60-shift) * K * M * InvS and then
+// to 2^60 * K * (2^-shift * M) * InvS.  Note finally that the scaling
+// constant K can be safely bounded by 2^27 ~~ 128mm and so we can
+// with excellent efficiency compute
+// 
+//                 K * M    -64     4        shift
+//      Position = ----- = 2    * (2  K) * (2      M) * InvS
+//                   S
+// 
+// In fact we gain slightly more head-room on K by computing K*InvS as an
+// <unsigned> multiply: an upper bound on K of over 250mm seems ample!
+ // ============================================================================
+inline int delta_to_position (int k, int m, int invs, int shift)
+{
+  return ::MulSS(::MulUU(k << 4, invs), m << shift);
+}
+
+#endif //- _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+// ============================================================================
+// DataProcessing::compute_pos_block_45 for Turn-by-Turn data (DD) 
+// ============================================================================
+void DataProcessing::compute_pos_block_45 (DDData & _dd_data,
+                                           const DDRawBuffer & _dd_raw_buffer, 
+                                           size_t actual_num_samples,
+                                           const BPMConfig & _config)
+{
+  CSPI_DD_RAWATOM * _dd_raw_data = _dd_raw_buffer.base();
+  
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+// Timer t;
+// #define kDD_NUM_IT 200
+// for (size_t it = 0; it < kDD_NUM_IT; it++)
+// {
+
+  for (size_t i = 0; i < actual_num_samples; i++)
+  {
+    //- optimized pure integer algorithm
+    //----------------------------------------------------------------------
+
+    // In oder to avoid overflow in the computation of the total intensity (sum),
+    // we prescale each button value by 4 (i.e. >> 2). This can involve loss of 
+    // bits when the intensity is extremely low, but in fact the bottom bits are 
+    // pretty well pure noise and can be cheaply discarded. The button values 
+    // A,B,C,D are known to lie in the range 0 to 2^31 - 1 so we similarly know 
+    // that: 0 <= S < 2^31.
+    
+    i32 va = (CORDIC_MAG(_dd_raw_data[i].sinVa, _dd_raw_data[i].cosVa) >> 2)
+                * _config.int_VaGainCorrection;
+
+    i32 vb = (CORDIC_MAG(_dd_raw_data[i].sinVb, _dd_raw_data[i].cosVb) >> 2)
+                * _config.int_VbGainCorrection;
+
+    i32 vc = (CORDIC_MAG(_dd_raw_data[i].sinVc, _dd_raw_data[i].cosVc) >> 2)
+                * _config.int_VcGainCorrection;
+
+    i32 vd = (CORDIC_MAG(_dd_raw_data[i].sinVd, _dd_raw_data[i].cosVd) >> 2)
+                * _config.int_VdGainCorrection;
+ 
+    i32 sum = va + vb + vc + vd;
+
+    int shift = 0;
+    int inv_sum = ::Reciprocal(sum, shift);
+    shift = 60 - shift;
+            
+    i32 x = bpm::delta_to_position(_config.int_Kx, va - vb - vc + vd, inv_sum, shift) 
+               - _config.int_Xoffset_local;
+
+    i32 z = bpm::delta_to_position(_config.int_Kz, va + vb - vc - vd, inv_sum, shift) 
+              - _config.int_Zoffset_local;
+   
+    i32 q = bpm::delta_to_position(_config.int_Kx, va - vb + vc - vd, inv_sum, shift) 
+              - _config.int_Qoffset_local;
+    
+    //- pos: nano to millimeters 
+    NM_TO_MM(x, _dd_data.x_.base() + i); 
+    NM_TO_MM(z, _dd_data.z_.base() + i); 
+    NM_TO_MM(q, _dd_data.q_.base() + i); 
+
+    if (DDData::m_optional_data_enabled)
+    {
+      INT_TO_FP(_dd_raw_data[i].sinVa, _dd_data.sin_va_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVb, _dd_data.sin_vb_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVc, _dd_data.sin_vc_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVd, _dd_data.sin_vd_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVa, _dd_data.cos_va_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVb, _dd_data.cos_vb_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVc, _dd_data.cos_vc_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVd, _dd_data.cos_vd_.base() + i);
+    }
+    
+    //- electrode values: int to float
+    UNSCALE_BUTTON_GAIN_CORRECTION(va, _dd_data.va_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vb, _dd_data.vb_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vc, _dd_data.vc_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vd, _dd_data.vd_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(sum, _dd_data.sum_.base() + i);
+  } //- for each DD raw sample
+
+// }
+// double dt = t.elapsed_usec();
+// double dd_perf = t.elapsed_usec() / (kDD_NUM_IT * actual_num_samples);
+// std::cout << "dd_perf: " << dd_perf << " usec per DDRawAtom" << std::endl;
+ 
+//   std::cout << "DataProcessing::compute_pos_block_45::DD::optimized::x: " 
+//             << _dd_data.x_[actual_num_samples - 1] << std::endl;
+//   std::cout << "DataProcessing::compute_pos_block_45::DD::optimized::z: " 
+//             << _dd_data.z_[actual_num_samples - 1] << std::endl;
+
+#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm 
+  //----------------------------------------------------------------------
+  for (size_t i = 0; i < actual_num_samples; i++)
+  {
+    _dd_data.va_[i] = CORDIC_MAG(_dd_raw_data[i].sinVa, _dd_raw_data[i].cosVa)
+                        * _config.VaGainCorrection;
+
+    _dd_data.vb_[i] = CORDIC_MAG(_dd_raw_data[i].sinVb, _dd_raw_data[i].cosVb)
+                        * _config.VbGainCorrection;
+
+    _dd_data.vc_[i] = CORDIC_MAG(_dd_raw_data[i].sinVc, _dd_raw_data[i].cosVc)
+                        * _config.VcGainCorrection;
+
+    _dd_data.vd_[i] = CORDIC_MAG(_dd_raw_data[i].sinVd, _dd_raw_data[i].cosVd)
+                        * _config.VdGainCorrection;
+    
+    _dd_data.sum_[i] = _dd_data.va_[i] + _dd_data.vb_[i] + _dd_data.vc_[i] + _dd_data.vd_[i];
+
+    _dd_data.x_[i] = 
+        _config.Kx * (((_dd_data.va_[i] + _dd_data.vd_[i]) - (_dd_data.vb_[i] + _dd_data.vc_[i])) / _dd_data.sum_[i]) 
+            - _config.Xoffset_local;
+
+    _dd_data.z_[i] = 
+        _config.Kz * (((_dd_data.va_[i] + _dd_data.vb_[i]) - (_dd_data.vc_[i] + _dd_data.vd_[i])) / _dd_data.sum_[i]) 
+            - _config.Zoffset_local;
+
+    _dd_data.q_[i] = 
+        _config.Kx * (((_dd_data.va_[i] + _dd_data.vc_[i]) - (_dd_data.vb_[i] + _dd_data.vd_[i])) / _dd_data.sum_[i]) 
+            - _config.Qoffset_local;
+
+    if (DDData::m_optional_data_enabled)
+    {
+      _dd_data.sin_va_[i] = _dd_raw_data[i].sinVa;
+      _dd_data.cos_va_[i] = _dd_raw_data[i].cosVa;
+      _dd_data.sin_vb_[i] = _dd_raw_data[i].sinVb;
+      _dd_data.cos_vb_[i] = _dd_raw_data[i].cosVb;
+      _dd_data.sin_vc_[i] = _dd_raw_data[i].sinVc;
+      _dd_data.cos_vc_[i] = _dd_raw_data[i].cosVc;
+      _dd_data.sin_vd_[i] = _dd_raw_data[i].sinVd;
+      _dd_data.cos_vd_[i] = _dd_raw_data[i].cosVd;
+    }
+  } //- for each DD raw sample
+
+//   std::cout << "DataProcessing::compute_pos_block_45::DD::---std---::x: "
+//             << _dd_data.x_[actual_num_samples - 1] << std::endl;
+//   std::cout << "DataProcessing::compute_pos_block_45::DD::---std---::z: " 
+//             << _dd_data.z_[actual_num_samples - 1] << std::endl;
+  
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+}
+
+// ============================================================================
+// DataProcessing::compute_pos_block_90 for Turn-by-Turn data (DD) 
+// ============================================================================
+void DataProcessing::compute_pos_block_90 (DDData & _dd_data,
+                                           const DDRawBuffer & _dd_raw_buffer, 
+                                           size_t actual_num_samples,
+                                           const BPMConfig & _config)
+{
+  CSPI_DD_RAWATOM * _dd_raw_data = _dd_raw_buffer.base();
+ 
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+  for (size_t i = 0; i < actual_num_samples; i++)
+  {
+    //- optimized pure integer algorithm
+    //----------------------------------------------------------------------
+
+    // In oder to avoid overflow in the computation of the total intensity (sum),
+    // we prescale each button value by 4 (i.e. >> 2). This can involve loss of 
+    // bits when the intensity is extremely low, but in fact the bottom bits are 
+    // pretty well pure noise and can be cheaply discarded. The button values 
+    // A,B,C,D are known to lie in the range 0 to 2^31 - 1 so we similarly know 
+    // that: 0 <= S < 2^31.
+    
+    i32 va = (CORDIC_MAG(_dd_raw_data[i].sinVa, _dd_raw_data[i].cosVa) >> 2)
+                * _config.int_VaGainCorrection;
+
+    i32 vb = (CORDIC_MAG(_dd_raw_data[i].sinVb, _dd_raw_data[i].cosVb) >> 2)
+                * _config.int_VbGainCorrection;
+
+    i32 vc = (CORDIC_MAG(_dd_raw_data[i].sinVc, _dd_raw_data[i].cosVc) >> 2)
+                * _config.int_VcGainCorrection;
+
+    i32 vd = (CORDIC_MAG(_dd_raw_data[i].sinVd, _dd_raw_data[i].cosVd) >> 2)
+                * _config.int_VdGainCorrection;
+
+    i32 sum = va + vb + vc + vd;
+
+    int shift = 0;
+    int inv_sum = ::Reciprocal(vd + vb, shift);
+    shift = 60 - shift;  
+        
+    i32 x = bpm::delta_to_position(_config.int_Kx, vd - vb, inv_sum, shift)
+              - _config.int_Xoffset_local;
+
+    shift = 0;
+    inv_sum = ::Reciprocal(va + vc, shift);
+    shift = 60 - shift;  
+    
+    i32 z = bpm::delta_to_position(_config.int_Kz, va - vc, inv_sum, shift)
+              - _config.int_Zoffset_local;
+
+    shift = 0;
+    inv_sum = ::Reciprocal(sum, shift);
+    shift = 60 - shift;  
+    
+    i32 q = bpm::delta_to_position(_config.int_Kx, va - vb + vc - vd, inv_sum, shift) 
+              - _config.int_Qoffset_local;
+        
+    //- pos: nano to millimeters 
+    NM_TO_MM(x, _dd_data.x_.base() + i); 
+    NM_TO_MM(z, _dd_data.z_.base() + i); 
+    NM_TO_MM(q, _dd_data.q_.base() + i); 
+
+    if (DDData::m_optional_data_enabled)
+    {
+      INT_TO_FP(_dd_raw_data[i].sinVa, _dd_data.sin_va_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVb, _dd_data.sin_vb_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVc, _dd_data.sin_vc_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].sinVd, _dd_data.sin_vd_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVa, _dd_data.cos_va_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVb, _dd_data.cos_vb_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVc, _dd_data.cos_vc_.base() + i);
+      INT_TO_FP(_dd_raw_data[i].cosVd, _dd_data.cos_vd_.base() + i);
+    }
+    
+    //- electrode values: int to float
+    UNSCALE_BUTTON_GAIN_CORRECTION(va, _dd_data.va_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vb, _dd_data.vb_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vc, _dd_data.vc_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(vd, _dd_data.vd_.base() + i);
+    UNSCALE_BUTTON_GAIN_CORRECTION(sum, _dd_data.sum_.base() + i);
+
+  } //- for each DD raw sample
+  
+//   std::cout << "DataProcessing::compute_pos_block_90::DD::optimized::x: " 
+//             << _dd_data.x_[actual_num_samples - 1] << std::endl;
+//   std::cout << "DataProcessing::compute_pos_block_90::DD::optimized::z: " 
+//             << _dd_data.z_[actual_num_samples - 1] << std::endl;
+
+#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm
+  //----------------------------------------------------------------------
+  for (size_t i = 0; i < actual_num_samples; i++)
+  {
+    _dd_data.va_[i] = CORDIC_MAG(_dd_raw_data[i].sinVa, _dd_raw_data[i].cosVa)
+                        * _config.VaGainCorrection;
+
+    _dd_data.vb_[i] = CORDIC_MAG(_dd_raw_data[i].sinVb, _dd_raw_data[i].cosVb)
+                        * _config.VbGainCorrection;
+
+    _dd_data.vc_[i] = CORDIC_MAG(_dd_raw_data[i].sinVc, _dd_raw_data[i].cosVc)
+                        * _config.VcGainCorrection;
+
+    _dd_data.vd_[i] = CORDIC_MAG(_dd_raw_data[i].sinVd, _dd_raw_data[i].cosVd)
+                        * _config.VdGainCorrection;
+                        
+    _dd_data.sum_[i] = _dd_data.va_[i] + _dd_data.vb_[i] + _dd_data.vc_[i] + _dd_data.vd_[i];
+
+    _dd_data.x_[i] = 
+        _config.Kx * ((_dd_data.vd_[i] - _dd_data.vb_[i]) / (_dd_data.vd_[i] + _dd_data.vb_[i])) 
+            - _config.Xoffset_local;
+
+    _dd_data.z_[i] = 
+        _config.Kz * ((_dd_data.va_[i] - _dd_data.vc_[i]) / (_dd_data.va_[i] + _dd_data.vc_[i])) 
+            - _config.Zoffset_local;
+
+    _dd_data.q_[i] = 
+        _config.Kx * (((_dd_data.va_[i] + _dd_data.vc_[i]) - (_dd_data.vb_[i] + _dd_data.vd_[i])) / _dd_data.sum_[i]) 
+            - _config.Qoffset_local;
+
+    if (DDData::m_optional_data_enabled)
+    {
+      _dd_data.sin_va_[i] = _dd_raw_data[i].sinVa;
+      _dd_data.cos_va_[i] = _dd_raw_data[i].cosVa;
+      _dd_data.sin_vb_[i] = _dd_raw_data[i].sinVb;
+      _dd_data.cos_vb_[i] = _dd_raw_data[i].cosVb;
+      _dd_data.sin_vc_[i] = _dd_raw_data[i].sinVc;
+      _dd_data.cos_vc_[i] = _dd_raw_data[i].cosVc;
+      _dd_data.sin_vd_[i] = _dd_raw_data[i].sinVd;
+      _dd_data.cos_vd_[i] = _dd_raw_data[i].cosVd;
+    }
+  }
+  
+//   std::cout << "DataProcessing::compute_pos_block_90::DD::---std---::x: "
+//             << _dd_data.x_[actual_num_samples - 1] << std::endl;
+//   std::cout << "DataProcessing::compute_pos_block_90::DD::---std---::z: " 
+//             << _dd_data.z_[actual_num_samples - 1] << std::endl;
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+}
+
+// ============================================================================
+// DataProcessing::compute_pos_esrf_sr for Turn-by-Turn data (DD) 
+// ============================================================================
+void DataProcessing::compute_pos_esrf_sr (DDData & _dd_data,
+                                          const DDRawBuffer & _dd_raw_buffer, 
+                                          size_t actual_num_samples,
+                                          const BPMConfig & _config)
+{
+//  std::cout << "DataProcessing::compute_pos_esrf_sr <-" << std::endl ;
+ 
+  CSPI_DD_RAWATOM * _dd_raw_data = _dd_raw_buffer.base();
+
+//#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+//#error no ESRF SR impl for ARM!
+//  for (size_t i = 0; i < actual_num_samples; i++)
+//  {
+//    //- optimized pure integer algorithm
+//    //----------------------------------------------------------------------
+//    
+//  }
+//// std::cout << "DataProcessing::compute_pos_esrf_sr::DD::optimized::x: " 
+////           << _dd_data.x_[actual_num_samples - 1] << std::endl;
+//// std::cout << "DataProcessing::compute_pos_esrf_sr::DD::optimized::z: " 
+////           << _dd_data.z_[actual_num_samples - 1] << std::endl;
+
+//#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm
+  //----------------------------------------------------------------------
+
+  for (size_t i = 0; i < actual_num_samples; i++)
+  {
+    _dd_data.va_[i] = CORDIC_MAG(_dd_raw_data[i].sinVa, _dd_raw_data[i].cosVa)
+                        * _config.VaGainCorrection;
+
+    _dd_data.vb_[i] = CORDIC_MAG(_dd_raw_data[i].sinVb, _dd_raw_data[i].cosVb)
+                        * _config.VbGainCorrection;
+
+    _dd_data.vc_[i] = CORDIC_MAG(_dd_raw_data[i].sinVc, _dd_raw_data[i].cosVc)
+                        * _config.VcGainCorrection;
+
+    _dd_data.vd_[i] = CORDIC_MAG(_dd_raw_data[i].sinVd, _dd_raw_data[i].cosVd)
+                        * _config.VdGainCorrection;
+                        
+    _dd_data.sum_[i] = _dd_data.va_[i] + _dd_data.vb_[i] + _dd_data.vc_[i] + _dd_data.vd_[i];
+    
+    _dd_data.q_[i] = 
+        _config.Kx * (((_dd_data.va_[i] + _dd_data.vc_[i]) - (_dd_data.vb_[i] + _dd_data.vd_[i])) / _dd_data.sum_[i]) 
+            - _config.Qoffset_local;
+            
+    //- the algorithm is given by: (c.f. Joel Chavanne Feb 2002)
+    //- X = -0.0592 + 11.469 * atanh(1.3658 * Qh)
+    //- In the present case, the offset -0.0592 is not applied
+    //- because we suppose it is already included in the offset.
+    //- which has been determided experimentally.
+    //- However, we add the -0.0592 to X to calculate the Z with the
+    //- following formula: Z = 14.37 * (1+0.001452 * X * X).
+			 
+    //- Qh = ((a - c) / (a + c) + (d - b) / (d + b))/2;
+    //- Rv = ((a - d) / (a + d) + (b - c) / (b + c))/2;
+			   
+    //- Xb = 11.469 * atanh(1.3658 * Qh);
+    //- Xb2 = Xb - 0.0592;
+    //- Zb = 14.37 * (1 + 0.001452 *(Xb2) * (Xb2)) * Rv;
+  
+    double Qh = ((_dd_data.va_[i] - _dd_data.vc_[i]) / (_dd_data.va_[i] + _dd_data.vc_[i]) + 
+                 (_dd_data.vd_[i] - _dd_data.vb_[i]) / (_dd_data.vd_[i] + _dd_data.vb_[i])) / 2.0;
+
+    double Rv = ((_dd_data.va_[i] - _dd_data.vd_[i]) / (_dd_data.va_[i] + _dd_data.vd_[i]) +
+                 (_dd_data.vb_[i] - _dd_data.vc_[i]) / (_dd_data.vb_[i] + _dd_data.vc_[i])) / 2.0;
+  
+    _dd_data.x_[i] = 11.469 * atanh(1.3658 * Qh);
+    
+    double Xb2  = _dd_data.x_[i] - 0.0592;
+
+    _dd_data.z_[i] = 14.37 * (1 + 0.001452 * Xb2 * Xb2) * Rv; 
+  }
+  
+// std::cout << "DataProcessing::compute_pos_esrf_sr::DD::---std---::x: " 
+//           << _dd_data.x_[actual_num_samples - 1] << std::endl;
+// std::cout << "DataProcessing::compute_pos_esrf_sr::DD::---std---::z: " 
+//           << _dd_data.z_[actual_num_samples - 1] << std::endl;
+         
+//#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+// std::cout << "DataProcessing::compute_pos_esrf_sr ->" << std::endl;
+}
+
+// ============================================================================
+// DataProcessing::compute_pos_block_45 for slow acquisition data (SA) 
+// ============================================================================
+void DataProcessing::compute_pos_block_45 (SAData & _sa_data, const BPMConfig & _config)
+{
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+// Timer t;
+// #define kSA_NUM_IT 100000
+// for (size_t it = 0; it < kSA_NUM_IT; it++)
+// {
+  
+  //- optimized pure integer algorithm
+  //----------------------------------------------------------------------
+  
+  // In oder to avoid overflow in the computation of the total intensity S (sum),
+  // we prescale each button value by 4 (i.e. >> 2). This can involve loss of 
+  // bits when the intensity is extremely low, but in fact the bottom bits are 
+  // pretty well pure noise and can be cheaply discarded. The button values 
+  // A,B,C,D are known to lie in the range 0 to 2^31 - 1 so we similarly know 
+  // that: 0 <= S < 2^31.
+  
+  i32 va = (_sa_data.int_va_ >> 2) * _config.int_VaGainCorrection;   
+  i32 vb = (_sa_data.int_vb_ >> 2) * _config.int_VbGainCorrection;   
+  i32 vc = (_sa_data.int_vc_ >> 2) * _config.int_VcGainCorrection;   
+  i32 vd = (_sa_data.int_vd_ >> 2) * _config.int_VdGainCorrection;
+  
+  i32 sum = va + vb + vc + vd;
+
+  i32 shift = 0;
+  i32 inv_sum = ::Reciprocal(sum, shift);
+  shift = 60 - shift;
+  
+  i32 x = bpm::delta_to_position(_config.int_Kx, va - vb - vc + vd, inv_sum, shift) 
+            - _config.int_Xoffset_local;
+
+  i32 z = bpm::delta_to_position(_config.int_Kz, va + vb - vc - vd, inv_sum, shift)
+            - _config.int_Zoffset_local;
+
+  i32 q = bpm::delta_to_position(_config.int_Kx, va - vb + vc - vd, inv_sum, shift) 
+            - _config.int_Qoffset_local;
+
+  //- store x & z for SA stats computation (see BPMData.cpp)
+  _sa_data.int_x_ = x;  
+  _sa_data.int_z_ = z;  
+  
+  //- pos: nano to millimeters 
+  NM_TO_MM(x, &_sa_data.x_); 
+  NM_TO_MM(z, &_sa_data.z_); 
+  NM_TO_MM(q, &_sa_data.q_); 
+
+  //- electrode values: int to float
+  UNSCALE_BUTTON_GAIN_CORRECTION(va, &_sa_data.va_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vb, &_sa_data.vb_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vc, &_sa_data.vc_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vd, &_sa_data.vd_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(sum, &_sa_data.sum_);
+  
+// }
+// double dt = t.elapsed_usec();
+// double sa_perf = t.elapsed_usec() / kSA_NUM_IT ;
+// std::cout << "sa_perf: " << sa_perf << " usec per SARawAtom" << std::endl;
+
+// std::cout << "DataProcessing::compute_pos_block_45::SA::optimized::x: " 
+//           << _sa_data.x_ << std::endl;
+// std::cout << "DataProcessing::compute_pos_block_45::SA::optimized::z: " 
+//           << _sa_data.z_ << std::endl;
+
+#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm
+  //----------------------------------------------------------------------
+  
+  //_config.dump_offsets();
+  //_config.dump_env_parameters();
+  
+  _sa_data.va_ *= _config.VaGainCorrection;
+  _sa_data.vb_ *= _config.VbGainCorrection;
+  _sa_data.vc_ *= _config.VcGainCorrection;
+  _sa_data.vd_ *= _config.VdGainCorrection;
+  
+  _sa_data.sum_ = _sa_data.va_ + _sa_data.vb_ + _sa_data.vc_ + _sa_data.vd_;
+
+  _sa_data.x_ = 
+      _config.Kx * (((_sa_data.va_ + _sa_data.vd_) - (_sa_data.vb_ + _sa_data.vc_)) / _sa_data.sum_) 
+          - _config.Xoffset_local;
+
+  _sa_data.z_ = 
+      _config.Kz * (((_sa_data.va_ + _sa_data.vb_) - (_sa_data.vc_ + _sa_data.vd_)) / _sa_data.sum_) 
+          - _config.Zoffset_local;
+
+  _sa_data.q_ = 
+      _config.Kx * (((_sa_data.va_ + _sa_data.vc_) - (_sa_data.vb_ + _sa_data.vd_)) / _sa_data.sum_) 
+          - _config.Qoffset_local;
+   
+  //- std::cout << "DataProcessing::compute_pos_block_45::SA::---std---::x: " << _sa_data.x_ << std::endl;
+  //- std::cout << "DataProcessing::compute_pos_block_45::SA::---std---::z: " << _sa_data.z_ << std::endl;
+
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+}
+
+// ============================================================================
+// DataProcessing::compute_pos_block_90 for slow acquisition data (SA) 
+// ============================================================================
+void DataProcessing::compute_pos_block_90 (SAData & _sa_data, const BPMConfig & _config)
+{
+#if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_)
+
+  //- optimized pure integer algorithm
+  //----------------------------------------------------------------------
+
+  // In oder to avoid overflow in the computation of the total intensity sum),
+  // we prescale each button value by 4 (i.e. >> 2). This can involve loss of 
+  // bits when the intensity is extremely low, but in fact the bottom bits are 
+  // pretty well pure noise and can be cheaply discarded. The button values 
+  // A,B,C,D are known to lie in the range 0 to 2^31 - 1 so we similarly know 
+  // that: 0 <= S < 2^31.
+
+  i32 va = (_sa_data.int_va_ >> 2) * _config.int_VaGainCorrection;   
+  i32 vb = (_sa_data.int_vb_ >> 2) * _config.int_VbGainCorrection;   
+  i32 vc = (_sa_data.int_vc_ >> 2) * _config.int_VcGainCorrection;   
+  i32 vd = (_sa_data.int_vd_ >> 2) * _config.int_VdGainCorrection;
+
+  i32 sum = va + vb + vc + vd;
+
+  int shift = 0;
+  int inv_sum = ::Reciprocal(vd + vb, shift);
+  shift = 60 - shift;  
+        
+  i32 x = bpm::delta_to_position(_config.int_Kx, vd - vb, inv_sum, shift)
+            - _config.int_Xoffset_local;
+
+  shift = 0;
+  inv_sum = ::Reciprocal(va + vc, shift);
+  shift = 60 - shift;  
+  
+  i32 z = bpm::delta_to_position(_config.int_Kz, va - vc, inv_sum, shift)
+            - _config.int_Zoffset_local;
+
+  shift = 0;
+  inv_sum = ::Reciprocal(sum, shift);
+  shift = 60 - shift;  
+  
+  i32 q = bpm::delta_to_position(_config.int_Kx, va - vb + vc - vd, inv_sum, shift) 
+            - _config.int_Qoffset_local;       
+              
+  //- pos: nano to millimeters 
+  NM_TO_MM(x, &_sa_data.x_); 
+  NM_TO_MM(z, &_sa_data.z_); 
+  NM_TO_MM(q, &_sa_data.q_); 
+
+  //- electrode values: int to float
+  UNSCALE_BUTTON_GAIN_CORRECTION(va, &_sa_data.va_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vb, &_sa_data.vb_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vc, &_sa_data.vc_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(vd, &_sa_data.vd_);
+  UNSCALE_BUTTON_GAIN_CORRECTION(sum, &_sa_data.sum_);
+
+// std::cout << "DataProcessing::compute_pos_block_90::SA::optimized::x: " 
+//           << _sa_data.x_ << std::endl;
+// std::cout << "DataProcessing::compute_pos_block_90::SA::optimized::z: " 
+//           << _sa_data.z_ << std::endl;
+
+#else // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+
+  //- pure floating point algorithm
+  //----------------------------------------------------------------------
+
+  _sa_data.va_ *= _config.VaGainCorrection;
+  _sa_data.vb_ *= _config.VbGainCorrection;
+  _sa_data.vc_ *= _config.VcGainCorrection;
+  _sa_data.vd_ *= _config.VdGainCorrection;
+
+  _sa_data.sum_ = _sa_data.va_ + _sa_data.vb_ + _sa_data.vc_ + _sa_data.vd_;
+
+  _sa_data.x_ = 
+      _config.Kx * ((_sa_data.vd_ - _sa_data.vb_) / (_sa_data.vd_ + _sa_data.vb_)) 
+          - _config.Xoffset_local;
+
+  _sa_data.z_ = 
+      _config.Kz * ((_sa_data.va_ - _sa_data.vc_) / (_sa_data.va_ + _sa_data.vc_)) 
+          - _config.Zoffset_local;
+
+  _sa_data.q_ = 
+      _config.Kx * (((_sa_data.va_ + _sa_data.vc_) - (_sa_data.vb_ + _sa_data.vd_)) / _sa_data.sum_) 
+          - _config.Qoffset_local;
+          
+// std::cout << "DataProcessing::compute_pos_block_90::SA::---std---::x: " 
+//           << _sa_data.x_ << std::endl;
+// std::cout << "DataProcessing::compute_pos_block_90::SA::---std---::z: " 
+//           << _sa_data.z_ << std::endl;
+  
+#endif // _EMBEDDED_DEVICE_ && _USE_ARM_OPTIMIZATION_
+}
+
+// ============================================================================
+// DataProcessing::compute_pos_esrf_sr for slow acquisition data (SA) 
+// ============================================================================
+void DataProcessing::compute_pos_esrf_sr (SAData & _sa_data, const BPMConfig & _config)
+{
+  //- the SAData has been pre-filled with a CSPI_SA_ATOM
+  _sa_data.va_ *= _config.VaGainCorrection;
+
+  _sa_data.vb_ *= _config.VbGainCorrection;
+
+  _sa_data.vc_ *= _config.VcGainCorrection;
+
+  _sa_data.vd_ *= _config.VdGainCorrection;
+
+  _sa_data.sum_ = _sa_data.va_ + _sa_data.vb_ + _sa_data.vc_ + _sa_data.vd_;
+  
+  _sa_data.q_ = 
+    _config.Kx 
+        * (((_sa_data.va_ + _sa_data.vc_) - (_sa_data.vb_ + _sa_data.vd_)) / _sa_data.sum_) 
+            - _config.Qoffset_local;
+  
+  /* 
+    the algorithme is given by: (Cf Joel Chavanne Feb 2002)
+	  X = -0.0592 + 11.469 * atanh(1.3658 * Qh)
+	  In the present case, the offset -0.0592 is not applied
+	  because we suppose it is already included in the offset.
+	  which has been determided experimentally.
+	  However, we add the -0.0592 to X to calculate the Z with the
+	  following formula: Z = 14.37 * (1+0.001452 * X * X).
+	*/
+			 
+  // Qh = ((a - c) / (a + c) + (d - b) / (d + b))/2;
+  // Rv = ((a - d) / (a + d) + (b - c) / (b + c))/2;
+			   
+  // Xb  = 11.469 * atanh(1.3658*Qh);
+  // Xb2 = Xb - 0.0592;
+  // Zb  = 14.37 * (1+0.001452*(Xb2)*(Xb2)) * Rv;
+  
+  double Qh   = ((_sa_data.va_ - _sa_data.vc_) / (_sa_data.va_ + _sa_data.vc_) + 
+                 (_sa_data.vd_ - _sa_data.vb_) / (_sa_data.vd_ + _sa_data.vb_)) / 2.0;
+
+  double Rv   = ((_sa_data.va_ - _sa_data.vd_) / (_sa_data.va_ + _sa_data.vd_) +
+                 (_sa_data.vb_ - _sa_data.vc_) / (_sa_data.vb_ + _sa_data.vc_)) / 2.0;
+  
+  _sa_data.x_ = 11.469 * atanh(1.3658 * Qh);
+  
+  double Xb2  = _sa_data.x_ - 0.0592;
+
+  _sa_data.z_ = 14.37 * (1 + 0.001452 * (Xb2)*(Xb2)) * Rv; 
+}
+
+} // namespace bpm
diff --git a/src/DataProcessing.h b/src/DataProcessing.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c9c2d0de831cceffd8f546d661aab648184cfe7
--- /dev/null
+++ b/src/DataProcessing.h
@@ -0,0 +1,119 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _DATA_PROC_H_
+#define _DATA_PROC_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "BPMData.h"
+#include "BPMConfig.h"
+
+namespace bpm
+{
+
+// ============================================================================
+//! DataProcessing abstraction class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class DataProcessing
+{
+public:
+  /**
+   * BPM DD data processing 
+   */
+  static void compute_pos (DDData & dd_data,
+                           const DDRawBuffer & dd_raw_data,
+                           size_t actual_num_samples,
+                           const BPMConfig & bpm_config);
+                                    
+  /**
+   * BPM SA data processing
+   */                              
+  static void compute_pos (SAData & _sa_data, const BPMConfig & _config);
+                                    
+private:
+
+  /**
+   * BPM DD data processing for block electrodes at 45°  
+   */
+  static void compute_pos_block_45 (DDData & dd_data,
+                                    const DDRawBuffer & dd_raw_data,
+                                    size_t actual_num_samples,
+                                    const BPMConfig & bpm_config);
+                                    
+  /**
+   * BPM SA data processing for block electrodes at 45° 
+   */                              
+  static void compute_pos_block_45 (SAData & _sa_data,
+                                    const BPMConfig & _config);
+
+  /**
+   * BPM DD data processing for block electrodes at 90° 
+   */
+  static void compute_pos_block_90 (DDData & dd_data,
+                                    const DDRawBuffer & dd_raw_data,
+                                    size_t actual_num_samples,
+                                    const BPMConfig & bpm_config);
+                                                                   
+  /**
+   * BPM SA data processing for block electrodes at 90° 
+   */                              
+  static void compute_pos_block_90 (SAData & _sa_data,
+                                    const BPMConfig & _config);
+  /**
+   * BPM DD data processing for the ESRF SR algorithm
+   */                            
+  static void compute_pos_esrf_sr (DDData & _dd_data,
+                                   const DDRawBuffer & _dd_raw_buffer, 
+                                   size_t actual_num_samples,
+                                   const BPMConfig & _config);
+                                   
+  /**
+   * BPM SA data processing for the ESRF SR algorithm
+   */                            
+  static void compute_pos_esrf_sr (SAData & _sa_data,
+                                   const BPMConfig & _config);
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  DataProcessing (void);
+  DataProcessing (const DataProcessing &);
+  virtual ~DataProcessing (void);
+  DataProcessing & operator= (const DataProcessing &);
+};
+
+} // namespace bpm
+
+#endif  // _DATA_PROC_H_
diff --git a/src/Doxyfile b/src/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..843d8a00dbbbbe20de29540ca1833025d65d3f5d
--- /dev/null
+++ b/src/Doxyfile
@@ -0,0 +1,831 @@
+# Doxyfile 1.2.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Libera BPM Device Server"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =	I:\dev\libera-0.90-4\device\src/..\doc\doc_html
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, 
+# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, 
+# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
+
+OUTPUT_LANGUAGE        = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these class will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = 
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a class diagram (in Html and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS         = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower case letters. If set to YES upper case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments  will behave just like the Qt-style comments (thus requiring an 
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consist of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = 
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  =	I:\dev\libera-0.90-4\device\src
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+FILE_PATTERNS          = *.h *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse.
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = 
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = /segfs/tango/templates/pogo/html/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = /segfs/tango/templates/pogo/html/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript and frames is required (for instance Netscape 4.0+ 
+# or Internet explorer 4.0+).
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 200
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = 
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = 
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = 
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = 
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermedate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
+# The CGI_NAME tag should be the name of the CGI script that 
+# starts the search engine (doxysearch) with the correct parameters. 
+# A script with this name will be generated by doxygen.
+
+CGI_NAME               = 
+
+# The CGI_URL tag should be the absolute URL to the directory where the 
+# cgi binaries are located. See the documentation of your http daemon for 
+# details.
+
+CGI_URL                = 
+
+# The DOC_URL tag should be the absolute URL to the directory where the 
+# documentation is located. If left blank the absolute path to the 
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL                = 
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the 
+# documentation is located. If left blank the directory on the local machine 
+# will be used.
+
+DOC_ABSPATH            = 
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
+# is installed.
+
+BIN_ABSPATH            = 
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
+# documentation generated for other projects. This allows doxysearch to search 
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS          = 
diff --git a/src/DynamicAttr.cpp b/src/DynamicAttr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4dcf99ccadf6fb7f77f8d5a61a4903882d9a9991
--- /dev/null
+++ b/src/DynamicAttr.cpp
@@ -0,0 +1,172 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#include "BPM.h"
+#include "DynamicAttr.h"
+
+#if !defined (INLINE_IMPL)
+# include "DynamicAttr.i"
+#endif
+
+namespace Libera_ns
+{
+
+//=============================================================================
+// Base class for any DynamicAttritute
+//=============================================================================
+//- the BPM
+bpm::BPM * DynamicAttritute::bpm = 0;
+//- the BPM DD data (data on demand)
+bpm::DDData * DynamicAttritute::dd_data = 0;
+//- the BPM ADC data (adc values)
+bpm::ADCData * DynamicAttritute::adc_data = 0;
+//- the BPM SA data (slow acquisition)
+bpm::SAData * DynamicAttritute::sa_data = 0;
+//- the BPM PM data (post mortem)
+bpm::DDData * DynamicAttritute::pm_data = 0;
+                                        
+//=============================================================================
+// DynamicAttritute::DynamicAttritute
+//=============================================================================
+DynamicAttritute::DynamicAttritute ()
+{
+  //- noop
+}
+
+//=============================================================================
+// DynamicAttritute::DynamicAttritute
+//=============================================================================
+DynamicAttritute::~DynamicAttritute ()
+{
+  //- noop
+}
+
+//=============================================================================
+// PosAlgorithmIdAttr::PosAlgorithmIdAttr
+//=============================================================================
+PosAlgorithmIdAttr::PosAlgorithmIdAttr (const std::string& _name,
+                                        Tango::DeviceImpl * _device)
+  : DynamicAttritute (),
+    Tango::Attr (_name.c_str(), Tango::DEV_USHORT, Tango::READ_WRITE),
+    Tango::LogAdapter (_device),
+    pos_algorithm_id_ (bpm::BPMConfig::kINVALID_POS_ALGO_ID)
+{
+  Tango::UserDefaultAttrProp  prop;
+  prop.set_label("Pos.Comp.Algorithm");
+  prop.set_unit(" a.u.");
+  prop.set_format("%2d");
+  prop.set_description("Pos. Computation Algorithm (0:STD-ALGO, 1:ESRF-SR");
+  this->set_disp_level(Tango::EXPERT);
+  this->set_default_properties(prop);
+}
+                
+//=============================================================================
+// PosAlgorithmIdAttr::~PosAlgorithmIdAttr
+//=============================================================================
+PosAlgorithmIdAttr::~PosAlgorithmIdAttr ()
+{
+  //- noop
+}
+    
+//=============================================================================
+// PosAlgorithmIdAttr::read
+//=============================================================================
+void PosAlgorithmIdAttr::read (Tango::DeviceImpl* d, Tango::Attribute &a)
+{
+  // DEBUG_STREAM << "PosAlgorithmIdAttr::read (Tango::DeviceImpl* d, Tango::Attribute &a) entering... "<< endl;
+  this->pos_algorithm_id_ =
+    static_cast<Tango::DevUShort>(DynamicAttritute::bpm_hw()->configuration().get_pos_algorithm());
+  
+  a.set_value(&this->pos_algorithm_id_);
+}
+
+//=============================================================================
+// PosAlgorithmIdAttr::write
+//=============================================================================
+void PosAlgorithmIdAttr::write (Tango::DeviceImpl* d, Tango::WAttribute &wa)
+{
+  // DEBUG_STREAM << "PosAlgorithmIdAttr::write(Tango::DeviceImpl* d, Tango::WAttribute &wa) entering... "<< endl;
+
+  Tango::DevUShort tdus;
+  wa.get_write_value(tdus);
+
+  int id = static_cast<int>(tdus);
+  
+  if (id < bpm::BPMConfig::kSTD_POS_ALGO || id >= bpm::BPMConfig::kINVALID_POS_ALGO_ID)
+    Tango::Except::throw_exception(_CPTC("WRONG_PARAMETER"),
+                                   _CPTC("invalid pos. comp. algorithm specify"),
+                                   _CPTC("PosAlgorithmIdAttr::write"));
+                                   
+  bpm::BPMConfig cfg = DynamicAttritute::bpm_hw()->configuration();
+  cfg.set_pos_algorithm(id);
+  DynamicAttritute::bpm_hw()->reconfigure(cfg);
+}
+
+//=============================================================================
+// PosAlgorithmIdAttr::is_allowed
+//=============================================================================
+bool PosAlgorithmIdAttr::is_allowed (Tango::DeviceImpl* d, Tango::AttReqType &rt)
+{
+  Tango::DevState s = d->get_state();
+  return s != Tango::UNKNOWN && s != Tango::FAULT;
+}
+
+// //=============================================================================
+// // BMPSpectrum::BMPSpectrum
+// //=============================================================================
+// BMPSpectrum::BMPSpectrum (const std::string& _name,
+//                           Tango::DeviceImpl * TANG)
+//   : DynamicAttritute (),
+//     Tango::Attr (ATTR_NAME, TANGO_TYPE, TANGO_RW),
+//     Tango::LogAdapter (TANGO_DEVICE)
+// {
+//   Tango::UserDefaultAttrProp  prop;
+//   prop.set_label(DISP_LABEL);
+//   prop.set_unit(std::sting(" ") + DISP_UNIT);
+//   prop.set_format(DISP_FORMAT);
+//   prop.set_description(DESC);
+//   this->set_disp_level(DISP_LEVEL);
+//   this->set_default_properties(prop);
+// }
+//                 
+// //=============================================================================
+// // BMPSpectrum::~BMPSpectrum
+// //=============================================================================
+// BMPSpectrum::~BMPSpectrum ()
+// {
+//   //- noop
+// }
+//     
+
+} // namespace
+
diff --git a/src/DynamicAttr.h b/src/DynamicAttr.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cd497885e861af3fa3c25e8821cc2d5d3b8f7f2
--- /dev/null
+++ b/src/DynamicAttr.h
@@ -0,0 +1,147 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _DYNAMIC_ATTR_H_
+#define _DYNAMIC_ATTR_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+
+//=============================================================================
+// Forward declarations
+//=============================================================================
+namespace bpm
+{
+  class BPM;
+  class DDData;
+  class SAData;
+  class ADCData;
+}
+
+namespace Libera_ns
+{
+
+//=============================================================================
+// Base class for any DynnamicAttritute
+//=============================================================================
+class DynamicAttritute
+{
+  friend class Libera;
+  
+protected:
+  //- the BPM
+  static bpm::BPM * bpm;
+  //- the BPM DD data (data on demand)
+  static bpm::DDData * dd_data;
+  //- the BPM ADC data (adc values)
+  static bpm::ADCData * adc_data;
+  //- the BPM SA data (slow acquisition)
+  static bpm::SAData * sa_data;
+  //- the BPM PM data (post mortem)
+  static bpm::DDData * pm_data;
+
+  //- the BPM
+  inline static bpm::BPM * bpm_hw ()
+    throw (Tango::DevFailed)
+  {
+    if (! DynamicAttritute::bpm)
+    {
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("no BPM instance registered"),
+                                     _CPTC("DynamicAttritute::bpm_hw"));
+    }
+    return DynamicAttritute::bpm;
+  }
+  
+  DynamicAttritute();
+  DynamicAttritute(const DynamicAttritute&);
+  const DynamicAttritute& operator= (const DynamicAttritute&);
+  ~DynamicAttritute();
+};
+
+//=============================================================================
+// PosAlgorithmIdAttr: read only scalar of type bpm::FPDataType
+//=============================================================================
+class PosAlgorithmIdAttr : public DynamicAttritute,
+                           public Tango::Attr,
+                           public Tango::LogAdapter
+{
+public:
+  //- ctor
+  PosAlgorithmIdAttr (const std::string& name, Tango::DeviceImpl * device);
+                
+  //- dtor
+  virtual ~PosAlgorithmIdAttr ();
+
+  //- read
+  virtual void read (Tango::DeviceImpl* d, Tango::Attribute &ra);
+  
+  //- write
+  virtual void write (Tango::DeviceImpl* d, Tango::WAttribute &wa);
+
+  //- is_allowed
+  virtual bool is_allowed (Tango::DeviceImpl* d, Tango::AttReqType &rt);
+  
+private:
+  //- the currently selected pos comp algorithm 
+  Tango::DevUShort pos_algorithm_id_;
+};
+
+// //=============================================================================
+// // BMPSpectrum: read only spectrum of type bpm::FPDataType
+// //=============================================================================
+// class BMPSpectrum : public DynamicAttritute,
+//                     public Tango::Attr,
+//                     public Tango::LogAdapter
+// {
+// public:
+//   //- ctor
+//   BMPSpectrum (const std::string& name, Tango::DeviceImpl * device);
+//   //- dtor
+//   virtual ~BMPSpectrum ();
+//   //- read
+//   virtual void read (Tango::DeviceImpl* d, Tango::Attribute &ra);
+//   //- write
+//   virtual void write (Tango::DeviceImpl* d, Tango::WAttribute &wa);
+//   //- is_allowed
+//   virtual bool is_allowed (Tango::DeviceImpl* d, Tango::AttReqType &rt);
+// };
+
+} // namespace
+
+//=============================================================================
+// INLINED CODE
+//=============================================================================
+#if defined (INLINE_IMPL)
+# include "DynamicAttr.i"
+#endif
+
+#endif 
diff --git a/src/DynamicAttr.i b/src/DynamicAttr.i
new file mode 100644
index 0000000000000000000000000000000000000000..42d74b951e86ee6ff730370cc31e6f4e89f19b31
--- /dev/null
+++ b/src/DynamicAttr.i
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// // ============================================================================
+// // DynamicAttr::xxxx
+// // ============================================================================
+// INLINE_IMPL xxxxx DynamicAttr::xxxx (xxxx) const
+// {
+//   xxxxxxxxx;
+// }
+
+
+} //- namespace
diff --git a/src/DynamicAttrHelper.cpp b/src/DynamicAttrHelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd7606d10eec1ef349c46a70df272cf2a91f98e1
--- /dev/null
+++ b/src/DynamicAttrHelper.cpp
@@ -0,0 +1,262 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Julien Malik, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "DynamicAttr.h"
+#include "DynamicAttrHelper.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "DynamicAttrHelper.i"
+#endif
+
+namespace bpm
+{
+
+// ============================================================================
+// DynamicAttrHelper::ctor
+// ============================================================================
+DynamicAttrHelper::DynamicAttrHelper ()
+	: host_device_(0)
+{
+  //- noop
+}
+
+// ============================================================================
+// DynamicAttrHelper::dtor
+// ============================================================================
+DynamicAttrHelper::~DynamicAttrHelper ()
+{
+  this->remove_all();
+}
+
+// ============================================================================
+// DynamicAttrHelper::dtor
+// ============================================================================
+void DynamicAttrHelper::host_device (Tango::DeviceImpl * _host_device)
+{
+  this->host_device_ = _host_device;
+}
+  
+// ============================================================================
+// DynamicAttrHelper::add 
+// ============================================================================
+void DynamicAttrHelper::add (Tango::Attr* _attr)
+	throw (Tango::DevFailed)
+{
+	if (! this->host_device_)
+	{
+	  THROW_DEVFAILED("PROGRAMMING_ERROR",
+	                  "no associated Tango device (host device not set)",
+                    "DynamicAttrHelper::add");
+  }
+                   
+  //- check attribute does not already exist
+  DynAttrIt it = this->rep_.find(_attr->get_name());
+  if (it != this->rep_.end())
+  {
+	  THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+	                  "attribute already exists",
+                    "DynamicAttrHelper::add");
+  }
+
+  //- add it to the device
+  try
+  {
+    this->host_device_->add_attribute( _attr );
+  }
+  catch(Tango::DevFailed& ex)
+  {
+	  RETHROW_DEVFAILED(ex,
+                      "INTERNAL_ERROR",
+	                    "attribute could not be added to the device",
+                      "DynamicAttrHelper::add");
+  }
+  catch(...)
+  {
+	  THROW_DEVFAILED("UNKNOWN_ERROR",
+	                  "unknown caught while trying to add attribute to the device",
+                    "DynamicAttrHelper::add");
+  }
+  
+  //- ok, everything went fine :
+  //- insert the attribute into the list
+  std::pair<DynAttrIt, bool> insertion_result;
+  insertion_result = this->rep_.insert( DynAttrEntry(_attr->get_name(), _attr) );
+
+  if (insertion_result.second == false)
+  {
+	  THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+	                  "attribute could not be inserted into the attribute repostory",
+                    "DynamicAttrHelper::add");
+  }
+}
+
+// ============================================================================
+// DynamicAttrHelper::remove 
+// ============================================================================
+void DynamicAttrHelper::remove (const std::string& _name)
+	throw (Tango::DevFailed)
+{
+	if (! this->host_device_)
+	{
+	  THROW_DEVFAILED("PROGRAMMING_ERROR",
+	                  "no associated Tango device (host device not set)",
+                    "DynamicAttrHelper::remove");
+  }
+  
+  //- check if attribute exists
+  DynAttrIt it = this->rep_.find(_name);
+  if (it == this->rep_.end())
+  {
+	  THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+	                  "attribute does not exist",
+                    "DynamicAttrHelper::remove");
+  }
+
+  //- remove it from the device
+  try
+  {
+    this->host_device_->remove_attribute( (*it).second, true );
+  }
+  catch(Tango::DevFailed& ex)
+  {
+	  RETHROW_DEVFAILED(ex,
+                      "INTERNAL_ERROR",
+	                    "attribute could not be removed from the device",
+                      "DynamicAttrHelper::remove");
+  }
+  catch(...)
+  {
+	  THROW_DEVFAILED("UNKNOWN_ERROR",
+	                  "could not remove attribute from the device",
+                    "DynamicAttrHelper::remove");
+  }
+
+  //- remove from db
+  Tango::DeviceData argin;
+  std::vector<std::string> v(2);
+  v[0] = this->host_device_->name();
+  v[1] = _name;
+  argin << v;
+
+  Tango::Database * db =
+      this->host_device_->get_db_device()->get_dbase();
+
+  try
+  {
+    Tango::DeviceData argout =
+        db->command_inout("DbDeleteDeviceAttribute", argin);
+  }
+  catch(Tango::DevFailed& ex)
+  {
+	  RETHROW_DEVFAILED(ex,
+                      "INTERNAL_ERROR",
+	                    "unable to delete attribute from the database",
+                      "DynamicAttrHelper::remove");
+  }
+  catch(...)
+  {
+	  THROW_DEVFAILED("UNKNOWN_ERROR",
+	                  "unable to delete attribute from the database",
+                    "DynamicAttrHelper::remove");
+  }
+
+  //- remove from the internal map
+  this->rep_.erase(it);
+}
+
+// ============================================================================
+// DynamicAttrHelper::remove_all 
+// ============================================================================
+void DynamicAttrHelper::remove_all ()
+	throw (Tango::DevFailed)
+{
+	if (! this->host_device_ || this->rep_.empty())
+		return;
+  
+  DynAttrIt it;
+
+  Tango::DeviceData argin;
+  std::vector<std::string> v(2);
+  v[0] = this->host_device_->name();
+
+  for (it  = this->rep_.begin(); it != this->rep_.end(); ++it)
+  {
+
+    //- remove it from the device
+    try
+    {
+      this->host_device_->remove_attribute( (*it).second, true );
+    }
+    catch(Tango::DevFailed& ex)
+    {
+	    RETHROW_DEVFAILED(ex,
+                        "INTERNAL_ERROR",
+	                      "attribute could not be removed from the device",
+                        "DynamicAttrHelper::remove_all");
+    }
+    catch(...)
+    {
+	    THROW_DEVFAILED("UNKNOWN_ERROR",
+	                    "could not remove attribute from the device",
+                      "DynamicAttrHelper::remove_all");
+    }
+
+    //- remove from db
+    v[1] = (*it).first;
+    argin << v;
+    Tango::Database * db = this->host_device_->get_db_device()->get_dbase();
+
+    try
+    {
+      Tango::DeviceData argout = db->command_inout("DbDeleteDeviceAttribute", argin);
+    }
+    catch(Tango::DevFailed& ex)
+    {
+	    RETHROW_DEVFAILED(ex,
+                        "INTERNAL_ERROR",
+	                      "unable to delete attribute from the database",
+                        "DynamicAttrHelper::remove_all");
+    }
+    catch(...)
+    {
+	    THROW_DEVFAILED("UNKNOWN_ERROR",
+	                    "unable to delete attribute from the database",
+                      "DynamicAttrHelper::remove_all");
+    }
+  }
+
+  //- then clear the map
+  this->rep_.clear();
+}
+
+} // namespace
+
diff --git a/src/DynamicAttrHelper.h b/src/DynamicAttrHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..5792f8dd9c0794cc6ab536715a2ed8ced591b01f
--- /dev/null
+++ b/src/DynamicAttrHelper.h
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Julien Malik, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _DYNAMIC_ATTR_HELPER_H_
+#define _DYNAMIC_ATTR_HELPER_H_
+
+#include "CommonHeader.h"
+
+namespace bpm
+{
+
+typedef std::map <std::string, Tango::Attr*> DynAttrRepository;
+typedef DynAttrRepository::value_type        DynAttrEntry;
+typedef DynAttrRepository::iterator          DynAttrIt;
+typedef DynAttrRepository::const_iterator    DynAttrCIt;
+
+// ============================================================================
+//
+// class: DynamicAttrHelper
+//
+// ============================================================================
+class DynamicAttrHelper
+{
+public:
+  /**
+   * Constructor. 
+   * @param  _host_device the device handled by the instance
+   */
+  DynamicAttrHelper();
+  
+  /**
+   * Destructor
+   */
+  ~DynamicAttrHelper();
+
+  /**
+   * host_device
+   * @param attr a Tango::Attr* to be registered
+   */
+  void host_device (Tango::DeviceImpl * host_device);
+    
+  /**
+   * add
+   * @param attr a Tango::Attr* to be registered
+   */
+  void add (Tango::Attr * attr)
+		throw (Tango::DevFailed);
+
+  /**
+   * remove
+   * @param name the attribute name
+   */
+  void remove (const std::string& name)
+		throw (Tango::DevFailed);
+
+  /**
+   * remove_all
+   *
+   * Removes all the dynamic attributes registered
+   */
+  void remove_all ()
+		throw (Tango::DevFailed);
+
+  /**
+   * get (Tango::Attr version)
+   * @param _name the attribute name
+   * @param _a a reference to a Tango::Attr* where the pointer to the desired attribute is stored
+   */
+  Tango::Attr* get (const std::string& _name)
+		throw (Tango::DevFailed)
+  {
+    DynAttrIt it = this->rep_.find(_name);
+	  if (it == this->rep_.end())
+	  {
+	    THROW_DEVFAILED("OPERATION_NOT_ALLOWED",
+	                    "Attribute does not exist",
+                      "DynamicAttrHelper::get_attribute");
+	  }
+	  return (*it).second;
+  };
+
+  DynAttrCIt begin() const;
+  DynAttrIt  begin();
+  
+  DynAttrCIt end() const;
+  DynAttrIt  end();
+  
+  size_t size() const;
+  bool empty() const;
+
+private:
+  Tango::DeviceImpl * host_device_;
+  DynAttrRepository   rep_;
+
+  DynamicAttrHelper (const DynamicAttrHelper&);
+  DynamicAttrHelper& operator= (const DynamicAttrHelper&);
+};
+
+} // namespace
+
+//=============================================================================
+// INLINED CODE
+//=============================================================================
+#if defined (__INLINE_IMPL__)
+# include "DynamicAttrHelper.i"
+#endif
+
+#endif 
diff --git a/src/DynamicAttrHelper.i b/src/DynamicAttrHelper.i
new file mode 100644
index 0000000000000000000000000000000000000000..f3904dec1ddd4040bb85f025ff3a1e28f777c9b5
--- /dev/null
+++ b/src/DynamicAttrHelper.i
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2007-2008 Julien Malik, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// DynamicAttrHelper::begin
+// ============================================================================
+INLINE_IMPL DynAttrCIt DynamicAttrHelper::begin() const
+{
+  return this->rep_.begin();
+}
+
+// ============================================================================
+// DynamicAttrHelper::begin
+// ============================================================================
+INLINE_IMPL DynAttrIt DynamicAttrHelper::begin()
+{
+  return this->rep_.begin();
+}
+
+// ============================================================================
+// DynamicAttrHelper::end
+// ============================================================================
+INLINE_IMPL DynAttrCIt DynamicAttrHelper::end() const
+{
+  return this->rep_.end();
+}
+
+// ============================================================================
+// DynamicAttrHelper::end
+// ============================================================================
+INLINE_IMPL DynAttrIt DynamicAttrHelper::end()
+{
+  return this->rep_.end();
+}
+
+// ============================================================================
+// DynamicAttrHelper::size
+// ============================================================================
+INLINE_IMPL size_t DynamicAttrHelper::size() const
+{
+  return this->rep_.size();
+}
+
+// ============================================================================
+// DynamicAttrHelper::empty
+// ============================================================================
+INLINE_IMPL bool DynamicAttrHelper::empty() const
+{
+  return this->rep_.empty();
+}
+
+} //- namespace
diff --git a/src/GenericContainer.h b/src/GenericContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..35288f4e20db5bfc9feab96a3e89d4aa1040c5ea
--- /dev/null
+++ b/src/GenericContainer.h
@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _GENERIC_CONTAINER_H_
+#define _GENERIC_CONTAINER_H_
+
+#include "CommonHeader.h"
+
+namespace bpm 
+{
+
+// ============================================================================
+//	class: Container
+// ============================================================================
+class Container
+{
+public:
+  Container ()
+  {
+    //- noop
+  };
+
+  virtual ~Container () 
+  {
+    //- noop
+  };
+};
+
+// ============================================================================
+//	template class: GenericContainer - class T must have a copy ctor
+// ============================================================================
+template <typename T> 
+class GenericContainer : public Container
+{
+public:
+
+  //- ctor
+  GenericContainer (T* _msg_data, bool _ownership = true) 
+    : ptr_(_msg_data), own_(_ownership) 
+  {
+    //- noop
+  }
+
+  //- ctor
+  GenericContainer (const T& _data) 
+    : ptr_(0), own_(true)
+  {
+    try
+    {
+      this->ptr_ = new T(_data);
+      if (this->ptr_ == 0)
+        throw std::bad_alloc();
+    }
+    catch (const std::bad_alloc&)
+    {
+      this->ptr_ = 0;
+      Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                      _CPTC("memory allocation failed"),
+                                      _CPTC("GenericContainer:GenericContainer"));
+    }
+  }
+
+  //- dtor
+  virtual ~GenericContainer ()
+  {
+    if (own_)
+      delete this->ptr_;
+  }
+
+  //- returns content and optionaly transfers ownership to caller
+  T * content (bool transfer_ownership)
+  {
+    T * tmp = this->ptr_;
+    if (transfer_ownership)
+    {
+      this->own_ = false;
+      this->ptr_ = 0;
+    }
+    return tmp;
+  }
+
+  //- returns content
+  T & content ()
+  {
+    return  *(this->ptr_);
+  }
+  
+private:
+  //- actual container content
+  T * ptr_;
+  bool own_;
+};
+
+
+// ============================================================================
+//	template function
+// ============================================================================
+template <typename T> T * extract_data (Container * _c, 
+                                        bool _transfer_ownership = true)
+    throw (Tango::DevFailed)
+{
+  GenericContainer<T> * gc = 0;
+
+  try
+  {
+    gc = dynamic_cast<GenericContainer<T>*>(_c);
+    if (gc == 0)
+  	{
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from Container [unexpected content]"),
+                                      _CPTC("dettach_data"));
+  	}
+  }
+  catch (const std::bad_cast&)
+  {
+    Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                    _CPTC("could not extract data from Container [unexpected content]"),
+                                    _CPTC("dettach_data"));
+  }
+
+  return gc->content(_transfer_ownership);
+}
+
+} // namespace bpm
+
+#endif // _GENERIC_CONTAINER_H_
+
+
+
diff --git a/src/Implementation.h b/src/Implementation.h
new file mode 100644
index 0000000000000000000000000000000000000000..af050779e83da00c4778069083d4f4eda7c0a58c
--- /dev/null
+++ b/src/Implementation.h
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_THREADING_IMPL_H_
+#define _BPM_THREADING_IMPL_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/impl/PosixThreadingImpl.h"
+
+// ============================================================================
+// MISC DEFINEs
+// ============================================================================
+#define kINFINITE_WAIT  0
+#define DUMP_THREAD_UID std::hex << yat::ThreadingUtilities::self() << std::dec 
+
+#endif //- _BPM_THREADING_IMPL_H_
diff --git a/src/Inline.h b/src/Inline.h
new file mode 100644
index 0000000000000000000000000000000000000000..21abc5f9c54e07d44d44f94e6214ece76d88ef27
--- /dev/null
+++ b/src/Inline.h
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _INLINE_H_
+#define _INLINE_H_
+
+//-----------------------------------------------------------------------------
+// DEBUG
+//-----------------------------------------------------------------------------
+#if !defined(_DEBUG)
+# define __INLINE_IMPL__
+#endif
+
+//-----------------------------------------------------------------------------
+// INLINE
+//-----------------------------------------------------------------------------
+#if defined(__INLINE_IMPL__)
+# define INLINE_IMPL inline
+#else
+# define INLINE_IMPL
+#endif
+
+#endif // __INLINE_H_
diff --git a/src/InnerAppender.cpp b/src/InnerAppender.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcd1ef585346caefe0af7c90e9695556e6774146
--- /dev/null
+++ b/src/InnerAppender.cpp
@@ -0,0 +1,138 @@
+// ============================================================================
+//
+// = CONTEXT
+//   FOFBManager: fast orbit feedback manager
+//
+// = File
+//   InnerAppender.h
+//
+// = AUTHOR
+//   Julien Malik - SOLEIL
+//
+// ============================================================================
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <iomanip>
+#include <time.h>
+#include <InnerAppender.h>
+
+// ============================================================================
+// CONSTANTs
+// ============================================================================
+#define kLOG_NUMBER_LIMIT 1024
+
+namespace Libera_ns
+{
+
+// ============================================================================
+// InnerAppender::InnerAppender
+// ============================================================================
+InnerAppender::InnerAppender (const std::string& _name, bool _open_connection)
+  : log4tango::Appender(_name)
+{
+  if ( _open_connection )
+    this->reopen();
+}
+
+// ============================================================================
+// InnerAppender::~InnerAppender
+// ============================================================================
+InnerAppender::~InnerAppender ()
+{
+  this->close();
+}
+
+// ============================================================================
+// InnerAppender::requires_layout
+// ============================================================================
+bool InnerAppender::requires_layout () const
+{
+  return false; 
+}
+
+// ============================================================================
+// InnerAppender::set_layout
+// ============================================================================
+void InnerAppender::set_layout (log4tango::Layout*)
+{
+  // no-op
+}
+
+// ============================================================================
+// InnerAppender::is_valid
+// ============================================================================
+bool InnerAppender::is_valid (void) const
+{
+  return true;
+}
+
+// ============================================================================
+// InnerAppender::
+// ============================================================================
+int InnerAppender::_append (const log4tango::LoggingEvent& event)
+{
+  //------------------------------------------------------------
+  //- DO NOT LOG FROM THIS METHOD !!!
+  //------------------------------------------------------------
+  static size_t max_time_str_len = 32;
+  
+  try
+  {
+    //- reformat LoggingEvent
+    time_t raw_time;
+    ::time(&raw_time);
+    char c_date_string[max_time_str_len];
+    struct tm * time_info = ::localtime(&raw_time);
+    ::strftime (c_date_string, max_time_str_len,"%d:%m:%y@%H:%M:%S", time_info);
+  
+    std::ostringstream oss;
+    oss << c_date_string
+        << " ["
+        << log4tango::Level::get_name(event.level)
+        << "] "
+        << event.message;
+        
+    //- push the log into the repository
+    {
+      bpm::MutexLock scoped_lock(m_mutex);
+      this->m_logs_list.push_back(oss.str());
+      if (this->m_logs_list.size() > kLOG_NUMBER_LIMIT)
+        this->m_logs_list.pop_front();
+    }
+  }
+  catch (...) 
+  {
+    close();
+    return -1;
+  }
+  return 0;
+} 
+
+// ============================================================================
+// InnerAppender::reopen
+// ============================================================================
+bool InnerAppender::reopen (void) 
+{
+  return true;
+}
+
+// ============================================================================
+// InnerAppender::close
+// ============================================================================
+void InnerAppender::close (void)
+{
+  //- noop
+}
+  
+// ============================================================================
+// InnerAppender::get_logs
+// ============================================================================
+void InnerAppender::get_logs (InnerAppender::LogList& log_list_)
+{
+  bpm::MutexLock scoped_lock(m_mutex);
+  log_list_ = this->m_logs_list;
+}
+
+} // namespace Libera_ns
diff --git a/src/InnerAppender.h b/src/InnerAppender.h
new file mode 100644
index 0000000000000000000000000000000000000000..085daa5bad45c49fd54a2a33e0add72bd48f657b
--- /dev/null
+++ b/src/InnerAppender.h
@@ -0,0 +1,92 @@
+// ============================================================================
+//
+// = CONTEXT
+//   FOFBManager: fast orbit feedback manager
+//
+// = File
+//   InnerAppender.h
+//
+// = AUTHOR
+//   Julien Malik - SOLEIL
+//
+// ============================================================================
+
+#ifndef _INNER_APPENDER_H_
+#define _INNER_APPENDER_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <deque>
+#include <threading/Mutex.h>
+#include <tango.h>
+
+namespace Libera_ns
+{
+
+// ============================================================================
+// class: InnerAppender
+// ============================================================================
+class InnerAppender : public log4tango::Appender
+{
+public:
+  
+  //- the LogList type
+  typedef std::deque<std::string> LogList;
+
+public:
+  /**
+    *
+    **/
+  InnerAppender (const std::string& name, bool open_connection = true);
+  
+  /**
+    *
+    **/
+  virtual ~InnerAppender ();
+
+  /**
+    *
+    **/
+  virtual bool requires_layout () const;
+      
+  /**
+    *
+    **/
+  virtual void set_layout (log4tango::Layout* layout);
+
+  /**
+    *
+    **/
+  virtual void close ();
+                  
+  /**
+    *
+    **/
+  virtual bool reopen ();
+
+  /**
+    *
+    **/
+  virtual bool is_valid () const;
+  
+  /**
+    *
+    **/
+  void get_logs (InnerAppender::LogList& log_list);
+
+protected:
+
+  /**
+    *
+    **/
+  virtual int _append (const log4tango::LoggingEvent& event); 
+
+private:
+  bpm::Mutex m_mutex;
+  LogList m_logs_list;
+};
+
+} // namespace Libera_ns
+
+#endif // _INNER_APPENDER_H_
diff --git a/src/Libera.cpp b/src/Libera.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a520b36cd12241a3abd2629294111508b9c0f0f1
--- /dev/null
+++ b/src/Libera.cpp
@@ -0,0 +1,4143 @@
+static const char *RcsId = "$Header:  $";
+//+=============================================================================
+//
+// file :         Libera.cpp
+//
+// description :  C++ source for the Libera and its commands. 
+//                The class is derived from Device. It represents the
+//                CORBA servant object which will be accessed from the
+//                network. All commands which can be executed on the
+//                Libera are implemented in this file.
+//
+// project :      TANGO Device Server
+//
+// $Author:  $
+//
+// $Revision:  $
+// 
+// $Log:  $ 
+//
+// copyleft :     European Synchrotron Radiation Facility
+//                BP 220, Grenoble 38043
+//                FRANCE
+//
+//-=============================================================================
+//
+//      This file is generated by POGO
+//  (Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+
+//===================================================================
+//
+//	The following table gives the correspondence
+//	between commands and method name.
+//
+//  Command name                |  Method name
+//	----------------------------------------
+//  State                       |  dev_state()
+//  Status                      |  dev_status()
+//  GetParameters               |  get_parameters()
+//  UnfreezeDDBuffer            |  unfreeze_ddbuffer()
+//  EnableDDBufferFreezing      |  enable_ddbuffer_freezing()
+//  DisableDDBufferFreezing     |  disable_ddbuffer_freezing()
+//  EnableDD                    |  enable_dd()
+//  DisableDD                   |  disable_dd()
+//  EnableSA                    |  enable_sa()
+//  DisableSA                   |  disable_sa()
+//  ResetPMNotification         |  reset_pmnotification()
+//  ResetInterlockNotification  |  reset_interlock_notification()
+//  SetInterlockConfiguration   |  set_interlock_configuration()
+//  EnableADC                   |  enable_adc()
+//  DisableADC                  |  disable_adc()
+//  SetTimeOnNextTrigger        |  set_time_on_next_trigger()
+//  ReadFAData                  |  read_fadata()
+//  WriteFAData                 |  write_fadata()
+//  SaveDSCParameters           |  save_dscparameters()
+//  ReloadSystemProperties      |  reload_system_properties()
+//  SetRefIncoherence           |  set_ref_incoherence()
+//
+//===================================================================
+
+#include <sys/time.h>
+#include <tango.h>
+#include <Libera.h>
+#include <LiberaClass.h>
+#include "Offsets.h"
+#include "DynamicAttrHelper.h"
+
+// ============================================================================
+// CONSTs 
+// ============================================================================
+#define kMAX_DB_RETRY 5
+#define kRFFSRATIO_PROPERTY_NAME "RfSfRatio"
+
+namespace Libera_ns
+{
+
+//- Libera::instance_counter
+int Libera::instance_counter = 0;
+
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::Libera(string &s)
+// 
+// description :  constructor for simulated Libera
+//
+// in : - cl : Pointer to the DeviceClass object
+//      - s : Device name 
+//
+//-----------------------------------------------------------------------------
+Libera::Libera(Tango::DeviceClass * cl, string & s) :Tango::Device_4Impl(cl, s.c_str())
+{
+  init_device();
+}
+Libera::Libera(Tango::DeviceClass * cl, const char *s) :Tango::Device_4Impl(cl, s)
+{
+  init_device();
+}
+Libera::Libera(Tango::DeviceClass * cl, const char *s, const char *d) :Tango::Device_4Impl(cl, s, d)
+{
+  init_device();
+}
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::delete_device()
+// 
+// description :  will be called at device destruction or at init command.
+//
+//-----------------------------------------------------------------------------
+void Libera::delete_device()
+{
+  //- remove dynamic attributes
+  try
+  {
+    dyn_attrs.remove_all();
+  }
+  catch (...) {}
+  
+  
+  //  Delete device's allocated object
+  if (this->dd_data)
+  {
+    this->dd_data->release();
+    this->dd_data = 0;
+  }
+
+  if (this->adc_data)
+  {
+    this->adc_data->release();
+    this->adc_data = 0;
+  }
+  
+  if (this->sa_data)
+  {
+    this->sa_data->release();
+    this->sa_data = 0;
+  }
+  
+  if (this->pm_data)
+  {
+    this->pm_data->release();
+    this->pm_data = 0;
+  }
+
+  DynamicAttritute::bpm = 0;
+
+  if (this->bpm_hw)
+  {
+    delete this->bpm_hw;
+    this->bpm_hw = 0;
+  }
+
+  if (this->m_appender)
+  {
+    this->get_logger()->remove_appender(this->m_appender);
+    this->m_appender = 0;
+  }
+  
+  //- dec instance counter
+  if (Libera::instance_counter)
+    Libera::instance_counter--;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::init_device()
+//
+// description :  will be called at device initialization.
+//
+//-----------------------------------------------------------------------------
+void Libera::init_device()
+{
+  //- instanciate the appender
+  try
+  {
+    this->m_appender = new InnerAppender("SelfAppender");
+    this->get_logger()->add_appender(this->m_appender);
+  }
+  catch( Tango::DevFailed& df )
+  {
+    ERROR_STREAM << df << std::endl;
+    this->set_state(Tango::FAULT);
+    this->set_status( "initialization failed - could not instanciate the InnerAppender");
+    return;
+  }
+  
+  //- no more than one instance of Libera device per Libera device-server!
+  if (Libera::instance_counter)
+  {
+    ERROR_STREAM << "initialization error - can't instanciate more than one Libera device per server" << std::endl;
+    this->set_status("initialization error [can't instanciate more than one Libera device per server]");
+    this->set_state(Tango::FAULT);
+    return;
+  }
+  
+  //- inc instance counter
+  Libera::instance_counter++;
+  
+  //- reset members to their default value
+  //--------------------------------------
+  //- no critical value missing
+  this->critical_properties_missing = false;
+  //- data & data sources
+  this->bpm_hw = 0;
+  this->dd_data = 0;
+  this->dd_enabled = false;
+  this->dd_cache_enabled = false;
+  this->dd_cache_frozen = false;
+  this->adc_data = 0;
+  this->adc_enabled = false;
+  this->sa_data = 0;
+  this->sa_enabled = false;
+  this->pm_data = 0;
+  //- external trigger
+  this->external_trigger_enabled = false;
+  this->external_trigger_delay = 0;
+  //- offset (in num of samples) from the "last trigger" in the Libera turn-by-trun buffer
+  this->dd_buffer_offset = 0;
+  //- post mortem notification
+  this->pm_notified = false;
+  //- interlock notifications
+  this->intl_x_notified = false;
+  this->intl_z_notified = false;
+  this->intl_attn_notified = false;
+  this->intl_adc_pre_filter_notified = false;
+  this->intl_adc_post_filter_notified = false;
+  //- turn-by-trun decimation factor
+  this->dDDecimationFactor = 1;
+  //- auto switching enabled
+  this->auto_switching_enabled = false;
+  //- time settings
+  this->mt = 0;
+  this->st = 0;
+  this->tp = 0;
+  //- ADC source switching
+  this->external_switching_enabled = false;
+  this->switching_delay = 0;
+  //- tune compensation  (mtvcxoff and mtncoshft)
+  this->tune_compensation_enabled = true;
+  this->tune_offset = 0;
+  //- post mortem offset
+  this->pm_offset = 0;
+  //- moving average filter length and delay
+  this->maf_length = 1;
+  this->maf_delay  = 0;
+  this->maf_support = false;
+  //- incoherence values
+  this->incoherence = 0; 
+  this->ref_incoherence = 0;
+  this->max_incoherence = 0;
+  this->max_drift_incoherence = 0;
+  
+  INFO_STREAM << "Libera::Libera() create device " << device_name << endl;
+
+  // Initialise variables to default values
+  //--------------------------------------------
+  
+  //- we may generate some kind of overflow on the TANGO db in case
+  //- we (re)intialize all the BPMs - its a good idea to implement
+  //- a retry mecanism to avoid the problem...
+  size_t retries = kMAX_DB_RETRY;
+  do
+  {
+    try
+    {
+      this->get_device_property();
+      break;
+    }
+    catch(Tango::DevFailed & df)
+    {
+      if (! --retries)
+      {
+        ERROR_STREAM << df << std::endl;      
+        ERROR_STREAM << "BPM initialization failed [get_device_property error]" << std::endl;   
+        this->set_status("BPM initialization failed [get_device_property error]");
+        this->set_state(Tango::FAULT);
+        this->delete_device();
+        return;
+      }
+    }
+    catch(...)
+    {
+      if (! --retries)
+      {
+        ERROR_STREAM << "BPM initialization failed - unknown error" << std::endl;
+        this->set_status("BPM initialization failed [get_device_property error]");
+        this->set_state(Tango::FAULT);
+        this->delete_device();
+        return;
+      }
+    }
+    WARN_STREAM << "failed to obtain device properties from Tango-DB. Retrying..." << std::endl;
+    Thread::sleep(125);
+  }
+  while (true);
+  
+  //- abort initialization if properties missing
+  if (critical_properties_missing)
+  {
+    ERROR_STREAM << "configuration error - unspecified or invalid device property" << std::endl;
+    this->set_status("configuration error [unspecified or invalid device/class property]");
+    this->set_state(Tango::FAULT);
+    return;
+  }
+  
+  //- read the offsets
+  //- here again, we may generate some kind of overflow on the TANGO 
+  //- db in case we (re)intialize all the BPMs - its a good idea to 
+  //- implement a retry mecanism to avoid the problem...
+  BPMOffsets offsets;
+  retries = kMAX_DB_RETRY;
+  do
+  {
+    try
+    {
+      offsets.read_from_tango_db(this->bpm_location, this);
+      break;
+    }
+    catch(Tango::DevFailed & df)
+    {
+      if (! --retries)
+      {
+        ERROR_STREAM << df << std::endl;
+        this->set_status("BPM initialization failed [could not obtain BPMOffsets from database]");
+        this->set_state(Tango::FAULT);
+        this->delete_device();
+        return;
+      }
+    }
+    catch(...)
+    {
+      if (! --retries)
+      {
+        ERROR_STREAM << "BPM initialization failed - unknown error" << std::endl;
+        this->set_status("BPM initialization failed [unknown error]");
+        this->set_state(Tango::FAULT);
+        this->delete_device();
+        return;
+      }
+    }
+    WARN_STREAM << "failed to obtain system properties from Tango-DB. Retrying..." << std::endl;
+    Thread::sleep(125);
+  }
+  while (true);
+  
+  //- try to instanciate the BPM
+  try
+  {
+    this->bpm_hw = new BPM(this);
+    if (this->bpm_hw == 0)
+      throw std::bad_alloc();
+  }
+  catch(const std::bad_alloc&)
+  {
+    ERROR_STREAM << "initialization error - out of memory" << std::endl;
+    this->set_status("initialization error [out of memory]");
+    this->set_state(Tango::FAULT);
+    this->delete_device();
+    return;
+  }
+  catch(...)
+  {
+    ERROR_STREAM << "initialization error - unknown error" << std::endl;
+    this->set_status("initialization error [unknown error]");
+    this->set_state(Tango::FAULT);
+    this->delete_device();
+    return;
+  }
+     
+  try
+  {
+    //- initial configuration
+    BPMConfig config;
+
+    //- should we pass the BBA offsets to the FPGA process?   
+    config.pass_bba_offsets_to_fpga(this->passBBAOffsetsToFPGA);
+    
+# if ! defined(_EMBEDDED_DEVICE_)
+    //- generic server addr and port(required)
+    config.set_ip_config(liberaIpAddr, liberaPort, liberaMulticastIpAddr);
+#endif
+    
+    //- set interlock config
+    config.set_interlock_configuration(this->interlockConfiguration);
+    
+    //- the number of samples to read from DD buffer
+    config.set_dd_raw_buffer_depth(this->defaultDDBufferSize);
+    config.set_max_dd_buffer_depth_for_dec_on(this->maxDDBufferSizeWhenDecimationEnabled);
+
+    //- the number of samples to read from ADC buffer
+    config.set_adc_raw_buffer_depth(this->defaultADCBufferSize);
+    
+    //- set switches mode(must be set before actual offsets are computed)
+    config.set_switches_mode(this->switches);
+    
+    //- the initial offsets
+    config.set_offsets(offsets);
+    
+    //- the BPM location
+    config.set_location(this->bpm_location);
+
+    //- set DD thread activity period
+    config.set_dd_thread_activity_period(this->dDTaskActivityPeriod);
+    
+    //- set SA thread activity period
+    config.set_sa_thread_activity_period(this->sATaskActivityPeriod);
+    
+    //- set ADC thread activity period
+    config.set_adc_thread_activity_period(this->aDCTaskActivityPeriod);
+    
+    //- set FA data refresh period
+    config.set_fa_cache_refresh_period(this->fADataCacheRefreshPeriod);
+
+    //- set some special behaviours
+    config.enable_auto_switching_on_sa_activation(this->enableAutoSwitchingIfSAEnabled);
+    config.enable_dsc_on_auto_switching_activation(this->enableDSCIfAutoSwitchingEnabled);
+
+    //- external trigger status
+    if (this->enableExternalTrigger)
+      config.enable_external_trigger();
+    else
+      config.disable_external_trigger();
+
+    //- should we enable DD?
+    if (this->enableDD)
+      config.enable_dd();
+    else
+      config.disable_dd();
+
+    //- should we enable ADC?
+    if (this->enableADC)
+      config.enable_adc();
+    else
+      config.disable_adc();
+      
+    //- should we enable SA?
+    if (this->enableSA)
+      config.enable_sa();
+    else
+      config.disable_sa();
+
+    //- set SA history depth
+    config.set_sa_history_depth(this->sAHistoryLength);
+
+    //- set num of samples to use for SA RMS pos computation
+    config.set_sa_stats_num_samples(this->defaultSAStatNumSamples);
+
+    //- set DD decimation factor
+    config.set_decimation_factor(static_cast<int>(this->dDDecimationFactor));
+    
+    //- set machine time phase to defaultTimePhaseValue
+    this->tp = defaultTimePhaseValue;
+
+    //- should we enable DD optional data?
+    if (this->enableDDOptionalData)
+      config.enable_dd_optional_data();
+    else
+      config.disable_dd_optional_data();
+
+    //- should we enable SA optional data?
+    if (this->enableSAOptionalData)
+      config.enable_sa_optional_data();
+    else
+      config.disable_sa_optional_data();
+      
+    //- should we enable SA History optional data?
+    if (this->enableSAHistoryOptionalData)
+      config.enable_sa_history_optional_data();
+    else
+      config.disable_sa_history_optional_data();
+      
+    //- should we enable ADC optional data?
+    if (this->enableADCOptionalData)
+      config.enable_adc_optional_data();
+    else
+      config.disable_adc_optional_data();
+
+    //- set institute
+    config.set_institute(this->institute);
+  
+    //- actual init
+    this->bpm_hw->init(config);
+
+    //- add dynamic attributes
+    dyn_attrs.host_device(this);
+    
+    if (config.get_institute() == BPMConfig::kESRF)
+    {
+      PosAlgorithmIdAttr * pca_attr =
+                  new PosAlgorithmIdAttr("PosCompAlgorithm", this);
+      dyn_attrs.add(pca_attr);
+    }
+  }
+  catch(Tango::DevFailed & df)
+  {
+    //- ERROR_STREAM << df << std::endl;
+    this->set_status("BPM initialization failed");
+    this->set_state(Tango::FAULT);
+    this->delete_device();
+    return;
+  }
+  catch(...)
+  {
+    ERROR_STREAM << "BPM initialization failed - unknown error" << std::endl;
+    this->set_status("BPM initialization failed [unknown error]");
+    this->set_state(Tango::FAULT);
+    this->delete_device();
+    return;
+  }
+
+  //- tell the dynmaic attrs who is the BPM
+  DynamicAttritute::bpm = this->bpm_hw;
+
+  //- update sate and status
+  this->set_state(Tango::RUNNING);
+  this->set_status("device is running");
+  //- DEBUG_STREAM << "BPM successfully initialized" << std::endl;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::get_device_property()
+// 
+// description : 	Read the device properties from database.
+//
+//-----------------------------------------------------------------------------
+void Libera::get_device_property()
+{
+	//	Initialize your default values here(if not done with  POGO).
+	//------------------------------------------------------------------
+  //- Libera IP addr
+  this->liberaIpAddr = "unspecified";
+  //- Libera IP addr
+  this->liberaMulticastIpAddr = "unspecified";
+  //- Libera generic server port
+  this->liberaPort = GS_DEFAULT_PORT;
+  //- num of samples to be read from on demand data buffer
+  this->defaultDDBufferSize = NSAMPLES_DEFAULT_VALUE;
+  //- default switches configuration P3
+  this->switches = 0x3;
+  //- bpm location
+  this->location = "unspecified";
+  //- external trigger status
+  this->enableExternalTrigger = true;
+  //- external trigger status
+  this->dDTaskActivityPeriod  = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->sATaskActivityPeriod  = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->aDCTaskActivityPeriod = kDEFAULT_THREAD_ACTIVITY_PERIOD_MS;
+  this->fADataCacheRefreshPeriod = kDEFAULT_FA_CACHE_REFRESH_PERIOD_MS;
+  //- DD data soure
+  this->enableDD = false;
+  this->enableSA = false;
+  this->enableADC = false;
+  //- set SA history depth
+  this->sAHistoryLength = kDEFAULT_SA_HISTORY_DEPTH;
+  //- set default num of samples to use for SA RMS pos computation
+  this->defaultSAStatNumSamples = kDEFAULT_SA_STAT_SAMPLES;
+  //- set default decimation factor
+  this->dDDecimationFactor = 1;
+  //- set default value for machine time phase
+  this->defaultTimePhaseValue = 0;
+  //- no default value for RfSfRatio
+  this->rf_sf_ratio = 0;
+  //- all optional data disabled by default
+  this->enableDDOptionalData = false;
+  this->enableSAOptionalData = false;
+  this->enableSAHistoryOptionalData = false;
+  this->enableADCOptionalData = false;
+  //- where are we?
+  this->institute = BPMConfig::kTANGO_INSTITUTE;
+  
+	//	Read device properties from database.(Automatic code generation)
+	//------------------------------------------------------------------
+	Tango::DbData	dev_prop;
+	dev_prop.push_back(Tango::DbDatum("LiberaIpAddr"));
+	dev_prop.push_back(Tango::DbDatum("LiberaPort"));
+	dev_prop.push_back(Tango::DbDatum("DefaultDDBufferSize"));
+	dev_prop.push_back(Tango::DbDatum("Switches"));
+	dev_prop.push_back(Tango::DbDatum("LiberaMulticastIpAddr"));
+	dev_prop.push_back(Tango::DbDatum("Location"));
+	dev_prop.push_back(Tango::DbDatum("EnableExternalTrigger"));
+	dev_prop.push_back(Tango::DbDatum("DDTaskActivityPeriod"));
+	dev_prop.push_back(Tango::DbDatum("SATaskActivityPeriod"));
+	dev_prop.push_back(Tango::DbDatum("EnableDD"));
+	dev_prop.push_back(Tango::DbDatum("EnableSA"));
+	dev_prop.push_back(Tango::DbDatum("SAHistoryLength"));
+	dev_prop.push_back(Tango::DbDatum("DDDecimationFactor"));
+	dev_prop.push_back(Tango::DbDatum("EnableAutoSwitchingIfSAEnabled"));
+	dev_prop.push_back(Tango::DbDatum("EnableDSCIfAutoSwitchingEnabled"));
+	dev_prop.push_back(Tango::DbDatum("DefaultSAStatNumSamples"));
+	dev_prop.push_back(Tango::DbDatum("DefaultADCBufferSize"));
+	dev_prop.push_back(Tango::DbDatum("ADCTaskActivityPeriod"));
+	dev_prop.push_back(Tango::DbDatum("EnableADC"));
+	dev_prop.push_back(Tango::DbDatum("DefaultTimePhaseValue"));
+	dev_prop.push_back(Tango::DbDatum("InterlockConfiguration"));
+	dev_prop.push_back(Tango::DbDatum("EnableDDOptionalData"));
+	dev_prop.push_back(Tango::DbDatum("EnableSAOptionalData"));
+	dev_prop.push_back(Tango::DbDatum("EnableSAHistoryOptionalData"));
+	dev_prop.push_back(Tango::DbDatum("EnableADCOptionalData"));
+	dev_prop.push_back(Tango::DbDatum("Institute"));
+	dev_prop.push_back(Tango::DbDatum("MaxDDBufferSizeWhenDecimationEnabled"));
+	dev_prop.push_back(Tango::DbDatum("PassBBAOffsetsToFPGA"));
+	dev_prop.push_back(Tango::DbDatum("FADataCacheRefreshPeriod"));
+
+	//	Call database and extract values
+	//--------------------------------------------
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_device()->get_property(dev_prop);
+	Tango::DbDatum	def_prop, cl_prop;
+	LiberaClass	*ds_class =
+		(static_cast<LiberaClass *>(get_device_class()));
+	int	i = -1;
+
+	//	Try to initialize LiberaIpAddr from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  liberaIpAddr;
+	else {
+		//	Try to initialize LiberaIpAddr from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  liberaIpAddr;
+	}
+	//	And try to extract LiberaIpAddr value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  liberaIpAddr;
+
+	//	Try to initialize LiberaPort from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  liberaPort;
+	else {
+		//	Try to initialize LiberaPort from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  liberaPort;
+	}
+	//	And try to extract LiberaPort value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  liberaPort;
+
+	//	Try to initialize DefaultDDBufferSize from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  defaultDDBufferSize;
+	else {
+		//	Try to initialize DefaultDDBufferSize from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  defaultDDBufferSize;
+	}
+	//	And try to extract DefaultDDBufferSize value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  defaultDDBufferSize;
+
+	//	Try to initialize Switches from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  switches;
+	else {
+		//	Try to initialize Switches from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  switches;
+	}
+	//	And try to extract Switches value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  switches;
+
+	//	Try to initialize LiberaMulticastIpAddr from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  liberaMulticastIpAddr;
+	else {
+		//	Try to initialize LiberaMulticastIpAddr from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  liberaMulticastIpAddr;
+	}
+	//	And try to extract LiberaMulticastIpAddr value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  liberaMulticastIpAddr;
+
+	//	Try to initialize Location from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  location;
+	else {
+		//	Try to initialize Location from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  location;
+	}
+	//	And try to extract Location value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  location;
+
+	//	Try to initialize EnableExternalTrigger from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableExternalTrigger;
+	else {
+		//	Try to initialize EnableExternalTrigger from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableExternalTrigger;
+	}
+	//	And try to extract EnableExternalTrigger value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableExternalTrigger;
+
+	//	Try to initialize DDTaskActivityPeriod from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  dDTaskActivityPeriod;
+	else {
+		//	Try to initialize DDTaskActivityPeriod from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  dDTaskActivityPeriod;
+	}
+	//	And try to extract DDTaskActivityPeriod value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  dDTaskActivityPeriod;
+
+	//	Try to initialize SATaskActivityPeriod from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  sATaskActivityPeriod;
+	else {
+		//	Try to initialize SATaskActivityPeriod from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  sATaskActivityPeriod;
+	}
+	//	And try to extract SATaskActivityPeriod value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  sATaskActivityPeriod;
+
+	//	Try to initialize EnableDD from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableDD;
+	else {
+		//	Try to initialize EnableDD from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableDD;
+	}
+	//	And try to extract EnableDD value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableDD;
+
+	//	Try to initialize EnableSA from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableSA;
+	else {
+		//	Try to initialize EnableSA from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableSA;
+	}
+	//	And try to extract EnableSA value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableSA;
+
+	//	Try to initialize SAHistoryLength from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  sAHistoryLength;
+	else {
+		//	Try to initialize SAHistoryLength from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  sAHistoryLength;
+	}
+	//	And try to extract SAHistoryLength value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  sAHistoryLength;
+
+	//	Try to initialize DDDecimationFactor from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  dDDecimationFactor;
+	else {
+		//	Try to initialize DDDecimationFactor from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  dDDecimationFactor;
+	}
+	//	And try to extract DDDecimationFactor value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  dDDecimationFactor;
+
+	//	Try to initialize EnableAutoSwitchingIfSAEnabled from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableAutoSwitchingIfSAEnabled;
+	else {
+		//	Try to initialize EnableAutoSwitchingIfSAEnabled from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableAutoSwitchingIfSAEnabled;
+	}
+	//	And try to extract EnableAutoSwitchingIfSAEnabled value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableAutoSwitchingIfSAEnabled;
+
+	//	Try to initialize EnableDSCIfAutoSwitchingEnabled from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableDSCIfAutoSwitchingEnabled;
+	else {
+		//	Try to initialize EnableDSCIfAutoSwitchingEnabled from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableDSCIfAutoSwitchingEnabled;
+	}
+	//	And try to extract EnableDSCIfAutoSwitchingEnabled value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableDSCIfAutoSwitchingEnabled;
+
+	//	Try to initialize DefaultSAStatNumSamples from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  defaultSAStatNumSamples;
+	else {
+		//	Try to initialize DefaultSAStatNumSamples from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  defaultSAStatNumSamples;
+	}
+	//	And try to extract DefaultSAStatNumSamples value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  defaultSAStatNumSamples;
+
+	//	Try to initialize DefaultADCBufferSize from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  defaultADCBufferSize;
+	else {
+		//	Try to initialize DefaultADCBufferSize from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  defaultADCBufferSize;
+	}
+	//	And try to extract DefaultADCBufferSize value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  defaultADCBufferSize;
+
+	//	Try to initialize ADCTaskActivityPeriod from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  aDCTaskActivityPeriod;
+	else {
+		//	Try to initialize ADCTaskActivityPeriod from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  aDCTaskActivityPeriod;
+	}
+	//	And try to extract ADCTaskActivityPeriod value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  aDCTaskActivityPeriod;
+
+	//	Try to initialize EnableADC from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableADC;
+	else {
+		//	Try to initialize EnableADC from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableADC;
+	}
+	//	And try to extract EnableADC value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableADC;
+
+	//	Try to initialize DefaultTimePhaseValue from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  defaultTimePhaseValue;
+	else {
+		//	Try to initialize DefaultTimePhaseValue from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  defaultTimePhaseValue;
+	}
+	//	And try to extract DefaultTimePhaseValue value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  defaultTimePhaseValue;
+
+	//	Try to initialize InterlockConfiguration from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  interlockConfiguration;
+	else {
+		//	Try to initialize InterlockConfiguration from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  interlockConfiguration;
+	}
+	//	And try to extract InterlockConfiguration value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  interlockConfiguration;
+
+	//	Try to initialize EnableDDOptionalData from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableDDOptionalData;
+	else {
+		//	Try to initialize EnableDDOptionalData from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableDDOptionalData;
+	}
+	//	And try to extract EnableDDOptionalData value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableDDOptionalData;
+
+	//	Try to initialize EnableSAOptionalData from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableSAOptionalData;
+	else {
+		//	Try to initialize EnableSAOptionalData from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableSAOptionalData;
+	}
+	//	And try to extract EnableSAOptionalData value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableSAOptionalData;
+
+	//	Try to initialize EnableSAHistoryOptionalData from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableSAHistoryOptionalData;
+	else {
+		//	Try to initialize EnableSAHistoryOptionalData from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableSAHistoryOptionalData;
+	}
+	//	And try to extract EnableSAHistoryOptionalData value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableSAHistoryOptionalData;
+
+	//	Try to initialize EnableADCOptionalData from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  enableADCOptionalData;
+	else {
+		//	Try to initialize EnableADCOptionalData from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  enableADCOptionalData;
+	}
+	//	And try to extract EnableADCOptionalData value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  enableADCOptionalData;
+
+	//	Try to initialize Institute from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  institute;
+	else {
+		//	Try to initialize Institute from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  institute;
+	}
+	//	And try to extract Institute value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  institute;
+
+	//	Try to initialize MaxDDBufferSizeWhenDecimationEnabled from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  maxDDBufferSizeWhenDecimationEnabled;
+	else {
+		//	Try to initialize MaxDDBufferSizeWhenDecimationEnabled from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  maxDDBufferSizeWhenDecimationEnabled;
+	}
+	//	And try to extract MaxDDBufferSizeWhenDecimationEnabled value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  maxDDBufferSizeWhenDecimationEnabled;
+
+	//	Try to initialize PassBBAOffsetsToFPGA from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  passBBAOffsetsToFPGA;
+	else {
+		//	Try to initialize PassBBAOffsetsToFPGA from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  passBBAOffsetsToFPGA;
+	}
+	//	And try to extract PassBBAOffsetsToFPGA value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  passBBAOffsetsToFPGA;
+
+	//	Try to initialize FADataCacheRefreshPeriod from class property
+	cl_prop = ds_class->get_class_property(dev_prop[++i].name);
+	if (cl_prop.is_empty()==false)	cl_prop  >>  fADataCacheRefreshPeriod;
+	else {
+		//	Try to initialize FADataCacheRefreshPeriod from default device value
+		def_prop = ds_class->get_default_device_property(dev_prop[i].name);
+		if (def_prop.is_empty()==false)	def_prop  >>  fADataCacheRefreshPeriod;
+	}
+	//	And try to extract FADataCacheRefreshPeriod value from database
+	if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  fADataCacheRefreshPeriod;
+
+
+
+	//	End of Automatic code generation
+	//------------------------------------------------------------------
+	
+	//----------------------------------------------------------------------
+	//- Get incoherence ref. value (this is an attr. property)
+	//----------------------------------------------------------------------
+	//- get the reference incoherence value 
+	Tango::DbData db_data;
+	Tango::DbDatum	ref_inco("RefIncoherence");	
+	db_data.push_back (ref_inco);
+	
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_device()->get_attribute_property (db_data);
+		
+	for (size_t i = 0; i< db_data.size(); i++)
+  {
+   	long nb_prop;
+   	string &att_name = db_data[i].name;
+   	db_data[i] >> nb_prop;
+   	i++;
+   	for (int k=0; k < nb_prop; k++)
+    {
+       string &prop_name = db_data[i].name;
+       if (att_name == "RefIncoherence")
+       {
+			  if (prop_name == "__value")
+          db_data[i] >>  ref_incoherence;
+       }
+       i++;
+    }
+	}
+	//-----------------------------------------------------------------------
+		
+	//----------------------------------------------------------------------
+  //- get system property: RfSfRatio 
+	//----------------------------------------------------------------------
+  Tango::DbData rf_rs_ratio_db_data;
+  try
+  {
+    //- get value from database
+    rf_rs_ratio_db_data.push_back(Tango::DbDatum(kRFFSRATIO_PROPERTY_NAME));
+    this->get_db_device()->get_dbase()->get_property(BPM_ROOT_PROPERTY, rf_rs_ratio_db_data);
+  }
+  catch(Tango::DevFailed & df)
+  {
+    Tango::Except::re_throw_exception(df, 
+                                       _CPTC("SOFTWARE_FAILURE"), 
+                                       _CPTC("TANGO exception caught while trying to reading a BPM system property]"), 
+                                       _CPTC("BPMOffsets::get_device_property"));
+  }
+  
+  if ((rf_rs_ratio_db_data[0] >> this->rf_sf_ratio) == false)
+  {
+    ERROR_STREAM << "required system property <" << kRFFSRATIO_PROPERTY_NAME " is missing or has invalid value" << endl;
+    critical_properties_missing = true;
+  }
+  
+# if ! defined(_EMBEDDED_DEVICE_)
+  if (liberaIpAddr == "unspecified")
+  {
+    ERROR_STREAM << "required device property <LiberaIpAddr> is missing" << endl;
+    critical_properties_missing = true;
+  }
+  if (liberaMulticastIpAddr == "unspecified")
+  {
+    ERROR_STREAM << "required device property <LiberaMulticastIpAddr> is missing" << endl;
+    critical_properties_missing = true;
+  }
+#endif
+
+  if (location == "unspecified")
+  {
+    ERROR_STREAM << "required device property <Location> is missing" << endl;
+    critical_properties_missing = true;
+  }
+  else
+  {
+    std::transform(location.begin(), location.end(), location.begin(),::toupper);
+    if (location == LOCATION_TL1)
+      this->bpm_location = BPM_LOC_TL1;
+      
+    else if (location == LOCATION_BOOSTER)
+      this->bpm_location = BPM_LOC_BOOSTER;
+
+    else if (location == LOCATION_TL2)
+      this->bpm_location = BPM_LOC_TL2;
+
+    else if (location == LOCATION_STORAGE_RING)
+      this->bpm_location = BPM_LOC_STORAGE_RING;
+
+    else
+    {
+      this->bpm_location = BPM_LOC_UNKNOWN;
+      ERROR_STREAM << "device property <Location> is invalid" << endl;
+      critical_properties_missing = true;
+    }
+  }
+  
+  if (defaultDDBufferSize < NSAMPLES_MIN_VALUE)
+  {
+    this->defaultDDBufferSize = NSAMPLES_MIN_VALUE;
+    WARN_STREAM << "device property <DefaultDDBufferSize> is invalid - using " << NSAMPLES_MIN_VALUE << endl;
+  }
+     
+  if (this->interlockConfiguration.size() == 0)
+  {
+    ERROR_STREAM << "required class(or device) property <InterlockConfiguration> is missing - aborting init process" << endl;
+    critical_properties_missing = true;
+  }
+  else if (this->interlockConfiguration.size() !=  kINTERLOCK_CONFIG_FIELDS)
+  {
+    ERROR_STREAM << "invalid class(or device) property <InterlockConfiguration> - vector should contains " 
+                 << kINTERLOCK_CONFIG_FIELDS
+                 << " entries - check property definition"
+                 << endl;
+    critical_properties_missing = true;
+  }
+  
+# if ! defined(_EMBEDDED_DEVICE_)
+  INFO_STREAM << "property LiberaIpAddr::" << liberaIpAddr << endl;
+  INFO_STREAM << "property LiberaPort::" << liberaPort << endl;
+  INFO_STREAM << "property LiberaMulticastIpAddr::" << liberaMulticastIpAddr << endl;
+#endif 
+  INFO_STREAM << "property DefaultNumSamples [DD]::" << defaultDDBufferSize << endl;
+  INFO_STREAM << "property DefaultNumSamples [ADC]::" << defaultADCBufferSize << endl;
+  INFO_STREAM << "property Switches::" << switches << endl;
+  INFO_STREAM << "property Location::" << location << endl;
+  INFO_STREAM << "property DDTaskActivityPeriod::" << dDTaskActivityPeriod << " ms" << endl;
+  INFO_STREAM << "property SATaskActivityPeriod::" << sATaskActivityPeriod << " ms" << endl;
+  INFO_STREAM << "property ADCTaskActivityPeriod::" << aDCTaskActivityPeriod << " ms" << endl;
+  INFO_STREAM << "property FADataCacheRefreshPeriod::" << fADataCacheRefreshPeriod << " ms" << endl;
+  INFO_STREAM << "property EnableExternalTrigger::" << enableExternalTrigger << endl;
+  INFO_STREAM << "property EnableDD::" << enableDD << endl;
+  INFO_STREAM << "property EnableSA::" << enableSA << endl;
+  INFO_STREAM << "property EnableADC::" << enableADC << endl;
+  INFO_STREAM << "property SAHistoryLength::" << sAHistoryLength << endl;
+  INFO_STREAM << "property DDDecimationFactor::" << dDDecimationFactor << endl;
+  INFO_STREAM << "property EnableDSCIfAutoSwitchingEnabled::" << enableDSCIfAutoSwitchingEnabled << endl;
+  INFO_STREAM << "property EnableAutoSwitchingIfSAEnabled::" << enableAutoSwitchingIfSAEnabled << endl;
+  INFO_STREAM << "property DefaultSAStatNumSamples::" << defaultSAStatNumSamples << endl;
+  INFO_STREAM << "property DefaultTimePhaseValue::" << defaultTimePhaseValue << endl;
+  INFO_STREAM << "property " << kRFFSRATIO_PROPERTY_NAME << "::" << rf_sf_ratio << endl;
+  INFO_STREAM << "property EnableDDOptionalData::" << enableDDOptionalData << endl;
+  INFO_STREAM << "property EnableSAOptionalData::" << enableSAOptionalData << endl;
+  INFO_STREAM << "property EnableADCOptionalData::" << enableADCOptionalData << endl;
+  INFO_STREAM << "property EnableSAHistoryOptionalData::" << enableSAHistoryOptionalData << endl;
+  INFO_STREAM << "property Institute::" << institute << endl;
+  INFO_STREAM << "property MaxDDBufferSizeWhenDecimationEnabled::" << maxDDBufferSizeWhenDecimationEnabled << endl;
+  INFO_STREAM << "property PassBBAOffsetsToFPGA::" << passBBAOffsetsToFPGA << endl;
+  
+//  INFO_STREAM << "interlockConfiguration.size = " << this->interlockConfiguration.size() << std::endl;
+//  for(size_t i = 0; i < this->interlockConfiguration.size(); i++)
+//    INFO_STREAM << this->interlockConfiguration[i] << std::endl;
+//  ::sleep(2);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::always_executed_hook()
+//
+// description :  method always executed before any command is executed
+//
+//-----------------------------------------------------------------------------
+void Libera::always_executed_hook()
+{
+
+}
+
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::read_attr_hardware
+//
+// description :  Hardware acquisition for attributes.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_attr_hardware(vector<long> &attr_list)
+{
+  //- DEBUG_STREAM << "Libera::read_attr_hardware(vector<long> &attr_list) entering... " << endl;
+
+  //static bpm::Timer t_call_dt;
+  //std::cout << "Libera::read_attr_hardware::call-dt " << t_call_dt.elapsed_msec() << " ms" << std::endl;
+  //t_call_dt.restart();
+  //bpm::Timer t_exec;
+    
+  //  Add your own code here
+  if (this->bpm_hw)
+  {
+    //---- UPDATE HARDWARE STATUS ---------------
+    this->bpm_hw->get_hw_status(this->bpm_hw_status);
+
+    //--- INTERLOCK STATUS ----------------------
+	  this->intl_x_notified = this->bpm_hw_status.intl_flags & bpm::BPM::INTERLOCK_X;
+		this->intl_z_notified = this->bpm_hw_status.intl_flags & bpm::BPM::INTERLOCK_Z;
+		this->intl_attn_notified = this->bpm_hw_status.intl_flags & bpm::BPM::INTERLOCK_ATTN;
+		this->intl_adc_pre_filter_notified = this->bpm_hw_status.intl_flags & bpm::BPM::INTERLOCK_ADC;
+		this->intl_adc_post_filter_notified = this->bpm_hw_status.intl_flags & bpm::BPM::INTERLOCK_ADCF;
+   
+    //---- READ POST-MORTEM DATA SOURCE ---------
+    this->pm_event_counter = this->bpm_hw->pm_event_counter();
+    this->pm_notified = this->bpm_hw->pm_notified();
+    if (this->pm_notified)
+    {
+      //- read data from hardware (may throw an exception)
+      try
+      {
+        bool force_data_update = false;
+        if (this->pm_data == 0)
+        {
+          this->pm_data = new DDData();
+          force_data_update = true;
+        }
+        this->bpm_hw->get_pm_data(*(this->pm_data), force_data_update);
+        DynamicAttritute::pm_data = this->pm_data;
+      }
+      catch(Tango::DevFailed & df)
+      {
+        std::string reason(df.errors[0].reason);
+        if (reason != kNO_DATA_MSG)
+        {
+          Tango::Except::re_throw_exception(df, 
+                                            _CPTC("HARDWARE_FAILURE"), 
+                                            _CPTC("TANGO exception caught while reading the PM data"),
+                                            _CPTC("Libera::read_attr_hardware"));
+        }
+      }
+      catch(...)
+      {
+        Tango::Except::throw_exception(_CPTC("HARDWARE_FAILURE"), 
+                                       _CPTC("unknown exception caught while reading the PM data"), 
+                                       _CPTC("Libera::read_attr_hardware"));
+      }    
+    }
+    //---- READ DD DATA SOURCE ------------------
+    if (this->bpm_hw->configuration().dd_enabled())
+    {
+      //- read data from hardware (may throw an exception)
+      try
+      {
+        bool force_data_update = false;
+        if (this->dd_data == 0)
+        {
+          this->dd_data = new DDData();
+          force_data_update = true;
+        }
+        this->bpm_hw->get_dd_data(*(this->dd_data), force_data_update);
+        DynamicAttritute::dd_data = this->dd_data;
+      }
+      catch(Tango::DevFailed & df)
+      {
+        std::string reason(df.errors[0].reason);
+        if (reason != kNO_DATA_MSG)
+        {
+          Tango::Except::re_throw_exception(df, 
+                                             _CPTC("HARDWARE_FAILURE"), 
+                                             _CPTC("TANGO exception caught while reading the DD data"),
+                                             _CPTC("Libera::read_attr_hardware"));
+        }
+      }
+      catch(...)
+      {
+        Tango::Except::throw_exception(_CPTC("HARDWARE_FAILURE"), 
+                                       _CPTC("unknown exception caught while reading the DD data"), 
+                                       _CPTC("Libera::read_attr_hardware"));
+      }
+    }
+    else if (this->dd_data)
+    {
+      this->dd_data->release();
+      this->dd_data = 0;
+    }   
+    //---- READ ADC DATA SOURCE ------------------
+    if (this->bpm_hw->configuration().adc_enabled())
+    {
+      //- read data from hardware (may throw an exception)
+      try
+      {
+        bool force_data_update = false;
+        if (this->adc_data == 0)
+        {
+          this->adc_data = new ADCData();
+          force_data_update = true;
+        }
+        this->bpm_hw->get_adc_data(*(this->adc_data), force_data_update);
+        DynamicAttritute::adc_data = this->adc_data;
+      }
+      catch(Tango::DevFailed & df)
+      {
+        std::string reason(df.errors[0].reason);
+        if (reason != kNO_DATA_MSG)
+        {
+          Tango::Except::re_throw_exception(df, 
+                                            _CPTC("HARDWARE_FAILURE"), 
+                                            _CPTC("TANGO exception caught while reading the ADC data"),
+                                            _CPTC("Libera::read_attr_hardware"));
+        }
+      }
+      catch(...)
+      {
+        Tango::Except::throw_exception(_CPTC("HARDWARE_FAILURE"), 
+                                       _CPTC("unknown exception caught while reading the ADC data"), 
+                                       _CPTC("Libera::read_attr_hardware"));
+      }
+    }
+    else if (this->adc_data)
+    {
+      this->adc_data->release();
+      this->adc_data = 0;
+    }    
+    //---- READ SA DATA SOURCE ------------------
+    if (this->bpm_hw->configuration().sa_enabled())  
+    {
+      //- read data from hardware(may throw an exception)
+      try
+      {
+        bool force_data_update = false;
+        if (this->sa_data == 0)
+        {
+          this->sa_data = new SAData();
+          force_data_update = true;
+        }
+        this->bpm_hw->get_sa_data(*(this->sa_data), force_data_update);
+        DynamicAttritute::sa_data = this->sa_data;
+      }
+      catch(Tango::DevFailed & df)
+      {
+        std::string reason(df.errors[0].reason);
+        if (reason != kNO_DATA_MSG)
+        {
+          Tango::Except::re_throw_exception(df, 
+                                             _CPTC("HARDWARE_FAILURE"), 
+                                             _CPTC("TANGO exception caught while reading the SA data"), 
+                                             _CPTC("Libera::read_attr_hardware"));
+        }
+      }
+      catch(...)
+      {
+        Tango::Except::throw_exception(_CPTC("HARDWARE_FAILURE"), 
+                                        _CPTC("unknown exception caught while reading the SA data"), 
+                                        _CPTC("Libera::read_attr_hardware"));
+      }
+    } 
+    else if (this->sa_data)
+    {
+      this->sa_data->release();
+      this->sa_data = 0;
+      DynamicAttritute::sa_data = 0;
+    }       
+  }
+  else
+  {
+    Tango::Except::throw_exception(_CPTC("SOFTWARE_FAILURE"),
+                                   _CPTC("device is not properly initialized"), 
+                                   _CPTC("Libera::read_attr_hardware"));
+  }
+  
+  //std::cout << "Libera::read_attr_hardware::exec time " << t_exec.elapsed_msec() << " ms" << std::endl;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_LiberaModel
+// 
+// description : 	Extract real attribute values for LiberaModel acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_LiberaModel(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_LiberaModel(Tango::Attribute &attr) entering... "<< endl;
+  static unsigned short model = 0;
+  model = this->bpm_hw->configuration().libera_model();
+  attr.set_value(&model);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_UseLiberaSAData
+// 
+// description : 	Extract real attribute values for UseLiberaSAData acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_UseLiberaSAData(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_UseLiberaSAData(Tango::Attribute &attr) entering... "<< endl;
+  //  Add your own code to control device here
+  this->using_fpga_sa_pos = ! this->bpm_hw->configuration().local_sa_pos_computation_enabled();
+  attr.set_value(&using_fpga_sa_pos);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_UseLiberaSAData
+// 
+// description : 	Write UseLiberaSAData attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_UseLiberaSAData(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_UseLiberaSAData(Tango::WAttribute &attr) entering... "<< endl;
+  
+  Tango::DevBoolean tdb;
+  attr.get_write_value(tdb);
+
+  BPMConfig cfg = this->bpm_hw->configuration();
+  tdb ? cfg.disable_local_sa_pos_computation() : cfg.enable_local_sa_pos_computation();
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_HasMAFSupport
+// 
+// description : 	Extract real attribute values for HasMAFSupport acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_HasMAFSupport(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_HasMAFSupport(Tango::Attribute &attr) entering... "<< endl;
+  this->maf_support = this->bpm_hw->configuration().has_maf_support();
+  attr.set_value(&this->maf_support);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_logs
+// 
+// description : 	Extract real attribute values for logs acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_logs(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_logs(Tango::Attribute &attr) entering... "<< endl;
+
+  if (this->m_appender)
+  {
+    this->m_appender->get_logs(this->m_logs);
+    
+    this->m_logs_array.length(this->m_logs.size());
+  
+    for (size_t i = 0; i < this->m_logs.size(); i++)
+      this->m_logs_array[i] = this->m_logs[i].c_str();
+  
+    attr.set_value(this->m_logs_array.get_buffer(), this->m_logs.size());
+  }
+  else
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+  }
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SumSAHistory
+// 
+// description : 	Extract real attribute values for SumSAHistory acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SumSAHistory(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SumSAHistory(Tango::Attribute &attr) entering... "<< endl;
+  
+  const SAData::Buffer & sah_sum = this->bpm_hw->get_sa_history().sum();
+  attr.set_value(sah_sum.base(), sah_sum.depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SumMeanSA
+// 
+// description : 	Extract real attribute values for SumMeanSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SumMeanSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SumMeanSA(Tango::Attribute &attr) entering... "<< endl;
+
+  if (
+        ! this->bpm_hw->configuration().sa_enabled()
+      ||
+        ! this->bpm_hw->configuration().sa_history_optional_data_enabled()
+     )
+  {
+    attr.set_quality (Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_s_mean = this->bpm_hw->get_sa_history().sum_mean();
+  attr.set_value(&this->sa_s_mean);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_IaDD
+// 
+// description : 	Extract real attribute values for IaDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_IaDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_IaDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->sin_va().base(), this->dd_data->sin_va().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_IbDD
+// 
+// description : 	Extract real attribute values for IbDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_IbDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_IbDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->sin_vb().base(), this->dd_data->sin_vb().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_IcDD
+// 
+// description : 	Extract real attribute values for IcDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_IcDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_IcDD(Tango::Attribute &attr) entering... "<< endl;
+
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->sin_vc().base(), this->dd_data->sin_vc().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_IdDD
+// 
+// description : 	Extract real attribute values for IdDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_IdDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_IdDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->sin_vd().base(), this->dd_data->sin_vd().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QaDD
+// 
+// description : 	Extract real attribute values for QaDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QaDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QaDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->cos_va().base(), this->dd_data->cos_va().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QbDD
+// 
+// description : 	Extract real attribute values for QbDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QbDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QbDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->cos_vb().base(), this->dd_data->cos_vb().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QcDD
+// 
+// description : 	Extract real attribute values for QcDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QcDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QcDD(Tango::Attribute &attr) entering... "<< endl;
+  
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->cos_vc().base(), this->dd_data->cos_vc().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QdDD
+// 
+// description : 	Extract real attribute values for QdDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QdDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QdDD(Tango::Attribute &attr) entering... "<< endl;
+
+  if (this->dd_data == 0 || ! this->bpm_hw->configuration().dd_optional_data_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value (this->dd_data->cos_vd().base(), this->dd_data->cos_vd().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_Incoherence
+// 
+// description : 	Extract real attribute values for Incoherence acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_Incoherence(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_Incoherence(Tango::Attribute &attr) entering... "<< endl;
+	
+	//- an exception is thrown if no SA data is available to compute the incoherence value. 
+  //- so...
+	try
+  {
+    this->incoherence = bpm_hw->get_incoherence();
+    attr.set_value (&this->incoherence);
+  }
+  catch (Tango::DevFailed &df)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+	}	
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_RefIncoherence
+// 
+// description : 	Extract real attribute values for RefIncoherence acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_RefIncoherence(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_RefIncoherence(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->ref_incoherence);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MaxIncoherence
+// 
+// description : 	Extract real attribute values for MaxIncoherence acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MaxIncoherence(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MaxIncoherence(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value (&this->max_incoherence);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_MaxIncoherence
+// 
+// description : 	Write MaxIncoherence attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_MaxIncoherence(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_MaxIncoherence(Tango::WAttribute &attr) entering... "<< endl;
+	attr.get_write_value(this->max_incoherence);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MaxIncoherenceDrift
+// 
+// description : 	Extract real attribute values for MaxIncoherenceDrift acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MaxIncoherenceDrift(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MaxIncoherenceDrift(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value (&this->max_drift_incoherence);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_MaxIncoherenceDrift
+// 
+// description : 	Write MaxIncoherenceDrift attribute values to hardware.
+//
+//------------------- //- ----------------------------------------------------------
+void Libera::write_MaxIncoherenceDrift(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_MaxIncoherenceDrift(Tango::WAttribute &attr) entering... "<< endl;
+	attr.get_write_value(this->max_drift_incoherence);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ExternalSwitching
+// 
+// description : 	Extract real attribute values for ExternalSwitching acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ExternalSwitching(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ExternalSwitching(Tango::Attribute &attr) entering... "<< endl;
+	this->external_switching_enabled =  
+	    static_cast<Tango::DevBoolean>(this->bpm_hw->configuration().external_switching_enabled());
+  attr.set_value (&this->external_switching_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_ExternalSwitching
+// 
+// description : 	Write ExternalSwitching attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_ExternalSwitching(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_ExternalSwitching(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevBoolean tdb;
+  attr.get_write_value (tdb);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  tdb ? cfg.enable_external_switching() : cfg.disable_external_switching();
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SwitchingDelay
+// 
+// description : 	Extract real attribute values for SwitchingDelay acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SwitchingDelay(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SwitchingDelay(Tango::Attribute &attr) entering... "<< endl;
+	this->switching_delay = this->bpm_hw->configuration().get_switching_delay();
+  attr.set_value (&this->switching_delay);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_SwitchingDelay
+// 
+// description : 	Write SwitchingDelay attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_SwitchingDelay(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_SwitchingDelay(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdl;
+  attr.get_write_value (tdl);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_switching_delay (tdl);
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_CompensateTune
+// 
+// description : 	Extract real attribute values for CompensateTune acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_CompensateTune(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_CompensateTune(Tango::Attribute &attr) entering... "<< endl;
+	this->tune_compensation_enabled =  
+	    static_cast<Tango::DevBoolean>(this->bpm_hw->configuration().tune_compensation_enabled());
+  attr.set_value (&this->tune_compensation_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_CompensateTune
+// 
+// description : 	Write CompensateTune attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_CompensateTune(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_CompensateTune(Tango::WAttribute &attr) entering... "<< endl;
+	
+	Tango::DevBoolean tdb;
+  attr.get_write_value (tdb);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  tdb ? cfg.enable_tune_compensation() : cfg.disable_tune_compensation();
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_OffsetTune
+// 
+// description : 	Extract real attribute values for OffsetTune acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_OffsetTune(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_OffsetTune(Tango::Attribute &attr) entering... "<< endl;
+	this->tune_offset = this->bpm_hw->configuration().get_tune_offset();
+  attr.set_value (&this->tune_offset);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_OffsetTune
+// 
+// description : 	Write OffsetTune attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_OffsetTune(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_OffsetTune(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdd;
+  attr.get_write_value (tdd);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_tune_offset(tdd);
+  this->bpm_hw->reconfigure(cfg);  
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ExternalTriggerDelay
+// 
+// description : 	Extract real attribute values for ExternalTriggerDelay acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ExternalTriggerDelay(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ExternalTriggerDelay(Tango::Attribute &attr) entering... "<< endl;
+	this->external_trigger_delay = this->bpm_hw->configuration().get_external_trigger_delay();
+  attr.set_value(&this->external_trigger_delay);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_ExternalTriggerDelay
+// 
+// description : 	Write ExternalTriggerDelay attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_ExternalTriggerDelay(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_ExternalTriggerDelay(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_external_trigger_delay(tdl);
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_PMOffset
+// 
+// description : 	Extract real attribute values for PMOffset acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_PMOffset(Tango::Attribute &attr)
+{
+  //- DEBUG_STREAM << "Libera::read_PMOffset(Tango::Attribute &attr) entering... "<< endl;
+	this->pm_offset =  this->bpm_hw->configuration().get_pm_offset();
+  attr.set_value (&this->pm_offset);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_PMOffset
+// 
+// description : 	Write PMOffset attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_PMOffset(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_PMOffset(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdl;
+  attr.get_write_value (tdl);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_pm_offset (tdl);
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MAFLength
+// 
+// description : 	Extract real attribute values for MAFLength acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MAFLength(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MAFLength(Tango::Attribute &attr) entering... "<< endl;
+  const BPMConfig & cfg = this->bpm_hw->configuration();
+  if (cfg.has_maf_support())
+  {
+	  this->maf_length =  this->bpm_hw->configuration().get_maf_length();
+    attr.set_value(&this->maf_length);
+  }
+  else
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+  }
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_MAFLength
+// 
+// description : 	Write MAFLength attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_MAFLength(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_MAFLength(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdl;
+  attr.get_write_value (tdl);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  if (cfg.has_maf_support())
+  {
+    cfg.set_maf_length (tdl);
+    this->bpm_hw->reconfigure(cfg);
+  }
+  else
+  {
+    Tango::Except::throw_exception(_CPTC("UNSUPPORTED_FEATURE"), 
+                                   _CPTC("this Libera has no MAF support"), 
+                                   _CPTC("Libera::write_MAFLength"));
+  }
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MAFDelay
+// 
+// description : 	Extract real attribute values for MAFDelay acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MAFDelay(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MAFDelay(Tango::Attribute &attr) entering... "<< endl;
+	
+  const BPMConfig & cfg = this->bpm_hw->configuration();
+  if (cfg.has_maf_support())
+  {
+    this->maf_delay = this->bpm_hw->configuration().get_maf_delay();
+    attr.set_value (&this->maf_delay);
+  }
+  else
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+  }
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_MAFDelay
+// 
+// description : 	Write MAFDelay attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_MAFDelay(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_MAFDelay(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  
+  BPMConfig cfg = this->bpm_hw->configuration();
+  if (cfg.has_maf_support())
+  {
+    cfg.set_maf_delay(tdl);
+    this->bpm_hw->reconfigure(cfg);
+  }
+  else
+  {
+    Tango::Except::throw_exception(_CPTC("UNSUPPORTED_FEATURE"), 
+                                   _CPTC("this Libera has no MAF support"), 
+                                   _CPTC("Libera::write_MAFDelay"));
+  }
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_CpuUsage
+// 
+// description : 	Extract real attribute values for CpuUsage acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_CpuUsage(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_CpuUsage(Tango::Attribute &attr) entering... "<< endl;
+#if ! defined(_EMBEDDED_DEVICE_)
+	attr.set_quality(Tango::ATTR_INVALID);
+#else
+	attr.set_value(&this->bpm_hw_status.cpu_usage);
+#endif
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_FreeMemory
+// 
+// description : 	Extract real attribute values for FreeMemory acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_FreeMemory(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_FreeMemory(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_quality(Tango::ATTR_INVALID);
+	//-TODO: attr.set_value(&this->bpm_hw_status.memory_free);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_RamFsUsage
+// 
+// description : 	Extract real attribute values for RamFsUsage acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_RamFsUsage(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_RamFsUsage(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_quality(Tango::ATTR_INVALID);
+	//-TODO: attr.set_value(&this->bpm_hw_status.ram_fs_usage);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_UpTime
+// 
+// description : 	Extract real attribute values for UpTime acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_UpTime(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_UpTime(Tango::Attribute &attr) entering... "<< endl;
+#if ! defined(_EMBEDDED_DEVICE_)
+	attr.set_quality(Tango::ATTR_INVALID);
+#else
+	attr.set_value(&this->bpm_hw_status.uptime);
+#endif
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_UserData
+// 
+// description : 	Extract real attribute values for UserData acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_UserData(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_UserData(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<short*>(this->sa_data->user_data()), kNUM_USER_DATA);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_PMNotificationCounter
+// 
+// description : 	Extract real attribute values for PMNotificationCounter acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_PMNotificationCounter(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_PMNotificationCounter(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->pm_event_counter);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_CxSA
+// 
+// description : 	Extract real attribute values for CxSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_CxSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_CxSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<long*>(&this->sa_data->cx()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_CzSA
+// 
+// description : 	Extract real attribute values for CzSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_CzSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_CzSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<long*>(&this->sa_data->cz()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XMeanPosSA
+// 
+// description : 	Extract real attribute values for XMeanPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XMeanPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XMeanPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_x_mean = this->bpm_hw->get_sa_history().x_mean();
+  attr.set_value(&this->sa_x_mean);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZMeanPosSA
+// 
+// description : 	Extract real attribute values for ZMeanPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZMeanPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZMeanPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_z_mean = this->bpm_hw->get_sa_history().z_mean();
+  attr.set_value(&this->sa_z_mean);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XPeakPosSA
+// 
+// description : 	Extract real attribute values for XPeakPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XPeakPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XPeakPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_x_peak = this->bpm_hw->get_sa_history().x_peak();
+  attr.set_value(&this->sa_x_peak);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZPeakPosSA
+// 
+// description : 	Extract real attribute values for ZPeakPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZPeakPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZPeakPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_z_peak = this->bpm_hw->get_sa_history().z_peak();
+  attr.set_value(&this->sa_z_peak);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_TimePhase
+// 
+// description : 	Extract real attribute values for TimePhase acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_TimePhase(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_TimePhase(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->tp);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_TimePhase
+// 
+// description : 	Write TimePhase attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_TimePhase(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_TimePhase(Tango::WAttribute &attr) entering... "<< endl;
+	long max = static_cast<long>(this->rf_sf_ratio) - 1;
+	long mt_phase;
+	attr.get_write_value(mt_phase);
+	if (mt_phase < 0 || mt_phase > max)
+	{
+    Tango::Except::throw_exception(_CPTC("INVALID_ARGUMENT"), 
+                                    _CPTC("the specified time phase is out of range - valid range is [0, RfSfRatio - 1]"), 
+                                    _CPTC("Libera::write_TimePhase"));
+	}
+	this->tp = mt_phase;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_HWTemperature
+// 
+// description : 	Extract real attribute values for HWTemperature acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_HWTemperature(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_HWTemperature(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->bpm_hw_status.temp);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_Fan1Speed
+// 
+// description : 	Extract real attribute values for Fan1Speed acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_Fan1Speed(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_Fan1Speed(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->bpm_hw_status.fan_1_speed);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_Fan2Speed
+// 
+// description : 	Extract real attribute values for Fan2Speed acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_Fan2Speed(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_Fan2Speed(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->bpm_hw_status.fan_2_speed);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SCPLLStatus
+// 
+// description : 	Extract real attribute values for SCPLLStatus acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SCPLLStatus(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SCPLLStatus(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->bpm_hw_status.sc_ppl_lock_status);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MCPLLStatus
+// 
+// description : 	Extract real attribute values for MCPLLStatus acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MCPLLStatus(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MCPLLStatus(Tango::Attribute &attr) entering... "<< endl;
+	attr.set_value(&this->bpm_hw_status.mc_ppl_lock_status);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_MachineTime
+// 
+// description : 	Extract real attribute values for MachineTime acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_MachineTime(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_MachineTime(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(reinterpret_cast<FPDataType*>(&this->mt));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_MachineTime
+// 
+// description : 	Write MachineTime attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_MachineTime(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_MachineTime(Tango::WAttribute &attr) entering... "<< endl;
+  attr.get_write_value(this->mt);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SystemTime
+// 
+// description : 	Extract real attribute values for SystemTime acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SystemTime(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SystemTime(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(reinterpret_cast<FPDataType*>(&this->st));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_SystemTime
+// 
+// description : 	Write SystemTime attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_SystemTime(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_SystemTime(Tango::WAttribute &attr) entering... "<< endl;
+  attr.get_write_value(this->st);
+}
+ 
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCBufferSize
+// 
+// description : 	Extract real attribute values for ADCBufferSize acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCBufferSize(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCBufferSize(Tango::Attribute &attr) entering... "<< endl;
+  this->defaultADCBufferSize = static_cast<Tango::DevLong>(this->bpm_hw->configuration().get_adc_raw_buffer_depth());
+  attr.set_value(&this->defaultADCBufferSize);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_ADCBufferSize
+// 
+// description : 	Write ADCBufferSize attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_ADCBufferSize(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_ADCBufferSize(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_adc_raw_buffer_depth(static_cast<size_t>(tdl));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCChannelA
+// 
+// description : 	Extract real attribute values for ADCChannelA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCChannelA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCChannelA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->adc_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->adc_data->a().base(), this->adc_data->a().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCChannelB
+// 
+// description : 	Extract real attribute values for ADCChannelB acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCChannelB(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCChannelB(Tango::Attribute &attr) entering... "<< endl;
+  if (this->adc_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->adc_data->b().base(),  this->adc_data->b().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCChannelC
+// 
+// description : 	Extract real attribute values for ADCChannelC acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCChannelC(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCChannelC(Tango::Attribute &attr) entering... "<< endl;
+  if (this->adc_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->adc_data->c().base(), this->adc_data->c().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCChannelD
+// 
+// description : 	Extract real attribute values for ADCChannelD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCChannelD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCChannelD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->adc_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->adc_data->d().base(), this->adc_data->d().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SAStatNumSamples
+// 
+// description : 	Extract real attribute values for SAStatNumSamples acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SAStatNumSamples(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SAStatNumSamples(Tango::Attribute &attr) entering... "<< endl;
+  this->defaultSAStatNumSamples = static_cast<Tango::DevLong>(this->bpm_hw->configuration().get_sa_rms_num_samples());
+  attr.set_value(reinterpret_cast<Tango::DevLong*>(&this->defaultSAStatNumSamples));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_SAStatNumSamples
+// 
+// description : 	Write SAStatNumSamples attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_SAStatNumSamples(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_SAStatNumSamples(Tango::WAttribute &attr) entering... "<< endl;
+
+	Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_sa_stats_num_samples(static_cast<size_t>(tdl));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XRMSPosSA
+// 
+// description : 	Extract real attribute values for XRMSPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XRMSPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XRMSPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_x_rms = this->bpm_hw->get_sa_history().x_rms();
+  attr.set_value(&this->sa_x_rms);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZRMSPosSA
+// 
+// description : 	Extract real attribute values for ZRMSPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZRMSPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZRMSPosSA(Tango::Attribute &attr) entering... "<< endl;
+	if (! this->bpm_hw->configuration().sa_enabled())
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  this->sa_z_rms = this->bpm_hw->get_sa_history().z_rms();
+  attr.set_value(&this->sa_z_rms);
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_Gain
+// 
+// description : 	Extract real attribute values for Gain acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_Gain(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_Gain(Tango::Attribute &attr) entering... "<< endl;
+	this->gain =  this->bpm_hw->configuration().get_gain();
+  attr.set_value(&this->gain);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_Gain
+// 
+// description : 	Write Gain attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_Gain(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_Gain(Tango::WAttribute &attr) entering... "<< endl;
+	
+	FPDataType tdd;
+  attr.get_write_value(tdd);
+  int actual_gain = static_cast<int>(tdd);
+	if (this->bpm_hw->configuration().agc_enabled())
+	{
+    Tango::Except::throw_exception(_CPTC("invalid request"), 
+                                    _CPTC("can't change the Libera input gain while AGC is active"), 
+                                    _CPTC("Libera::Libera::write_Gain"));
+	}
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_gain(actual_gain);
+  this->bpm_hw->reconfigure(cfg);  
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DSCMode
+// 
+// description : 	Extract real attribute values for DSCMode acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DSCMode(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DSCMode(Tango::Attribute &attr) entering... "<< endl;
+	this->dsc_mode =  static_cast<Tango::DevShort>(this->bpm_hw->configuration().get_dsc_mode());
+  attr.set_value(&this->dsc_mode);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_DSCMode
+// 
+// description : 	Write DSCMode attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_DSCMode(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_DSCMode(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevShort tds;
+  attr.get_write_value(tds);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_dsc_mode(tds);
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockConfiguration
+// 
+// description : 	Extract real attribute values for InterlockConfiguration acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockConfiguration(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockConfiguration(Tango::Attribute &attr) entering... "<< endl;
+	const CSPI_ENVPARAMS& ep = this->bpm_hw->configuration().get_current_env_parameters();
+	this->ilk_config[0] = ep.ilk.mode;
+	this->ilk_config[1] = ep.ilk.Xlow / 1.E6;
+	this->ilk_config[2] = ep.ilk.Xhigh / 1.E6;
+  this->ilk_config[3] = ep.ilk.Ylow / 1.E6;
+  this->ilk_config[4] = ep.ilk.Yhigh / 1.E6;
+  this->ilk_config[5] = ep.ilk.overflow_limit;
+  this->ilk_config[6] = ep.ilk.overflow_dur;
+  this->ilk_config[7] = ep.ilk.gain_limit;
+  attr.set_value(this->ilk_config, kILK_NUM_PARAMS);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_AGCEnabled
+// 
+// description : 	Extract real attribute values for AGCEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_AGCEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_AGCEnabled(Tango::Attribute &attr) entering... "<< endl;
+	this->agc_enabled =  static_cast<Tango::DevBoolean>(this->bpm_hw->configuration().agc_enabled());
+  attr.set_value(&this->agc_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_AGCEnabled
+//
+// description : 	Write AGCEnabled attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_AGCEnabled(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_AGCEnabled(Tango::WAttribute &attr) entering... "<< endl;
+	Tango::DevBoolean tdb;
+  attr.get_write_value(tdb);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  tdb ? cfg.enable_agc() : cfg.disable_agc();
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_AutoSwitchingEnabled
+// 
+// description : 	Extract real attribute values for AutoSwitchingEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_AutoSwitchingEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_AutoSwitchingEnabled(Tango::Attribute &attr) entering... "<< endl;
+	this->auto_switching_enabled =  static_cast<Tango::DevBoolean>(this->bpm_hw->configuration().auto_switching_enabled());
+  attr.set_value(&this->auto_switching_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_Switches
+//
+// description : 	Extract real attribute values for Switches acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_Switches(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_Switches(Tango::Attribute &attr) entering... "<< endl;
+  this->switches = this->bpm_hw->configuration().get_switches_mode();
+  attr.set_value(&this->switches);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDDecimationFactor
+// 
+// description : 	Extract real attribute values for DDDecimationFactor acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDDecimationFactor(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDDecimationFactor(Tango::Attribute &attr) entering... "<< endl;
+  this->dDDecimationFactor =  static_cast<unsigned short>(this->bpm_hw->configuration().get_decimation_factor());
+  attr.set_value(&this->dDDecimationFactor);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_DDDecimationFactor
+// 
+// description : 	Write DDDecimationFactor attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_DDDecimationFactor(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_DDDecimationFactor(Tango::WAttribute &attr) entering... "<< endl;
+  attr.get_write_value(this->dDDecimationFactor);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_decimation_factor(static_cast<int>(this->dDDecimationFactor));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_DDBufferSize
+// 
+// description : 	Write DDBufferSize attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_DDBufferSize(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_DDBufferSize(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  if (tdl < 0) return;
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_dd_raw_buffer_depth(static_cast<size_t>(tdl));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_DDTriggerOffset
+// 
+// description : 	Write DDTriggerOffset attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_DDTriggerOffset(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_DDTriggerOffset(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevLong tdl;
+  attr.get_write_value(tdl);
+  if (tdl < 0) tdl = 0;
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_dd_trigger_offset(static_cast<unsigned long>(tdl));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_Switches
+// 
+// description : 	Write Switches attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_Switches(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_Switches(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevShort tds;
+  attr.get_write_value(tds);
+  BPMConfig cfg = this->bpm_hw->configuration();
+  cfg.set_switches_mode(static_cast<int>(tds));
+  this->bpm_hw->reconfigure(cfg);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XLow
+// 
+// description : 	Extract real attribute values for XLow acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XLow(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XLow(Tango::Attribute &attr) entering... "<< endl;
+  this->x_lo = this->bpm_hw->configuration().get_x_low_limit() / 1.E6;
+  attr.set_value(&this->x_lo);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XHigh
+// 
+// description : 	Extract real attribute values for XHigh acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XHigh(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XHigh(Tango::Attribute &attr) entering... "<< endl;
+  this->x_hi = this->bpm_hw->configuration().get_x_high_limit() / 1.E6;
+  attr.set_value(&this->x_hi);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZLow
+// 
+// description : 	Extract real attribute values for ZLow acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZLow(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZLow(Tango::Attribute &attr) entering... "<< endl;
+  this->z_lo = this->bpm_hw->configuration().get_z_low_limit() / 1.E6;
+  attr.set_value(&this->z_lo);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZHigh
+// 
+// description : 	Extract real attribute values for ZHigh acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZHigh(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZHigh(Tango::Attribute &attr) entering... "<< endl;
+  this->z_hi = this->bpm_hw->configuration().get_z_high_limit() / 1.E6;
+  attr.set_value(&this->z_hi);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XPosPM
+// 
+// description : 	Extract real attribute values for XPosPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XPosPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XPosPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->x().base(), this->pm_data->x().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZPosPM
+// 
+// description : 	Extract real attribute values for ZPosPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZPosPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZPosPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->z().base(), this->pm_data->z().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QuadPM
+// 
+// description : 	Extract real attribute values for QuadPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QuadPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QuadPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->q().base(), this->pm_data->q().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SumPM
+// 
+// description : 	Extract real attribute values for SumPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SumPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SumPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->sum().base(), this->pm_data->sum().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VaPM
+// 
+// description : 	Extract real attribute values for VaPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VaPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VaPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->va().base(), this->pm_data->va().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VbPM
+// 
+// description : 	Extract real attribute values for VbPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VbPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VbPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->vb().base(), this->pm_data->vb().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VcPM
+// 
+// description : 	Extract real attribute values for VcPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VcPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VcPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->vc().base(), this->pm_data->vc().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VdPM
+// 
+// description : 	Extract real attribute values for VdPM acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VdPM(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VdPM(Tango::Attribute &attr) entering... "<< endl;
+  if (this->pm_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->pm_data->vd().base(), this->pm_data->vd().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_PMNotified
+// 
+// description : 	Extract real attribute values for PMNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_PMNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_PMNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->pm_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockXNotified
+// 
+// description : 	Extract real attribute values for InterlockXNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockXNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockXNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->intl_x_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockZNotified
+// 
+// description : 	Extract real attribute values for InterlockZNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockZNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockZNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->intl_z_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockAttnNotified
+// 
+// description : 	Extract real attribute values for InterlockAttnNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockAttnNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockAttnNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->intl_attn_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockADCPreFilterNotified
+// 
+// description : 	Extract real attribute values for InterlockADCPreFilterNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockADCPreFilterNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockADCPreFilterNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->intl_adc_pre_filter_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_InterlockADCPostFilterNotified
+// 
+// description : 	Extract real attribute values for InterlockADCPostFilterNotified acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_InterlockADCPostFilterNotified(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_InterlockADCPostFilterNotified(Tango::Attribute &attr) entering... "<< endl;
+  attr.set_value(&this->intl_adc_post_filter_notified);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDTriggerOffset
+// 
+// description : 	Extract real attribute values for DDTriggerOffset acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDTriggerOffset(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDTriggerOffset(Tango::Attribute &attr) entering... "<< endl;
+  this->dd_buffer_offset = static_cast<Tango::DevLong>(this->bpm_hw->configuration().get_dd_trigger_offset());
+  attr.set_value(&this->dd_buffer_offset);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VaSA
+// 
+// description : 	Extract real attribute values for VaSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VaSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VaSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->va()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VbSA
+// 
+// description : 	Extract real attribute values for VbSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VbSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VbSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->vb()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VcSA
+// 
+// description : 	Extract real attribute values for VcSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VcSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VcSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->vc()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VdSA
+// 
+// description : 	Extract real attribute values for VdSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VdSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VdSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->vd()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XPosSA
+// 
+// description : 	Extract real attribute values for XPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XPosSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->x()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZPosSA
+// 
+// description : 	Extract real attribute values for ZPosSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZPosSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZPosSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->z()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SumSA
+// 
+// description : 	Extract real attribute values for SumSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SumSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SumSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->sum()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QuadSA
+// 
+// description : 	Extract real attribute values for QuadSA acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QuadSA(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QuadSA(Tango::Attribute &attr) entering... "<< endl;
+  if (this->sa_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(const_cast<FPDataType*>(&this->sa_data->q()));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDBufferSize
+// 
+// description : 	Extract real attribute values for DDBufferSize acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDBufferSize(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDBufferSize(Tango::Attribute &attr) entering... "<< endl;
+  BPMConfig& cfg = const_cast<BPMConfig&>(this->bpm_hw->configuration());
+  this->defaultDDBufferSize = static_cast<Tango::DevLong>(cfg.get_dd_raw_buffer_depth());
+  attr.set_value(&this->defaultDDBufferSize);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XPosDD
+// 
+// description : 	Extract real attribute values for XPosDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XPosDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XPosDD(Tango::Attribute &attr) entering... "<< endl;
+	
+  bpm::Timer t_exec;
+
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->x().base(), this->dd_data->x().depth());
+  
+  //- std::cout << "Libera::read_XPosDD::exec time is " << t_exec.elapsed_msec() << " ms" << std::endl;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZPosDD
+// 
+// description : 	Extract real attribute values for ZPosDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZPosDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZPosDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->z().base(), this->dd_data->z().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_QuadDD
+// 
+// description : 	Extract real attribute values for QuadDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_QuadDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_QuadDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->q().base(), this->dd_data->q().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SumDD
+// 
+// description : 	Extract real attribute values for SumDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SumDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SumDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->sum().base(), this->dd_data->sum().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VaDD
+// 
+// description : 	Extract real attribute values for VaDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VaDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VaDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->va().base(), this->dd_data->va().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VbDD
+// 
+// description : 	Extract real attribute values for VbDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VbDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VbDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->vb().base(), this->dd_data->vb().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VcDD
+// 
+// description : 	Extract real attribute values for VcDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VcDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VcDD(Tango::Attribute &attr) entering... " << endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->vc().base(), this->dd_data->vc().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_VdDD
+// 
+// description : 	Extract real attribute values for VdDD acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_VdDD(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_VdDD(Tango::Attribute &attr) entering... "<< endl;
+  if (this->dd_data == 0)
+  {
+    attr.set_quality(Tango::ATTR_INVALID);
+    return;
+  }
+  attr.set_value(this->dd_data->vd().base(), this->dd_data->vd().depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDTriggerCounter
+// 
+// description : 	Extract real attribute values for DDTriggerCounter acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDTriggerCounter(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDTriggerCounter(Tango::Attribute &attr) entering... "<< endl;
+  this->trigger_counter = static_cast < Tango::DevLong >(this->bpm_hw->trigger_counter());
+  attr.set_value(&this->trigger_counter);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDBufferFreezingEnabled
+// 
+// description : 	Extract real attribute values for DDBufferFreezingEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDBufferFreezingEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDBufferFreezingEnabled(Tango::Attribute &attr) entering... "<< endl;
+  this->dd_cache_enabled = this->bpm_hw->is_dd_buffer_freezing_enabled();
+  attr.set_value(&this->dd_cache_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDBufferFrozen
+// 
+// description : 	Extract real attribute values for DDBufferFrozen acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDBufferFrozen(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDBufferFrozen(Tango::Attribute &attr) entering... "<< endl;
+  this->dd_cache_frozen = this->bpm_hw->is_dd_buffer_frozen();
+  attr.set_value(&this->dd_cache_frozen);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_DDEnabled
+// 
+// description : 	Extract real attribute values for DDEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_DDEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_DDEnabled(Tango::Attribute &attr) entering... "<< endl;
+	//	Add your own code to control device here
+  this->dd_enabled = this->bpm_hw->configuration().dd_enabled();
+  attr.set_value(&this->dd_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_DDEnabled
+// 
+// description : 	Write DDEnabled attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_DDEnabled(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_DDEnabled(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevBoolean tdb;
+  attr.get_write_value(tdb);
+  tdb ? enable_dd() : disable_dd();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_SAEnabled
+// 
+// description : 	Extract real attribute values for SAEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_SAEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_SAEnabled(Tango::Attribute &attr) entering... "<< endl;
+	//	Add your own code to control device here
+  this->sa_enabled = this->bpm_hw->configuration().sa_enabled();
+  attr.set_value(&this->sa_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_SAEnabled
+// 
+// description : 	Write SAEnabled attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_SAEnabled(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_SAEnabled(Tango::WAttribute &attr) entering... "<< endl;
+  Tango::DevBoolean tdb;
+  attr.get_write_value(tdb);
+  tdb ? enable_sa() : disable_sa();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ADCEnabled
+// 
+// description : 	Extract real attribute values for ADCEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ADCEnabled(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ADCEnabled(Tango::Attribute &attr) entering... "<< endl;
+	//	Add your own code to control device here
+  this->adc_enabled = this->bpm_hw->configuration().adc_enabled();
+  attr.set_value(&this->adc_enabled);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::write_ADCEnabled
+// 
+// description : 	Write ADCEnabled attribute values to hardware.
+//
+//-----------------------------------------------------------------------------
+void Libera::write_ADCEnabled(Tango::WAttribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::write_ADCEnabled(Tango::Attribute &attr) entering... "<< endl;
+	Tango::DevBoolean tdb;
+  attr.get_write_value(tdb);
+  tdb ? enable_adc() : disable_adc();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_XPosSAHistory
+// 
+// description : 	Extract real attribute values for XPosSAHistory acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_XPosSAHistory(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_XPoxSAHistory(Tango::Attribute &attr) entering... "<< endl;
+  const SAData::Buffer & sah_x = this->bpm_hw->get_sa_history().x();
+  attr.set_value(sah_x.base(), sah_x.depth()); 
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::read_ZPosSAHistory
+// 
+// description : 	Extract real attribute values for ZPosSAHistory acquisition result. 
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ZPosSAHistory(Tango::Attribute &attr)
+{
+	//- DEBUG_STREAM << "Libera::read_ZPosSAHistory(Tango::Attribute &attr) entering... "<< endl;
+  const SAData::Buffer & sah_z = this->bpm_hw->get_sa_history().z();
+  attr.set_value(sah_z.base(), sah_z.depth());
+}
+
+//+----------------------------------------------------------------------------
+//
+// method :     Libera::read_ExternalTriggerEnabled
+//
+// description :  Extract real attribute values for ExternalTriggerEnabled acquisition result.
+//
+//-----------------------------------------------------------------------------
+void Libera::read_ExternalTriggerEnabled(Tango::Attribute &attr)
+{
+  //- DEBUG_STREAM << "Libera::read_ExternalTriggerEnabled(Tango::Attribute &attr) entering... " << endl;
+  this->external_trigger_enabled = this->bpm_hw->configuration().external_trigger_enabled();
+  attr.set_value(&this->external_trigger_enabled);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::get_parameters
+ *
+ *	description:	method to execute "GetParameters"
+ *	Retruns the current gains and offsets (i.e. the parameters used for position computation)
+ *
+ * @return	The BPM gain and offsets
+ *
+ */
+//+------------------------------------------------------------------
+Tango::DevVarDoubleStringArray *Libera::get_parameters()
+{
+  //- DEBUG_STREAM << "Libera::get_parameters(): entering... !" << endl;
+  const bpm::BPMOffsets & offsets = this->bpm_hw->configuration().get_offsets();
+  Tango::DevVarDoubleStringArray * argout = new Tango::DevVarDoubleStringArray();
+  size_t max = bpm::BPMOffsets::LAST_PARAMETER;
+  argout->dvalue.length(max + 2);
+  argout->svalue.length(max + 2);
+  argout->dvalue[0] = 0;
+  std::string bid = "BLOCK-ID::" + offsets.block_identifier();
+  argout->svalue[0] = CORBA::string_dup(bid.c_str());
+  argout->dvalue[1] = 0;
+  std::string hwid = "HW-ID::" + offsets.hw_identifier();
+  argout->svalue[1] = CORBA::string_dup(hwid.c_str());
+  for(size_t p = bpm::BPMOffsets::GEOMETRY, i = 2; p < max; p++, i++)
+  {
+    argout->dvalue[i] = offsets[p];
+    argout->svalue[i] = CORBA::string_dup(offsets.parameter_name(p));
+  }
+  return argout;
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::enable_dd
+ *
+ *	description:	method to execute "EnableDD"
+ *	Enables the so called "data on demand" (i.e. first turns) data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::enable_dd()
+{
+	//- DEBUG_STREAM << "Libera::enable_dd(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.enable_dd();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::disable_dd
+ *
+ *	description:	method to execute "DisableDD"
+ *	Disables the so called "data on demand" (i.e. first turns) data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::disable_dd()
+{
+	//- DEBUG_STREAM << "Libera::disable_dd(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.disable_dd();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::enable_sa
+ *
+ *	description:	method to execute "EnableSA"
+ *	Enables the so called "slow acquisition" data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::enable_sa()
+{
+	//- DEBUG_STREAM << "Libera::enable_sa(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.enable_sa();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::disable_sa
+ *
+ *	description:	method to execute "DisableSA"
+ *	Disables the so called "slow acquisition" data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::disable_sa()
+{
+	//- DEBUG_STREAM << "Libera::disable_sa(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.disable_sa();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::unfreeze_ddbuffer
+ *
+ *	description:	method to execute "UnfreezeDDBuffer"
+ *	Unfreezes the DD buffer
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::unfreeze_ddbuffer()
+{
+	//- DEBUG_STREAM << "Libera::unfreeze_ddbuffer(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  this->bpm_hw->unfreeze_dd_buffer(); 
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::enable_ddbuffer_freezing
+ *
+ *	description:	method to execute "EnableDDBufferFreezing"
+ *	Enables the DD buffer freezing mechanism
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::enable_ddbuffer_freezing()
+{
+	//- DEBUG_STREAM << "Libera::enable_ddbuffer_freezing(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.enable_dd_buffer_freezing();
+  this->bpm_hw->reconfigure(config); 
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::disable_ddbuffer_freezing
+ *
+ *	description:	method to execute "DisableDDBufferFreezing"
+ *	Disables the DD buffer freezing mechanism
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::disable_ddbuffer_freezing()
+{
+	//- DEBUG_STREAM << "Libera::disable_ddbuffer_freezing(): entering... !" << endl;
+
+  //  Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.disable_dd_buffer_freezing();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::reset_pmnotification
+ *
+ *	description:	method to execute "ResetPMNotification"
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::reset_pmnotification()
+{
+	//- DEBUG_STREAM << "Libera::reset_pm_notification(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  this->bpm_hw->reset_pm_notification();
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::reset_interlock_notification
+ *
+ *	description:	method to execute "ResetInterlockNotification"
+ *	Resets the interlock notification flags to false
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::reset_interlock_notification()
+{
+	//- DEBUG_STREAM << "Libera::reset_pm_notification(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  this->bpm_hw->reset_interlock_notification();
+  this->intl_x_notified = false;
+  this->intl_z_notified = false;
+  this->intl_attn_notified = false;
+  this->intl_adc_pre_filter_notified = false;
+  this->intl_adc_post_filter_notified = false;
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::set_interlock_configuration
+ *
+ *	description:	method to execute "SetInterlockConfiguration"
+ *	Change interlock configuration using the InterlockConfiguration class (or device) property.
+ *	Only  modify  the interlock configuration, the remaining env. parameters remain unchanged.
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::set_interlock_configuration()
+{
+	//- DEBUG_STREAM << "Libera::set_interlock_configuration(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  this->set_interlock_config_from_property();
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		apply_interlock_config_from_property()
+// 
+// description : 	Reads/applies the interlock part of the InterlockConfiguration property.
+//
+//-----------------------------------------------------------------------------
+void Libera::set_interlock_config_from_property()
+{
+	if (Tango::Util::instance()->_UseDb==false)
+	{
+    Tango::Except::throw_exception(_CPTC("SOFTWARE_ERROR"), 
+                                    _CPTC("can't load InterlockConfiguration property - device has been started with the 'nodb' option"), 
+                                    _CPTC("Libera::apply_interlock_config_from_property"));
+	}
+	
+	LiberaClass	*ds_class =(static_cast<LiberaClass *>(this->get_device_class()));
+	
+	Tango::DbData	dev_prop;
+	dev_prop.push_back(Tango::DbDatum("InterlockConfiguration"));
+	get_db_device()->get_property(dev_prop);
+			
+	Tango::DbDatum cl_prop;
+	cl_prop = ds_class->get_class_property(dev_prop[0].name);
+	if (! cl_prop.is_empty())	
+	{
+	  //- initialize InterlockConfiguration from user defined class property value
+	  cl_prop >> this->interlockConfiguration;
+	}
+	else 
+	{
+	  //- initialize UserDefinedStartupEnvParameters from its default class property value
+	  Tango::DbDatum def_prop; 
+	  def_prop = ds_class->get_default_device_property(dev_prop[0].name);
+	  if (! def_prop.is_empty())
+	    def_prop >> this->interlockConfiguration;
+	}
+	//- initialize UserDefinedStartupEnvParameters from user defined device property value(overwrite class value)
+	if (! dev_prop[0].is_empty())
+	  dev_prop[0] >> this->interlockConfiguration;
+  
+	BPMConfig cfg = this->bpm_hw->configuration();
+	cfg.set_interlock_configuration(this->interlockConfiguration);
+	this->bpm_hw->set_interlock_configuration(cfg);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::enable_adc
+ *
+ *	description:	method to execute "EnableADC"
+ *	Enables the so called ADC data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::enable_adc()
+{
+	//- DEBUG_STREAM << "Libera::enable_adc(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.enable_adc();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::disable_adc
+ *
+ *	description:	method to execute "DisableADC"
+ *	Disables the so called ADC data source
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::disable_adc()
+{
+	//- DEBUG_STREAM << "Libera::disable_adc(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  BPMConfig config = this->bpm_hw->configuration();
+  config.disable_adc();
+  this->bpm_hw->reconfigure(config);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::set_time_on_next_trigger
+ *
+ *	description:	method to execute "SetTimeOnNextTrigger"
+ *	Applies both machine et system time values on next trigger
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::set_time_on_next_trigger()
+{
+	//- DEBUG_STREAM << "Libera::set_time_on_next_trigger(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	bpm::BPM::TimeSettings ts;
+	ts.mt = this->mt;
+	ts.st = this->st;
+	ts.tp = this->tp;
+  this->bpm_hw->set_time_on_next_trigger(ts);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::read_fadata
+ *
+ *	description:	method to execute "ReadFAData"
+ *	Statring from[offest] in FA data block, reads [size of elems] * [num of elems] bytes.
+ *
+ * @param	argin	The reading parameters: [0]:offset in FA data block, [1]:size of elems, [2]:num of elems
+ * @return	The data [as an array of bytes]
+ *
+ */
+//+------------------------------------------------------------------
+Tango::DevVarLongArray *Libera::read_fadata(const Tango::DevVarLongArray * argin)
+{
+	//	POGO has generated a method core with argout allocation.
+	//	If you would like to use a static reference without copying,
+	//	See "TANGO Device Server Programmer's Manual"
+	//		(chapter : Writing a TANGO DS / Exchanging data)
+	//------------------------------------------------------------
+
+  //- DEBUG_STREAM << "Libera::read_fadata(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	
+	if (argin->length() != 3)
+	{    
+	  Tango::Except::throw_exception(_CPTC("INVALID_CMD_ARG"), 
+                                   _CPTC("input array should contains the 3 reading parameters: offset, size and count"), 
+                                   _CPTC("Libera::read_fadata"));	
+	}
+	
+	bpm::Timer t;
+	
+	bpm::BPM::FAData fad;
+	fad.offset = static_cast<size_t>((*argin)[0]);
+	fad.size   = static_cast<size_t>((*argin)[1]);
+	fad.count  = static_cast<size_t>((*argin)[2]);
+	      
+	this->bpm_hw->read_fa_data(fad);
+	
+	Tango::DevVarLongArray	*argout = new Tango::DevVarLongArray();
+	argout->length(fad.size * fad.count / sizeof(Tango::DevLong));
+	::memcpy(argout->get_buffer(), fad.pbuf, fad.size * fad.count); 
+
+  //- std::cout << "Libera::read_fadata took " << t.elapsed_msec() << std::endl;
+   
+	return argout;
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::write_fadata
+ *
+ *	description:	method to execute "WriteFAData"
+ *	Starting from [offset] in Fa data block, writes [size of elems * num of elems].
+ *	The actual data to be written starts at index [4] in the input array.
+ *
+ * @param	argin	The writting parameters: [0]:offset in FA data block, bytes[1]:size of elems, [2]:num of elems, [3, ...]: actual to data to be written
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::write_fadata(const Tango::DevVarLongArray *argin)
+{
+  //- DEBUG_STREAM << "Libera::write_fadata(): entering... !" << endl;
+
+	//	Add your own code to control device here
+	
+	if (argin->length() < 3)
+	{    
+	  Tango::Except::throw_exception(_CPTC("INVALID_CMD_ARG"), 
+                                    _CPTC("input array should contains the 3 reading parameters: offset, size, count and data"), 
+                                    _CPTC("Libera::read_fadata"));	
+	}
+	
+  bpm::BPM::FAData fad;
+	fad.offset = static_cast<size_t>((*argin)[0]);
+	fad.size = static_cast<size_t>((*argin)[1]);
+	fad.count = static_cast<size_t>((*argin)[2]);
+	fad.pbuf = new char[fad.size * fad.count];
+	::memcpy(fad.pbuf, argin->get_buffer() + 3, fad.size * fad.count); 
+	
+	this->bpm_hw->write_fa_data(fad);
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::save_dscparameters
+ *
+ *	description:	method to execute "SaveDSCParameters"
+ *	Saves the current DSC parameters
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::save_dscparameters()
+{
+	//- DEBUG_STREAM << "Libera::save_dscparameters(): entering... !" << endl;
+
+	//	Add your own code to control device here
+
+  this->bpm_hw->save_dsc_parameters();
+}
+
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::reload_system_properties
+ *
+ *	description:	method to execute "ReloadSystemProperties"
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::reload_system_properties()
+{
+  BPMConfig config = this->bpm_hw->configuration();
+  
+  BPMOffsets offsets;
+  
+  try
+  {
+    offsets.read_from_tango_db(config.get_location(), this);
+  }
+  catch(Tango::DevFailed & df)
+  {
+    ERROR_STREAM << df << std::endl;
+	  Tango::Except::re_throw_exception(df,
+	                                     _CPTC("SOFTWARE_ERROR"), 
+                                       _CPTC("could not read BPM system properties from database [Tango exception caught]"), 
+                                       _CPTC("Libera::reload_system_properties"));	
+  }
+  catch(...)
+  {
+    ERROR_STREAM << "BPM initialization failed - unknown error" << std::endl;
+	  Tango::Except::throw_exception(_CPTC("SOFTWARE_ERROR"), 
+                                    _CPTC("could not read BPM system properties from database [unknown exception caught]"), 
+                                    _CPTC("Libera::reload_system_properties"));	
+  }
+  
+  config.set_offsets(offsets);
+  
+  this->bpm_hw->reconfigure(config);   
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::set_ref_incoherence
+ *
+ *	description:	method to execute "SetRefIncoherence"
+ *	Set the actual incoherence value as refeference value for the drift alarm calculation.
+ *
+ *
+ */
+//+------------------------------------------------------------------
+void Libera::set_ref_incoherence()
+{
+	//- DEBUG_STREAM << "Libera::set_ref_incoherence(): entering... !" << endl;
+
+	//-	Add your own code to control device here
+
+	//- save current incoherence value as reference
+	this->ref_incoherence = this->incoherence;
+	
+	//- save the new reference as attribute property
+	Tango::DbDatum ref_inco("RefIncoherence");
+	Tango::DbDatum value("__value");
+	ref_inco << (short) 1;
+	value << this->ref_incoherence;
+	
+	Tango::DbData db_data;
+	db_data.push_back(ref_inco);
+	db_data.push_back(value);
+	
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_device()->put_attribute_property(db_data);	
+}
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::dev_status
+ *
+ *	description:	method to execute "Status"
+ *	This command gets the device status (stored in its <i>device_status</i> data member) and returns it to the caller.
+ *
+ * @return	Status description
+ *
+ */
+//+------------------------------------------------------------------
+Tango::ConstDevString Libera::dev_status()
+{
+	//- DEBUG_STREAM << "Libera::dev_status(): entering... !" << endl;
+
+	//	Add your own code to control device here
+
+  if (this->bpm_hw)
+  {
+    BPM::BPMSwStatus sw_status ;
+    this->bpm_hw->get_sw_status(sw_status);
+    switch (sw_status.state)
+    {
+      case BPM::BPM_RUNNING:
+        this->set_status(sw_status.status);
+        break;
+      case BPM::BPM_FAULT:
+        this->set_status(sw_status.status);
+        break;
+      default:
+        this->set_status("BPM unknown state");
+        break;
+    }
+  }
+  else
+  {
+    std::string current_status;
+    current_status  = "Device initialization failed [see device log for details]\n";
+    current_status += "- possible reason: invalid system or device property [hint: check the TANGO database entries]\n";
+#if ! defined(_EMBEDDED_DEVICE_)
+    current_status += "- possible reason: Libera is down or unreachable [errno:110 - connection timed out] [hint: try to ping the associated Libera]\n";
+    current_status += "- possible reason: Libera generic server not running [errno:111 - connection refused] [hint: be sure liberad is running on the Libera]\n";
+		current_status += "- possible reason: Previous connexion to Libera generic not properly shutdown [errno:16 - device or resource busy] [hint: exec /etc/init.d/libera-server restart on the Libera]\n";
+    current_status += "- possible reason: an embedded Libera service crashed [hint: be sure all deamons are running on the Libera]\n";
+#else
+    current_status += "- possible reason: Libera event daemon is running and could not be killed [hint: kill the event daemon on the Libera]\n";
+    current_status += "- possible reason: an embedded Libera service crashed [hint: be sure all  required deamons are running on the Libera]\n";
+#endif
+    current_status += "Check any potential problem source then execute the <Init> command on the device";
+    this->set_status(current_status);
+  }
+
+	return DeviceImpl::dev_status();
+}
+
+/*
+
+*/
+
+//+------------------------------------------------------------------
+/**
+ *	method:	Libera::dev_state
+ *
+ *	description:	method to execute "State"
+ *	This command gets the device state (stored in its <i>device_state</i> data member) and returns it to the caller.
+ *
+ * @return	State Code
+ *
+ */
+//+------------------------------------------------------------------
+Tango::DevState Libera::dev_state()
+{
+	Tango::DevState	argout = DeviceImpl::dev_state();
+  
+	//- DEBUG_STREAM << "Libera::dev_state(): entering... !" << endl;
+
+	//	Add your own code to control device here
+  
+  if (this->bpm_hw)
+  {
+    BPM::BPMSwStatus sw_status ;
+    this->bpm_hw->get_sw_status(sw_status);
+    switch (sw_status.state)
+    {
+      case BPM::BPM_RUNNING:
+        argout = this->incoherence_out_of_range() ? Tango::ALARM : Tango::ON;
+        break;
+      case BPM::BPM_FAULT:
+        argout = Tango::FAULT;
+        break;
+      default:
+        argout = Tango::UNKNOWN;
+        break;
+    }
+  }
+  else
+  {
+    argout = Tango::FAULT;
+  }
+  
+	this->set_state(argout);
+  
+	return argout;
+}
+
+// ============================================================================
+// Libera::incoherence_out_of_range
+// ============================================================================
+bool Libera::incoherence_out_of_range ()
+{
+  return (
+            (this->incoherence > this->max_incoherence) 
+          ||
+            ((::fabs(this->incoherence - this->ref_incoherence)) > this->max_drift_incoherence)
+         );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}	//	namespace
diff --git a/src/Libera.h b/src/Libera.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc428f4a9f5db614c3e58620af540bd7520327ef
--- /dev/null
+++ b/src/Libera.h
@@ -0,0 +1,1728 @@
+//=============================================================================
+//
+// file :        Libera.h
+//
+// description : Include for the Libera class.
+//
+// project :	Libera BPM Device Server
+//
+// $Author: nleclercq $
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//=============================================================================
+//
+//      This file is generated by POGO
+//  (Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+#ifndef _LIBERA_H
+#define _LIBERA_H
+
+#include <tango.h>
+#include "BPM.h"
+#include "DynamicAttr.h"
+#include "DynamicAttrHelper.h"
+#include "InnerAppender.h"
+
+using namespace bpm;
+
+//using namespace Tango;
+
+/**
+ * @author	$Author: nleclercq $
+ * @version	$Revision: 1.5.2.27.2.1 $
+ */
+
+// Add your own constants definitions here.
+//-----------------------------------------------
+#define kILK_NUM_PARAMS 8
+
+namespace Libera_ns
+{
+
+/**
+ * Class Description:
+ * IT Libera BPM Device Server
+ */
+
+/*
+ *	Device States Description:
+*  Tango::UNKNOWN :  Device is not [or not properly] initialized
+*  Tango::FAULT :    Device initialization failed or unrecoverable error
+*  Tango::ON :       BPM is up and running
+ */
+
+
+class Libera: public Tango::Device_4Impl
+{
+public:
+  //  Add your own data members here
+  //-----------------------------------------
+
+  //  Here is the Start of the automatic code generation part
+  //-------------------------------------------------------------
+  /**
+   *	@name attributes
+   *	Attributs member data.
+   */
+/*
+//@{
+		Tango::DevUShort	*attr_LiberaModel_read;
+		Tango::DevBoolean	*attr_DDEnabled_read;
+		Tango::DevBoolean	attr_DDEnabled_write;
+		Tango::DevLong	*attr_DDBufferSize_read;
+		Tango::DevLong	attr_DDBufferSize_write;
+		Tango::DevUShort	*attr_DDDecimationFactor_read;
+		Tango::DevUShort	attr_DDDecimationFactor_write;
+		Tango::DevLong	*attr_DDTriggerOffset_read;
+		Tango::DevLong	attr_DDTriggerOffset_write;
+		Tango::DevBoolean	*attr_DDBufferFreezingEnabled_read;
+		Tango::DevBoolean	*attr_DDBufferFrozen_read;
+		Tango::DevLong	*attr_DDTriggerCounter_read;
+		Tango::DevBoolean	*attr_ExternalTriggerEnabled_read;
+		Tango::DevLong	*attr_ExternalTriggerDelay_read;
+		Tango::DevLong	attr_ExternalTriggerDelay_write;
+		Tango::DevBoolean	*attr_SAEnabled_read;
+		Tango::DevBoolean	attr_SAEnabled_write;
+		Tango::DevDouble	*attr_VaSA_read;
+		Tango::DevDouble	*attr_VbSA_read;
+		Tango::DevDouble	*attr_VcSA_read;
+		Tango::DevDouble	*attr_VdSA_read;
+		Tango::DevDouble	*attr_XPosSA_read;
+		Tango::DevDouble	*attr_ZPosSA_read;
+		Tango::DevDouble	*attr_SumSA_read;
+		Tango::DevDouble	*attr_QuadSA_read;
+		Tango::DevLong	*attr_CxSA_read;
+		Tango::DevLong	*attr_CzSA_read;
+		Tango::DevLong	*attr_SAStatNumSamples_read;
+		Tango::DevLong	attr_SAStatNumSamples_write;
+		Tango::DevDouble	*attr_XMeanPosSA_read;
+		Tango::DevDouble	*attr_ZMeanPosSA_read;
+		Tango::DevDouble	*attr_XRMSPosSA_read;
+		Tango::DevDouble	*attr_ZRMSPosSA_read;
+		Tango::DevDouble	*attr_XPeakPosSA_read;
+		Tango::DevDouble	*attr_ZPeakPosSA_read;
+		Tango::DevDouble	*attr_SumMeanSA_read;
+		Tango::DevBoolean	*attr_ADCEnabled_read;
+		Tango::DevBoolean	attr_ADCEnabled_write;
+		Tango::DevLong	*attr_ADCBufferSize_read;
+		Tango::DevLong	attr_ADCBufferSize_write;
+		Tango::DevLong	*attr_PMOffset_read;
+		Tango::DevLong	attr_PMOffset_write;
+		Tango::DevBoolean	*attr_PMNotified_read;
+		Tango::DevShort	*attr_PMNotificationCounter_read;
+		Tango::DevBoolean	*attr_InterlockXNotified_read;
+		Tango::DevBoolean	*attr_InterlockZNotified_read;
+		Tango::DevBoolean	*attr_InterlockAttnNotified_read;
+		Tango::DevBoolean	*attr_InterlockADCPreFilterNotified_read;
+		Tango::DevBoolean	*attr_InterlockADCPostFilterNotified_read;
+		Tango::DevDouble	*attr_XLow_read;
+		Tango::DevDouble	*attr_XHigh_read;
+		Tango::DevDouble	*attr_ZLow_read;
+		Tango::DevDouble	*attr_ZHigh_read;
+		Tango::DevBoolean	*attr_AutoSwitchingEnabled_read;
+		Tango::DevShort	*attr_Switches_read;
+		Tango::DevShort	attr_Switches_write;
+		Tango::DevBoolean	*attr_ExternalSwitching_read;
+		Tango::DevBoolean	attr_ExternalSwitching_write;
+		Tango::DevLong	*attr_SwitchingDelay_read;
+		Tango::DevLong	attr_SwitchingDelay_write;
+		Tango::DevLong	*attr_OffsetTune_read;
+		Tango::DevLong	attr_OffsetTune_write;
+		Tango::DevBoolean	*attr_CompensateTune_read;
+		Tango::DevBoolean	attr_CompensateTune_write;
+		Tango::DevShort	*attr_DSCMode_read;
+		Tango::DevShort	attr_DSCMode_write;
+		Tango::DevBoolean	*attr_AGCEnabled_read;
+		Tango::DevBoolean	attr_AGCEnabled_write;
+		Tango::DevDouble	*attr_Gain_read;
+		Tango::DevDouble	attr_Gain_write;
+		Tango::DevBoolean	*attr_HasMAFSupport_read;
+		Tango::DevLong	*attr_MAFLength_read;
+		Tango::DevLong	attr_MAFLength_write;
+		Tango::DevLong	*attr_MAFDelay_read;
+		Tango::DevLong	attr_MAFDelay_write;
+		Tango::DevDouble	*attr_MachineTime_read;
+		Tango::DevDouble	attr_MachineTime_write;
+		Tango::DevLong	*attr_TimePhase_read;
+		Tango::DevLong	attr_TimePhase_write;
+		Tango::DevDouble	*attr_SystemTime_read;
+		Tango::DevDouble	attr_SystemTime_write;
+		Tango::DevBoolean	*attr_SCPLLStatus_read;
+		Tango::DevBoolean	*attr_MCPLLStatus_read;
+		Tango::DevShort	*attr_HWTemperature_read;
+		Tango::DevShort	*attr_Fan1Speed_read;
+		Tango::DevShort	*attr_Fan2Speed_read;
+		Tango::DevDouble	*attr_Incoherence_read;
+		Tango::DevDouble	*attr_RefIncoherence_read;
+		Tango::DevDouble	*attr_MaxIncoherence_read;
+		Tango::DevDouble	attr_MaxIncoherence_write;
+		Tango::DevDouble	*attr_MaxIncoherenceDrift_read;
+		Tango::DevDouble	attr_MaxIncoherenceDrift_write;
+		Tango::DevLong	*attr_UpTime_read;
+		Tango::DevLong	*attr_CpuUsage_read;
+		Tango::DevLong	*attr_FreeMemory_read;
+		Tango::DevLong	*attr_RamFsUsage_read;
+		Tango::DevBoolean	*attr_UseLiberaSAData_read;
+		Tango::DevBoolean	attr_UseLiberaSAData_write;
+		Tango::DevDouble	*attr_XPosDD_read;
+		Tango::DevDouble	*attr_ZPosDD_read;
+		Tango::DevDouble	*attr_QuadDD_read;
+		Tango::DevDouble	*attr_SumDD_read;
+		Tango::DevDouble	*attr_VaDD_read;
+		Tango::DevDouble	*attr_VbDD_read;
+		Tango::DevDouble	*attr_VcDD_read;
+		Tango::DevDouble	*attr_VdDD_read;
+		Tango::DevDouble	*attr_XPosSAHistory_read;
+		Tango::DevDouble	*attr_ZPosSAHistory_read;
+		Tango::DevDouble	*attr_SumSAHistory_read;
+		Tango::DevDouble	*attr_XPosPM_read;
+		Tango::DevDouble	*attr_ZPosPM_read;
+		Tango::DevDouble	*attr_QuadPM_read;
+		Tango::DevDouble	*attr_SumPM_read;
+		Tango::DevDouble	*attr_VaPM_read;
+		Tango::DevDouble	*attr_VbPM_read;
+		Tango::DevDouble	*attr_VcPM_read;
+		Tango::DevDouble	*attr_VdPM_read;
+		Tango::DevShort	*attr_ADCChannelA_read;
+		Tango::DevShort	*attr_ADCChannelB_read;
+		Tango::DevShort	*attr_ADCChannelC_read;
+		Tango::DevShort	*attr_ADCChannelD_read;
+		Tango::DevDouble	*attr_IaDD_read;
+		Tango::DevDouble	*attr_IbDD_read;
+		Tango::DevDouble	*attr_IcDD_read;
+		Tango::DevDouble	*attr_IdDD_read;
+		Tango::DevDouble	*attr_QaDD_read;
+		Tango::DevDouble	*attr_QbDD_read;
+		Tango::DevDouble	*attr_QcDD_read;
+		Tango::DevDouble	*attr_QdDD_read;
+		Tango::DevShort	*attr_UserData_read;
+		Tango::DevDouble	*attr_InterlockConfiguration_read;
+		Tango::DevString	*attr_logs_read;
+//@}
+*/
+  /*
+   *	@name Device properties
+   *	Device properties member data.
+   */
+  //@{
+/**
+ *	The Libera IP address [no default value]
+ */
+	string	liberaIpAddr;
+/**
+ *	The port on which the generic server handles external requests. Defaults to 23721.
+ */
+	Tango::DevShort	liberaPort;
+/**
+ *	Default [or initial] value for attribute DDBufferSize [in samples]. Defaults to 1024.
+ */
+	Tango::DevLong	defaultDDBufferSize;
+/**
+ *	Switches configuration. The valid range is [0..15]. Defaults to 3.
+ */
+	Tango::DevShort	switches;
+/**
+ *	Asynch. notifications (e.g. trigger events) will be send to this addr [no default value]
+ */
+	string	liberaMulticastIpAddr;
+/**
+ *	The BPM location [TL1, BOOSTER, TL2 or STORAGE_RING]. No default value.
+ */
+	string	location;
+/**
+ *	Enables (or not) the external trigger source.
+ *	Inlfuences the TANGO device behaviour not the Libera itself. Defaults to false.
+ */
+	Tango::DevBoolean	enableExternalTrigger;
+/**
+ *	Specify the watch-dog (1) or data reading period (2) in ms.
+ *	Must be in the rangec [500, 25000] ms. Defaults to 1000.
+ *	(1) : external trigger enabled - (2) : external trigger disabled.
+ */
+	Tango::DevULong	dDTaskActivityPeriod;
+/**
+ *	Specify the watch-dog (1) or data reading period (2) in ms.
+ *	Must be in the range [100, 25000] ms. Defaults to 100.
+ */
+	Tango::DevULong	sATaskActivityPeriod;
+/**
+ *	Specifies whether or not the DD data source should be enabled at startup. Defaults to false.
+ */
+	Tango::DevBoolean	enableDD;
+/**
+ *	Specifies whether or not the SA data source should be enabled at startup. Defaults to false.
+ */
+	Tango::DevBoolean	enableSA;
+/**
+ *	SA history buffer length [in samples]. Defaults to 8196.
+ */
+	Tango::DevULong	sAHistoryLength;
+/**
+ *	The DD decimation factor.
+ *	Allowed values : 1 (no decimation) or 64 (for the so called booster normal mode)
+ */
+	Tango::DevUShort	dDDecimationFactor;
+/**
+ *	When set to TRUE, auto-switching is automattically enabled when the SA data source is itself enabled
+ */
+	Tango::DevBoolean	enableAutoSwitchingIfSAEnabled;
+/**
+ *	When set to TRUE, the Digital Signal Conditioning is automattically enabled when the auto-switching is itself enabled
+ */
+	Tango::DevBoolean	enableDSCIfAutoSwitchingEnabled;
+/**
+ *	Default number of SA history samples to use form RMS pos. computation.
+ *	Defaults to 10 (last second in the SA history).
+ */
+	Tango::DevULong	defaultSAStatNumSamples;
+/**
+ *	Default [or initial] value for attribute ADCBufferSize [in samples]. Defaults to 1024.
+ */
+	Tango::DevLong	defaultADCBufferSize;
+/**
+ *	Specifies the data reading period in ms.
+ *	Must be in the range [500, 25000] ms. Defaults to 1000.
+ *	
+ */
+	Tango::DevULong	aDCTaskActivityPeriod;
+/**
+ *	Specifies whether or not the ADC data source should be enabled at startup. Defaults to false.
+ */
+	Tango::DevBoolean	enableADC;
+/**
+ *	Default value for the machine time phase. Its valid range is [0, RfSfRatio - 1] where
+ *	RfSfRatio is a machine dependent system property.
+ */
+	Tango::DevLong	defaultTimePhaseValue;
+/**
+ *	The user defined interlock configuration. This is the configuration that should be applied on the Libera in case the device 'finds'
+ *	the Libera in its default startup configuration when it is itself starting up or executing its Init TANGO command. This configuration
+ *	can also be applied using the dedicated 'SetInterlockConfiguration' expert command.
+ *	Parameters mapping:
+ *	[0] Interlock : mode - [0]: disabled, [1]: enabled, [3]: enabled with gain dependency
+ *	[1] Interlock : threshold : X low in mm
+ *	[2] Interlock : threshold : X high in mm
+ *	[3] Interlock : threshold : Z low in mm (i.e. Y low in the Libera terminology)
+ *	[4] Interlock : threshold : Z high in mm (i.e. Y high in the Libera terminology)
+ *	[5] Interlock : overflow limit (ADC threshold)
+ *	[6] Interlock : overflow duration (num of overloaded ADC samples before raising intlck)
+ *	[7] Interlock : gain limit in dBm  (intlck not active under this limit) - valid range is [-60, 0]
+ */
+	vector<FPDataType>	interlockConfiguration;
+/**
+ *	Enables/Disables  DD optional data (IxDD and QxDD)
+ */
+	Tango::DevBoolean	enableDDOptionalData;
+/**
+ *	Enables/disables SA optional Data (currently not used)
+ */
+	Tango::DevBoolean	enableSAOptionalData;
+/**
+ *	Enables/disables SA History optional data (sum history)
+ */
+	Tango::DevBoolean	enableSAHistoryOptionalData;
+/**
+ *	Enables/disables ADC optional data (currently not used)
+ */
+	Tango::DevBoolean	enableADCOptionalData;
+/**
+ *	0: TANGO_INSTITUTE (GENERIC)
+ *	1: ALBA
+ *	2: ESRF
+ *	3: ELETTRA
+ *	4: SOLEIL
+ */
+	Tango::DevShort	institute;
+/**
+ *	Max. DD buffer size when decimation enabled on DD data source.
+ *	Defaults to 10000
+ */
+	Tango::DevLong	maxDDBufferSizeWhenDecimationEnabled;
+/**
+ *	Controls wether or not the BBA offsets are taken into account when computing the offsets passed to the FPGA process
+ */
+	Tango::DevBoolean	passBBAOffsetsToFPGA;
+/**
+ *	The <FA Data> cache refresh period in msecs.
+ *	Defaults to 500 ms (2Hz).
+ */
+	Tango::DevULong	fADataCacheRefreshPeriod;
+//@}
+
+  /**@name Constructors
+   * Miscellaneous constructors */
+  //@{
+  /**
+   * Constructs a newly allocated Command object.
+   *
+   *	@param cl	Class.
+   *	@param s 	Device Name
+   */
+  Libera (Tango::DeviceClass * cl, string & s);
+
+  /**
+   * Constructs a newly allocated Command object.
+   *
+   *	@param cl	Class.
+   *	@param s 	Device Name
+   */
+  Libera (Tango::DeviceClass * cl, const char *s);
+
+  /**
+   * Constructs a newly allocated Command object.
+   *
+   *	@param cl	Class.
+   *	@param s 	Device name
+   *	@param d	Device description.
+   */
+  Libera (Tango::DeviceClass * cl, const char *s, const char *d);
+
+  //@}
+
+  /**@name Destructor
+   * Only one desctructor is defined for this class */
+  //@{
+  /**
+   * The object desctructor.
+   */
+  virtual ~ Libera ()
+  {
+    delete_device ();
+  };
+
+  /**
+   *	will be called at device destruction or at init command.
+   */
+  void delete_device ();
+
+  //@}
+
+  /**@name Miscellaneous methods */
+  //@{
+  /**
+   *	Initialize the device
+   */
+  virtual void init_device ();
+
+  /**
+   *	Always executed method befor execution command method.
+   */
+  virtual void always_executed_hook ();
+
+//@}
+
+/**
+ * @name Libera methods prototypes
+ */
+
+//@{
+/**
+ *	Hardware acquisition for attributes.
+ */
+	virtual void read_attr_hardware(vector<long> &attr_list);
+/**
+ *	Extract real attribute values for LiberaModel acquisition result.
+ */
+	virtual void read_LiberaModel(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for DDEnabled acquisition result.
+ */
+	virtual void read_DDEnabled(Tango::Attribute &attr);
+/**
+ *	Write DDEnabled attribute values to hardware.
+ */
+	virtual void write_DDEnabled(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for DDBufferSize acquisition result.
+ */
+	virtual void read_DDBufferSize(Tango::Attribute &attr);
+/**
+ *	Write DDBufferSize attribute values to hardware.
+ */
+	virtual void write_DDBufferSize(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for DDDecimationFactor acquisition result.
+ */
+	virtual void read_DDDecimationFactor(Tango::Attribute &attr);
+/**
+ *	Write DDDecimationFactor attribute values to hardware.
+ */
+	virtual void write_DDDecimationFactor(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for DDTriggerOffset acquisition result.
+ */
+	virtual void read_DDTriggerOffset(Tango::Attribute &attr);
+/**
+ *	Write DDTriggerOffset attribute values to hardware.
+ */
+	virtual void write_DDTriggerOffset(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for DDBufferFreezingEnabled acquisition result.
+ */
+	virtual void read_DDBufferFreezingEnabled(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for DDBufferFrozen acquisition result.
+ */
+	virtual void read_DDBufferFrozen(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for DDTriggerCounter acquisition result.
+ */
+	virtual void read_DDTriggerCounter(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ExternalTriggerEnabled acquisition result.
+ */
+	virtual void read_ExternalTriggerEnabled(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ExternalTriggerDelay acquisition result.
+ */
+	virtual void read_ExternalTriggerDelay(Tango::Attribute &attr);
+/**
+ *	Write ExternalTriggerDelay attribute values to hardware.
+ */
+	virtual void write_ExternalTriggerDelay(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for SAEnabled acquisition result.
+ */
+	virtual void read_SAEnabled(Tango::Attribute &attr);
+/**
+ *	Write SAEnabled attribute values to hardware.
+ */
+	virtual void write_SAEnabled(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for VaSA acquisition result.
+ */
+	virtual void read_VaSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VbSA acquisition result.
+ */
+	virtual void read_VbSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VcSA acquisition result.
+ */
+	virtual void read_VcSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VdSA acquisition result.
+ */
+	virtual void read_VdSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XPosSA acquisition result.
+ */
+	virtual void read_XPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZPosSA acquisition result.
+ */
+	virtual void read_ZPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SumSA acquisition result.
+ */
+	virtual void read_SumSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QuadSA acquisition result.
+ */
+	virtual void read_QuadSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for CxSA acquisition result.
+ */
+	virtual void read_CxSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for CzSA acquisition result.
+ */
+	virtual void read_CzSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SAStatNumSamples acquisition result.
+ */
+	virtual void read_SAStatNumSamples(Tango::Attribute &attr);
+/**
+ *	Write SAStatNumSamples attribute values to hardware.
+ */
+	virtual void write_SAStatNumSamples(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for XMeanPosSA acquisition result.
+ */
+	virtual void read_XMeanPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZMeanPosSA acquisition result.
+ */
+	virtual void read_ZMeanPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XRMSPosSA acquisition result.
+ */
+	virtual void read_XRMSPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZRMSPosSA acquisition result.
+ */
+	virtual void read_ZRMSPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XPeakPosSA acquisition result.
+ */
+	virtual void read_XPeakPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZPeakPosSA acquisition result.
+ */
+	virtual void read_ZPeakPosSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SumMeanSA acquisition result.
+ */
+	virtual void read_SumMeanSA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ADCEnabled acquisition result.
+ */
+	virtual void read_ADCEnabled(Tango::Attribute &attr);
+/**
+ *	Write ADCEnabled attribute values to hardware.
+ */
+	virtual void write_ADCEnabled(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for ADCBufferSize acquisition result.
+ */
+	virtual void read_ADCBufferSize(Tango::Attribute &attr);
+/**
+ *	Write ADCBufferSize attribute values to hardware.
+ */
+	virtual void write_ADCBufferSize(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for PMOffset acquisition result.
+ */
+	virtual void read_PMOffset(Tango::Attribute &attr);
+/**
+ *	Write PMOffset attribute values to hardware.
+ */
+	virtual void write_PMOffset(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for PMNotified acquisition result.
+ */
+	virtual void read_PMNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for PMNotificationCounter acquisition result.
+ */
+	virtual void read_PMNotificationCounter(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockXNotified acquisition result.
+ */
+	virtual void read_InterlockXNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockZNotified acquisition result.
+ */
+	virtual void read_InterlockZNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockAttnNotified acquisition result.
+ */
+	virtual void read_InterlockAttnNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockADCPreFilterNotified acquisition result.
+ */
+	virtual void read_InterlockADCPreFilterNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockADCPostFilterNotified acquisition result.
+ */
+	virtual void read_InterlockADCPostFilterNotified(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XLow acquisition result.
+ */
+	virtual void read_XLow(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XHigh acquisition result.
+ */
+	virtual void read_XHigh(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZLow acquisition result.
+ */
+	virtual void read_ZLow(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZHigh acquisition result.
+ */
+	virtual void read_ZHigh(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for AutoSwitchingEnabled acquisition result.
+ */
+	virtual void read_AutoSwitchingEnabled(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for Switches acquisition result.
+ */
+	virtual void read_Switches(Tango::Attribute &attr);
+/**
+ *	Write Switches attribute values to hardware.
+ */
+	virtual void write_Switches(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for ExternalSwitching acquisition result.
+ */
+	virtual void read_ExternalSwitching(Tango::Attribute &attr);
+/**
+ *	Write ExternalSwitching attribute values to hardware.
+ */
+	virtual void write_ExternalSwitching(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for SwitchingDelay acquisition result.
+ */
+	virtual void read_SwitchingDelay(Tango::Attribute &attr);
+/**
+ *	Write SwitchingDelay attribute values to hardware.
+ */
+	virtual void write_SwitchingDelay(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for OffsetTune acquisition result.
+ */
+	virtual void read_OffsetTune(Tango::Attribute &attr);
+/**
+ *	Write OffsetTune attribute values to hardware.
+ */
+	virtual void write_OffsetTune(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for CompensateTune acquisition result.
+ */
+	virtual void read_CompensateTune(Tango::Attribute &attr);
+/**
+ *	Write CompensateTune attribute values to hardware.
+ */
+	virtual void write_CompensateTune(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for DSCMode acquisition result.
+ */
+	virtual void read_DSCMode(Tango::Attribute &attr);
+/**
+ *	Write DSCMode attribute values to hardware.
+ */
+	virtual void write_DSCMode(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for AGCEnabled acquisition result.
+ */
+	virtual void read_AGCEnabled(Tango::Attribute &attr);
+/**
+ *	Write AGCEnabled attribute values to hardware.
+ */
+	virtual void write_AGCEnabled(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for Gain acquisition result.
+ */
+	virtual void read_Gain(Tango::Attribute &attr);
+/**
+ *	Write Gain attribute values to hardware.
+ */
+	virtual void write_Gain(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for HasMAFSupport acquisition result.
+ */
+	virtual void read_HasMAFSupport(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for MAFLength acquisition result.
+ */
+	virtual void read_MAFLength(Tango::Attribute &attr);
+/**
+ *	Write MAFLength attribute values to hardware.
+ */
+	virtual void write_MAFLength(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for MAFDelay acquisition result.
+ */
+	virtual void read_MAFDelay(Tango::Attribute &attr);
+/**
+ *	Write MAFDelay attribute values to hardware.
+ */
+	virtual void write_MAFDelay(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for MachineTime acquisition result.
+ */
+	virtual void read_MachineTime(Tango::Attribute &attr);
+/**
+ *	Write MachineTime attribute values to hardware.
+ */
+	virtual void write_MachineTime(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for TimePhase acquisition result.
+ */
+	virtual void read_TimePhase(Tango::Attribute &attr);
+/**
+ *	Write TimePhase attribute values to hardware.
+ */
+	virtual void write_TimePhase(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for SystemTime acquisition result.
+ */
+	virtual void read_SystemTime(Tango::Attribute &attr);
+/**
+ *	Write SystemTime attribute values to hardware.
+ */
+	virtual void write_SystemTime(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for SCPLLStatus acquisition result.
+ */
+	virtual void read_SCPLLStatus(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for MCPLLStatus acquisition result.
+ */
+	virtual void read_MCPLLStatus(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for HWTemperature acquisition result.
+ */
+	virtual void read_HWTemperature(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for Fan1Speed acquisition result.
+ */
+	virtual void read_Fan1Speed(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for Fan2Speed acquisition result.
+ */
+	virtual void read_Fan2Speed(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for Incoherence acquisition result.
+ */
+	virtual void read_Incoherence(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for RefIncoherence acquisition result.
+ */
+	virtual void read_RefIncoherence(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for MaxIncoherence acquisition result.
+ */
+	virtual void read_MaxIncoherence(Tango::Attribute &attr);
+/**
+ *	Write MaxIncoherence attribute values to hardware.
+ */
+	virtual void write_MaxIncoherence(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for MaxIncoherenceDrift acquisition result.
+ */
+	virtual void read_MaxIncoherenceDrift(Tango::Attribute &attr);
+/**
+ *	Write MaxIncoherenceDrift attribute values to hardware.
+ */
+	virtual void write_MaxIncoherenceDrift(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for UpTime acquisition result.
+ */
+	virtual void read_UpTime(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for CpuUsage acquisition result.
+ */
+	virtual void read_CpuUsage(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for FreeMemory acquisition result.
+ */
+	virtual void read_FreeMemory(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for RamFsUsage acquisition result.
+ */
+	virtual void read_RamFsUsage(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for UseLiberaSAData acquisition result.
+ */
+	virtual void read_UseLiberaSAData(Tango::Attribute &attr);
+/**
+ *	Write UseLiberaSAData attribute values to hardware.
+ */
+	virtual void write_UseLiberaSAData(Tango::WAttribute &attr);
+/**
+ *	Extract real attribute values for XPosDD acquisition result.
+ */
+	virtual void read_XPosDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZPosDD acquisition result.
+ */
+	virtual void read_ZPosDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QuadDD acquisition result.
+ */
+	virtual void read_QuadDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SumDD acquisition result.
+ */
+	virtual void read_SumDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VaDD acquisition result.
+ */
+	virtual void read_VaDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VbDD acquisition result.
+ */
+	virtual void read_VbDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VcDD acquisition result.
+ */
+	virtual void read_VcDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VdDD acquisition result.
+ */
+	virtual void read_VdDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XPosSAHistory acquisition result.
+ */
+	virtual void read_XPosSAHistory(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZPosSAHistory acquisition result.
+ */
+	virtual void read_ZPosSAHistory(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SumSAHistory acquisition result.
+ */
+	virtual void read_SumSAHistory(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for XPosPM acquisition result.
+ */
+	virtual void read_XPosPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ZPosPM acquisition result.
+ */
+	virtual void read_ZPosPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QuadPM acquisition result.
+ */
+	virtual void read_QuadPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for SumPM acquisition result.
+ */
+	virtual void read_SumPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VaPM acquisition result.
+ */
+	virtual void read_VaPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VbPM acquisition result.
+ */
+	virtual void read_VbPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VcPM acquisition result.
+ */
+	virtual void read_VcPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for VdPM acquisition result.
+ */
+	virtual void read_VdPM(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ADCChannelA acquisition result.
+ */
+	virtual void read_ADCChannelA(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ADCChannelB acquisition result.
+ */
+	virtual void read_ADCChannelB(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ADCChannelC acquisition result.
+ */
+	virtual void read_ADCChannelC(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for ADCChannelD acquisition result.
+ */
+	virtual void read_ADCChannelD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for IaDD acquisition result.
+ */
+	virtual void read_IaDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for IbDD acquisition result.
+ */
+	virtual void read_IbDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for IcDD acquisition result.
+ */
+	virtual void read_IcDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for IdDD acquisition result.
+ */
+	virtual void read_IdDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QaDD acquisition result.
+ */
+	virtual void read_QaDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QbDD acquisition result.
+ */
+	virtual void read_QbDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QcDD acquisition result.
+ */
+	virtual void read_QcDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for QdDD acquisition result.
+ */
+	virtual void read_QdDD(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for UserData acquisition result.
+ */
+	virtual void read_UserData(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for InterlockConfiguration acquisition result.
+ */
+	virtual void read_InterlockConfiguration(Tango::Attribute &attr);
+/**
+ *	Extract real attribute values for logs acquisition result.
+ */
+	virtual void read_logs(Tango::Attribute &attr);
+/**
+ *	Read/Write allowed for LiberaModel attribute.
+ */
+	virtual bool is_LiberaModel_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDEnabled attribute.
+ */
+	virtual bool is_DDEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDBufferSize attribute.
+ */
+	virtual bool is_DDBufferSize_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDDecimationFactor attribute.
+ */
+	virtual bool is_DDDecimationFactor_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDTriggerOffset attribute.
+ */
+	virtual bool is_DDTriggerOffset_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDBufferFreezingEnabled attribute.
+ */
+	virtual bool is_DDBufferFreezingEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDBufferFrozen attribute.
+ */
+	virtual bool is_DDBufferFrozen_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DDTriggerCounter attribute.
+ */
+	virtual bool is_DDTriggerCounter_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ExternalTriggerEnabled attribute.
+ */
+	virtual bool is_ExternalTriggerEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ExternalTriggerDelay attribute.
+ */
+	virtual bool is_ExternalTriggerDelay_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SAEnabled attribute.
+ */
+	virtual bool is_SAEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VaSA attribute.
+ */
+	virtual bool is_VaSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VbSA attribute.
+ */
+	virtual bool is_VbSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VcSA attribute.
+ */
+	virtual bool is_VcSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VdSA attribute.
+ */
+	virtual bool is_VdSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XPosSA attribute.
+ */
+	virtual bool is_XPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZPosSA attribute.
+ */
+	virtual bool is_ZPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SumSA attribute.
+ */
+	virtual bool is_SumSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QuadSA attribute.
+ */
+	virtual bool is_QuadSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for CxSA attribute.
+ */
+	virtual bool is_CxSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for CzSA attribute.
+ */
+	virtual bool is_CzSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SAStatNumSamples attribute.
+ */
+	virtual bool is_SAStatNumSamples_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XMeanPosSA attribute.
+ */
+	virtual bool is_XMeanPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZMeanPosSA attribute.
+ */
+	virtual bool is_ZMeanPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XRMSPosSA attribute.
+ */
+	virtual bool is_XRMSPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZRMSPosSA attribute.
+ */
+	virtual bool is_ZRMSPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XPeakPosSA attribute.
+ */
+	virtual bool is_XPeakPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZPeakPosSA attribute.
+ */
+	virtual bool is_ZPeakPosSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SumMeanSA attribute.
+ */
+	virtual bool is_SumMeanSA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCEnabled attribute.
+ */
+	virtual bool is_ADCEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCBufferSize attribute.
+ */
+	virtual bool is_ADCBufferSize_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for PMOffset attribute.
+ */
+	virtual bool is_PMOffset_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for PMNotified attribute.
+ */
+	virtual bool is_PMNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for PMNotificationCounter attribute.
+ */
+	virtual bool is_PMNotificationCounter_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockXNotified attribute.
+ */
+	virtual bool is_InterlockXNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockZNotified attribute.
+ */
+	virtual bool is_InterlockZNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockAttnNotified attribute.
+ */
+	virtual bool is_InterlockAttnNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockADCPreFilterNotified attribute.
+ */
+	virtual bool is_InterlockADCPreFilterNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockADCPostFilterNotified attribute.
+ */
+	virtual bool is_InterlockADCPostFilterNotified_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XLow attribute.
+ */
+	virtual bool is_XLow_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XHigh attribute.
+ */
+	virtual bool is_XHigh_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZLow attribute.
+ */
+	virtual bool is_ZLow_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZHigh attribute.
+ */
+	virtual bool is_ZHigh_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for AutoSwitchingEnabled attribute.
+ */
+	virtual bool is_AutoSwitchingEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for Switches attribute.
+ */
+	virtual bool is_Switches_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ExternalSwitching attribute.
+ */
+	virtual bool is_ExternalSwitching_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SwitchingDelay attribute.
+ */
+	virtual bool is_SwitchingDelay_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for OffsetTune attribute.
+ */
+	virtual bool is_OffsetTune_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for CompensateTune attribute.
+ */
+	virtual bool is_CompensateTune_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for DSCMode attribute.
+ */
+	virtual bool is_DSCMode_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for AGCEnabled attribute.
+ */
+	virtual bool is_AGCEnabled_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for Gain attribute.
+ */
+	virtual bool is_Gain_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for HasMAFSupport attribute.
+ */
+	virtual bool is_HasMAFSupport_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MAFLength attribute.
+ */
+	virtual bool is_MAFLength_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MAFDelay attribute.
+ */
+	virtual bool is_MAFDelay_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MachineTime attribute.
+ */
+	virtual bool is_MachineTime_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for TimePhase attribute.
+ */
+	virtual bool is_TimePhase_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SystemTime attribute.
+ */
+	virtual bool is_SystemTime_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SCPLLStatus attribute.
+ */
+	virtual bool is_SCPLLStatus_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MCPLLStatus attribute.
+ */
+	virtual bool is_MCPLLStatus_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for HWTemperature attribute.
+ */
+	virtual bool is_HWTemperature_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for Fan1Speed attribute.
+ */
+	virtual bool is_Fan1Speed_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for Fan2Speed attribute.
+ */
+	virtual bool is_Fan2Speed_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for Incoherence attribute.
+ */
+	virtual bool is_Incoherence_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for RefIncoherence attribute.
+ */
+	virtual bool is_RefIncoherence_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MaxIncoherence attribute.
+ */
+	virtual bool is_MaxIncoherence_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for MaxIncoherenceDrift attribute.
+ */
+	virtual bool is_MaxIncoherenceDrift_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for UpTime attribute.
+ */
+	virtual bool is_UpTime_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for CpuUsage attribute.
+ */
+	virtual bool is_CpuUsage_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for FreeMemory attribute.
+ */
+	virtual bool is_FreeMemory_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for RamFsUsage attribute.
+ */
+	virtual bool is_RamFsUsage_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for UseLiberaSAData attribute.
+ */
+	virtual bool is_UseLiberaSAData_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XPosDD attribute.
+ */
+	virtual bool is_XPosDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZPosDD attribute.
+ */
+	virtual bool is_ZPosDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QuadDD attribute.
+ */
+	virtual bool is_QuadDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SumDD attribute.
+ */
+	virtual bool is_SumDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VaDD attribute.
+ */
+	virtual bool is_VaDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VbDD attribute.
+ */
+	virtual bool is_VbDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VcDD attribute.
+ */
+	virtual bool is_VcDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VdDD attribute.
+ */
+	virtual bool is_VdDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XPosSAHistory attribute.
+ */
+	virtual bool is_XPosSAHistory_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZPosSAHistory attribute.
+ */
+	virtual bool is_ZPosSAHistory_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SumSAHistory attribute.
+ */
+	virtual bool is_SumSAHistory_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for XPosPM attribute.
+ */
+	virtual bool is_XPosPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ZPosPM attribute.
+ */
+	virtual bool is_ZPosPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QuadPM attribute.
+ */
+	virtual bool is_QuadPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for SumPM attribute.
+ */
+	virtual bool is_SumPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VaPM attribute.
+ */
+	virtual bool is_VaPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VbPM attribute.
+ */
+	virtual bool is_VbPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VcPM attribute.
+ */
+	virtual bool is_VcPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for VdPM attribute.
+ */
+	virtual bool is_VdPM_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCChannelA attribute.
+ */
+	virtual bool is_ADCChannelA_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCChannelB attribute.
+ */
+	virtual bool is_ADCChannelB_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCChannelC attribute.
+ */
+	virtual bool is_ADCChannelC_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for ADCChannelD attribute.
+ */
+	virtual bool is_ADCChannelD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for IaDD attribute.
+ */
+	virtual bool is_IaDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for IbDD attribute.
+ */
+	virtual bool is_IbDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for IcDD attribute.
+ */
+	virtual bool is_IcDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for IdDD attribute.
+ */
+	virtual bool is_IdDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QaDD attribute.
+ */
+	virtual bool is_QaDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QbDD attribute.
+ */
+	virtual bool is_QbDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QcDD attribute.
+ */
+	virtual bool is_QcDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for QdDD attribute.
+ */
+	virtual bool is_QdDD_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for UserData attribute.
+ */
+	virtual bool is_UserData_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for InterlockConfiguration attribute.
+ */
+	virtual bool is_InterlockConfiguration_allowed(Tango::AttReqType type);
+/**
+ *	Read/Write allowed for logs attribute.
+ */
+	virtual bool is_logs_allowed(Tango::AttReqType type);
+/**
+ *	Execution allowed for GetParameters command.
+ */
+	virtual bool is_GetParameters_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for UnfreezeDDBuffer command.
+ */
+	virtual bool is_UnfreezeDDBuffer_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for EnableDDBufferFreezing command.
+ */
+	virtual bool is_EnableDDBufferFreezing_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for DisableDDBufferFreezing command.
+ */
+	virtual bool is_DisableDDBufferFreezing_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for EnableDD command.
+ */
+	virtual bool is_EnableDD_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for DisableDD command.
+ */
+	virtual bool is_DisableDD_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for EnableSA command.
+ */
+	virtual bool is_EnableSA_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for DisableSA command.
+ */
+	virtual bool is_DisableSA_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for ResetPMNotification command.
+ */
+	virtual bool is_ResetPMNotification_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for ResetInterlockNotification command.
+ */
+	virtual bool is_ResetInterlockNotification_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for SetInterlockConfiguration command.
+ */
+	virtual bool is_SetInterlockConfiguration_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for EnableADC command.
+ */
+	virtual bool is_EnableADC_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for DisableADC command.
+ */
+	virtual bool is_DisableADC_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for SetTimeOnNextTrigger command.
+ */
+	virtual bool is_SetTimeOnNextTrigger_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for ReadFAData command.
+ */
+	virtual bool is_ReadFAData_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for WriteFAData command.
+ */
+	virtual bool is_WriteFAData_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for SaveDSCParameters command.
+ */
+	virtual bool is_SaveDSCParameters_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for ReloadSystemProperties command.
+ */
+	virtual bool is_ReloadSystemProperties_allowed(const CORBA::Any &any);
+/**
+ *	Execution allowed for SetRefIncoherence command.
+ */
+	virtual bool is_SetRefIncoherence_allowed(const CORBA::Any &any);
+/**
+ * This command gets the device state (stored in its <i>device_state</i> data member) and returns it to the caller.
+ *	@return	State Code
+ *	@exception DevFailed
+ */
+	virtual Tango::DevState	dev_state();
+/**
+ * This command gets the device status (stored in its <i>device_status</i> data member) and returns it to the caller.
+ *	@return	Status description
+ *	@exception DevFailed
+ */
+	virtual Tango::ConstDevString	dev_status();
+/**
+ * Retruns the current gains and offsets (i.e. the parameters used for position computation)
+ *	@return	The BPM gain and offsets
+ *	@exception DevFailed
+ */
+	Tango::DevVarDoubleStringArray	*get_parameters();
+/**
+ * Unfreezes the DD buffer
+ *	@exception DevFailed
+ */
+	void	unfreeze_ddbuffer();
+/**
+ * Enables the DD buffer freezing mechanism
+ *	@exception DevFailed
+ */
+	void	enable_ddbuffer_freezing();
+/**
+ * Disables the DD buffer freezing mechanism
+ *	@exception DevFailed
+ */
+	void	disable_ddbuffer_freezing();
+/**
+ * Enables the so called "data on demand" (i.e. first turns) data source
+ *	@exception DevFailed
+ */
+	void	enable_dd();
+/**
+ * Disables the so called "data on demand" (i.e. first turns) data source
+ *	@exception DevFailed
+ */
+	void	disable_dd();
+/**
+ * Enables the so called "slow acquisition" data source
+ *	@exception DevFailed
+ */
+	void	enable_sa();
+/**
+ * Disables the so called "slow acquisition" data source
+ *	@exception DevFailed
+ */
+	void	disable_sa();
+/**
+ * 
+ *	@exception DevFailed
+ */
+	void	reset_pmnotification();
+/**
+ * Resets the interlock notification flags to false
+ *	@exception DevFailed
+ */
+	void	reset_interlock_notification();
+/**
+ * Change interlock configuration using the InterlockConfiguration class (or device) property.
+ *	Only  modify  the interlock configuration, the remaining env. parameters remain unchanged.
+ *	@exception DevFailed
+ */
+	void	set_interlock_configuration();
+/**
+ * Enables the so called ADC data source
+ *	@exception DevFailed
+ */
+	void	enable_adc();
+/**
+ * Disables the so called ADC data source
+ *	@exception DevFailed
+ */
+	void	disable_adc();
+/**
+ * Applies both machine et system time values on next trigger
+ *	@exception DevFailed
+ */
+	void	set_time_on_next_trigger();
+/**
+ * Statring from[offest] in FA data block, reads [size of elems] * [num of elems] bytes.
+ *	@param	argin	The reading parameters: [0]:offset in FA data block, [1]:size of elems, [2]:num of elems
+ *	@return	The data [as an array of bytes]
+ *	@exception DevFailed
+ */
+	Tango::DevVarLongArray	*read_fadata(const Tango::DevVarLongArray *);
+/**
+ * Starting from [offset] in Fa data block, writes [size of elems * num of elems].
+ *	The actual data to be written starts at index [4] in the input array.
+ *	@param	argin	The writting parameters: [0]:offset in FA data block, bytes[1]:size of elems, [2]:num of elems, [3, ...]: actual to data to be written
+ *	@exception DevFailed
+ */
+	void	write_fadata(const Tango::DevVarLongArray *);
+/**
+ * Saves the current DSC parameters
+ *	@exception DevFailed
+ */
+	void	save_dscparameters();
+/**
+ * 
+ *	@exception DevFailed
+ */
+	void	reload_system_properties();
+/**
+ * Set the actual incoherence value as refeference value for the drift alarm calculation.
+ *	@exception DevFailed
+ */
+	void	set_ref_incoherence();
+
+/**
+ *	Read the device properties from database
+ */
+	 void get_device_property();
+//@}
+
+  //  Here is the end of the automatic code generation part
+  //-------------------------------------------------------------
+protected:
+  //  Add your own data members here
+  //-----------------------------------------
+
+  //- changes the interlock config from the UserDefinedStartupEnvParameters property
+  void set_interlock_config_from_property();
+
+  //- true if (at least) a critical device property is missing, false otherwise
+  bool critical_properties_missing;
+
+  //- underlying Libera hardware
+  BPM * bpm_hw;
+
+  //- the BPM DD data (data on demand)
+  DDData * dd_data;
+
+  //- the BPM ADC data (adc values)
+  ADCData * adc_data;
+  
+  //- the BPM SA data (slow acquisition)
+  SAData * sa_data;
+  
+  //- the BPM PM data (post mortem)
+  DDData * pm_data;
+  
+  //- dd activation flag
+  bool dd_enabled;
+
+  //- sa activation flag
+  bool sa_enabled;
+
+  //- adc activation flag
+  bool adc_enabled;
+  
+  //- the trigger_counter
+  long trigger_counter;
+
+  //- DD (i.e. turn-by-turn) cache status
+  bool dd_cache_enabled;
+  bool dd_cache_frozen;
+
+  //- external trigger status
+  bool external_trigger_enabled;
+
+  //- bpm location
+  BPMLocation bpm_location;
+
+  //- count device instances in order to prevent more than one device
+  //- to be instanciated into the same process (not 100% thread safe
+  //- due to asynch notification mechanism)
+  static int instance_counter;
+  
+  //- pos threshold (for interlock)
+  FPDataType x_lo;
+  FPDataType x_hi;
+  FPDataType z_lo;
+  FPDataType z_hi;
+  
+  //- dd buffer offset
+  Tango::DevLong dd_buffer_offset;
+  
+  //- pm stuffs
+  bool pm_notified;
+  short pm_event_counter;
+  
+  //- interlock status
+  bool intl_x_notified;
+  bool intl_z_notified;
+  bool intl_attn_notified;
+  bool intl_adc_pre_filter_notified;
+  bool intl_adc_post_filter_notified;
+  
+  //- auto switching enabled
+  bool auto_switching_enabled;
+  
+  //- AGC enabled
+  bool agc_enabled;
+  
+  //- using SA pos data from FPGA?
+  bool using_fpga_sa_pos;
+  
+  //- cuurent input gain
+  FPDataType gain;
+  
+  //- storage for current Interlock configuration
+  FPDataType ilk_config[kILK_NUM_PARAMS];
+  
+  //- SA pos. statistics
+  FPDataType sa_x_mean;
+  FPDataType sa_z_mean;
+  FPDataType sa_s_mean;
+  FPDataType sa_x_rms;
+  FPDataType sa_z_rms;
+  FPDataType sa_x_peak;
+  FPDataType sa_z_peak;
+  
+  //- time: MT, ST and phase
+  FPDataType mt;
+  FPDataType st;
+  Tango::DevLong tp;
+  
+  //- DSC mode
+  short dsc_mode;
+  
+  //- BPM hardware status
+  bpm::BPM::BPMHwStatus bpm_hw_status;
+  
+  //- the Rf/Sf ratio (machine dependent)
+  FPDataType rf_sf_ratio; 
+  
+  // ADC source switching
+  bool external_switching_enabled;
+  Tango::DevLong switching_delay;
+  
+  // Compensation tune (mtvcxoff and mtncoshft)
+  bool tune_compensation_enabled;
+  Tango::DevLong tune_offset;
+  
+  // External trigger delay
+  Tango::DevLong external_trigger_delay;
+  
+  // Post mortem offset
+  Tango::DevLong pm_offset;
+  
+  // Moving average filter length and delay
+  Tango::DevLong maf_length;
+  Tango::DevLong maf_delay;
+  Tango::DevBoolean maf_support;
+  
+	// Incoherence value 
+	FPDataType incoherence;
+	
+	// Reference and alarm configuration values for the incoherence alarm
+	FPDataType ref_incoherence;
+	FPDataType max_incoherence;
+	FPDataType max_drift_incoherence;
+  bool incoherence_out_of_range ();
+
+  //- dynamic attributes repository
+  DynamicAttrHelper dyn_attrs;
+  
+  //- logging trick (tanks Julien)
+  InnerAppender * m_appender;
+  InnerAppender::LogList m_logs;
+  Tango::DevVarStringArray m_logs_array;
+};
+
+} // namespace
+
+
+#endif // _LIBERA_H
diff --git a/src/LiberaClass.cpp b/src/LiberaClass.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..812d94b4e88f644e9c0846c90272aaeeaf3fa537
--- /dev/null
+++ b/src/LiberaClass.cpp
@@ -0,0 +1,2800 @@
+static const char *ClassId    = "$Id: $";
+static const char *CvsPath    = "$Source: $";
+static const char *SvnPath    = "$HeadURL: $";
+static const char *RcsId = "$Header: /cvsroot/tango-ds/BeamDiag/bpm_libera/src/LiberaClass.cpp,v 1.4.2.30.2.1 2008/05/25 13:21:42 nleclercq Exp $";
+static const char *TagName = "$Name:  $";
+static const char *FileName = "$Source: /cvsroot/tango-ds/BeamDiag/bpm_libera/src/LiberaClass.cpp,v $";
+static const char *HttpServer = "http://controle/DeviceServer/doc/";
+static const char *RCSfile = "$RCSfile: LiberaClass.cpp,v $";
+//+=============================================================================
+//
+// file :        LiberaClass.cpp
+//
+// description : C++ source for the LiberaClass. A singleton
+//               class derived from DeviceClass. It implements the
+//               command list and all properties and methods required
+//               by the Libera once per process.
+//
+// project :     TANGO Device Server
+//
+// $Author: nleclercq $
+//
+// $Revision: 1.4.2.30.2.1 $ 
+// 
+// $Log: LiberaClass.cpp,v $
+// Revision 1.4.2.30.2.1  2008/05/25 13:21:42  nleclercq
+// Enhanced embedded device support
+// Reorganized src tree
+// Complete rewrite of threading support (code extracted from NL & JM YAT lib)
+// Add DD buffer freezing support for embedded device
+// Added BPMSensors class (CPU & Memory uage)
+// Misc. minor changes
+//
+// Revision 1.4.2.30  2008/03/21 15:04:46  nleclercq
+// Fixed a pb in PM data handling
+// Added a UserData vector attribute
+// Removed individual user data atrributes
+//
+// Revision 1.4.2.29  2008/02/29 08:48:31  nleclercq
+// Upated to cpsi 1.60
+// Added FOFB attributes
+//
+// Revision 1.4.2.28  2008/02/28 16:20:52  nleclercq
+// Upated to cpsi 1.60
+// Added FOFB attributes
+//
+// Revision 1.4.2.27  2008/02/28 15:07:43  nleclercq
+// Minor change
+//
+// Revision 1.4.2.26  2007/06/27 15:05:33  nleclercq
+// no message
+//
+// Revision 1.4.2.25  2007/06/04 15:27:48  nleclercq
+// Changed Read/Write FA data (long)
+// Changed default PM array size (no data)
+//
+// Revision 1.4.2.24  2007/04/19 14:56:43  nleclercq
+// Fixed bug in Read/Write FA data
+// Added more interlock support
+//
+// Revision 1.4.2.23  2007/03/28 11:17:53  nleclercq
+// Added cspi-1.42 support (cpsi_seek)
+// Fixed a bug in ADC buffer size reading
+//
+// Revision 1.4.2.22  2007/02/27 15:13:28  nleclercq
+// Changed internal message handling
+// Added ReloadSystemProperties
+//
+// Revision 1.4.2.21  2007/02/12 17:33:07  nleclercq
+// Modified the "embdded" specific code
+//
+// Revision 1.4.2.20  2007/01/25 13:41:41  nleclercq
+// Added fixed some small bugs
+// Added support FP data type selection at compile time.
+//
+// Revision 1.4.2.19  2007/01/23 09:51:34  nleclercq
+// Added support for FA block read/write
+//
+// Revision 1.4.2.18  2007/01/17 15:28:08  nleclercq
+// Fixed some bugs - commit for pre-release 1.40
+//
+// Revision 1.4.2.17  2007/01/16 14:46:27  nleclercq
+// Added (almost full) cspi-1.40 support
+//
+// Revision 1.4.2.16  2007/01/12 10:15:12  nleclercq
+// First commit for cspi-1.40 support
+//
+// Revision 1.4.2.15  2006/11/30 14:43:52  nleclercq
+// Added support for cspi 1.22
+// Added support for ADC data source
+// Added set time (system and machine times)
+// Removed BBA offset component for FPGA pos. computation
+//
+// Revision 1.4.2.14  2006/09/21 16:10:35  nleclercq
+// Minor changes
+// Fixed some attribute default properties
+//
+// Revision 1.4.2.13  2006/09/18 13:07:42  nleclercq
+// Added suport for cspi 1.21
+//
+// Revision 1.4.2.12  2006/06/19 14:24:40  nleclercq
+// Sync with SOLEIL prod version
+//
+// Revision 1.5  2006/06/13 12:33:14  nleclercq
+// Added support for CSPI 1.03
+//
+// Revision 1.4.2.10  2006/06/07 08:00:33  nleclercq
+// Sync with SOLEIL prod. version
+//
+// Revision 1.4.2.8  2006/04/28 14:17:56  nleclercq
+// Changed DDenabled and SAEnabled to READ_WRITE
+// Renamed attr PMNotifed to PMNotified
+// No more exception raised when no data available - invalid attr values are returned instead (contain NAN)
+//
+// Revision 1.4.2.7  2006/04/25 08:45:34  nleclercq
+// Fixed switches, attenuators and decimation factor problems
+//
+// Revision 1.4.2.6  2006/03/27 16:52:52  nleclercq
+// Added switches attr, fixed a bug in SA history management.
+//
+// Revision 1.4.2.5  2006/03/23 09:42:29  nleclercq
+// Several minor bugs fixes
+//
+// Revision 1.4.2.4  2006/03/20 15:33:28  nleclercq
+// Added cspi 1.02 support
+// Added PM support
+//
+// Revision 1.4.2.3  2006/03/20 15:01:47  nleclercq
+// Restored all src files
+//
+// Revision 1.4  2005/10/20 08:27:08  nleclercq
+// Fixed bug in the doc. Added new features
+//
+// Revision 1.3  2005/09/26 16:42:37  nleclercq
+// Added attributes to the device interface (Libera cache status)
+//
+// Revision 1.2  2005/08/02 16:02:19  nleclercq
+// Sync with code deploy at SOLEILa.u.
+//
+//
+// copyleft :     Synchrotron SOLEIL
+//                L'Orme des Merisiers
+//                Saint-Aubin - BP 48
+//
+//-=============================================================================
+//
+//      This file is generated by POGO
+//  (Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+
+#include <tango.h>
+
+#include <Libera.h>
+#include <LiberaClass.h>
+
+
+namespace Libera_ns
+{
+//+----------------------------------------------------------------------------
+//
+// method : 		SetRefIncoherenceCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *SetRefIncoherenceCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "SetRefIncoherenceCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->set_ref_incoherence());
+	return new CORBA::Any();
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		ReloadSystemPropertiesCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *ReloadSystemPropertiesCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "ReloadSystemPropertiesCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->reload_system_properties());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		SaveDSCParametersCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *SaveDSCParametersCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "SaveDSCParametersCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->save_dscparameters());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		WriteFADataCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *WriteFADataCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "WriteFADataCmd::execute(): arrived" << endl;
+
+	const Tango::DevVarLongArray	*argin;
+	extract(in_any, argin);
+
+	((static_cast<Libera *>(device))->write_fadata(argin));
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		ReadFADataCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *ReadFADataCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "ReadFADataCmd::execute(): arrived" << endl;
+
+	const Tango::DevVarLongArray	*argin;
+	extract(in_any, argin);
+
+	return insert((static_cast<Libera *>(device))->read_fadata(argin));
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		SetTimeOnNextTriggerCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *SetTimeOnNextTriggerCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "SetTimeOnNextTriggerCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->set_time_on_next_trigger());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		DisableADCCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *DisableADCCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "DisableADCCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->disable_adc());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		EnableADCCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *EnableADCCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "EnableADCCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->enable_adc());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		SetInterlockConfigurationCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *SetInterlockConfigurationCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "SetInterlockConfigurationCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->set_interlock_configuration());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		ResetPMNotificationCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *ResetPMNotificationCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "ResetPMNotificationCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->reset_pmnotification());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		ResetInterlockNotificationCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *ResetInterlockNotificationCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "ResetInterlockNotificationCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->reset_interlock_notification());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		EnableSACmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *EnableSACmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "EnableSACmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->enable_sa());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		EnableDDCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *EnableDDCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "EnableDDCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->enable_dd());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		DisableDDBufferFreezingCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *DisableDDBufferFreezingCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "DisableDDBufferFreezingCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->disable_ddbuffer_freezing());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		EnableDDBufferFreezingCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *EnableDDBufferFreezingCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "EnableDDBufferFreezingCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->enable_ddbuffer_freezing());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		UnfreezeDDBufferCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *UnfreezeDDBufferCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "UnfreezeDDBufferCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->unfreeze_ddbuffer());
+	return new CORBA::Any();
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		GetParametersCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *GetParametersCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "GetParametersCmd::execute(): arrived" << endl;
+
+	return insert((static_cast<Libera *>(device))->get_parameters());
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		DisableSACmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *DisableSACmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "DisableSACmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->disable_sa());
+	return new CORBA::Any();
+}
+
+
+//+----------------------------------------------------------------------------
+//
+// method : 		DisableDDCmd::execute()
+// 
+// description : 	method to trigger the execution of the command.
+//                PLEASE DO NOT MODIFY this method core without pogo   
+//
+// in : - device : The device on which the command must be excuted
+//		- in_any : The command input data
+//
+// returns : The command output data (packed in the Any object)
+//
+//-----------------------------------------------------------------------------
+CORBA::Any *DisableDDCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any)
+{
+
+	cout2 << "DisableDDCmd::execute(): arrived" << endl;
+
+	((static_cast<Libera *>(device))->disable_dd());
+	return new CORBA::Any();
+}
+
+//
+//----------------------------------------------------------------
+//	Initialize pointer for singleton pattern
+//----------------------------------------------------------------
+//
+LiberaClass *LiberaClass::_instance = NULL;
+
+//+----------------------------------------------------------------------------
+//
+// method :     LiberaClass::LiberaClass(string &s)
+//
+// description :  constructor for the LiberaClass
+//
+// in : - s : The class name
+//
+//-----------------------------------------------------------------------------
+LiberaClass::LiberaClass(string &s):Tango::DeviceClass(s)
+{
+  cout2 << "Entering LiberaClass constructor" << endl;
+	get_class_property();
+
+	set_default_property();
+	write_class_property();
+  write_class_property ();
+
+  cout2 << "Leaving LiberaClass constructor" << endl;
+}
+//+----------------------------------------------------------------------------
+//
+// method :     LiberaClass::~LiberaClass()
+//
+// description :  destructor for the LiberaClass
+//
+//-----------------------------------------------------------------------------
+LiberaClass::~LiberaClass()
+{
+  _instance = NULL;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::instance
+// 
+// description : 	Create the object if not already done. Otherwise, just
+//			return a pointer to the object
+//
+// in : - name : The class name
+//
+//-----------------------------------------------------------------------------
+LiberaClass *LiberaClass::init(const char *name)
+{
+	if (_instance == NULL)
+	{
+		try
+		{
+			string s(name);
+			_instance = new LiberaClass(s);
+		}
+		catch (bad_alloc)
+		{
+			throw;
+		}		
+	}		
+	return _instance;
+}
+
+LiberaClass *LiberaClass::instance()
+{
+	if (_instance == NULL)
+	{
+		cerr << "Class is not initialised !!" << endl;
+		exit(-1);
+	}
+	return _instance;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::command_factory
+// 
+// description : 	Create the command object(s) and store them in the 
+//			command list
+//
+//-----------------------------------------------------------------------------
+void LiberaClass::command_factory()
+{
+	command_list.push_back(new GetParametersCmd("GetParameters",
+		Tango::DEV_VOID, Tango::DEVVAR_DOUBLESTRINGARRAY,
+		"N/A",
+		"The BPM gain and offsets",
+		Tango::OPERATOR));
+	command_list.push_back(new UnfreezeDDBufferCmd("UnfreezeDDBuffer",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new EnableDDBufferFreezingCmd("EnableDDBufferFreezing",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new DisableDDBufferFreezingCmd("DisableDDBufferFreezing",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new EnableDDCmd("EnableDD",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new DisableDDCmd("DisableDD",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new EnableSACmd("EnableSA",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new DisableSACmd("DisableSA",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new ResetPMNotificationCmd("ResetPMNotification",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new ResetInterlockNotificationCmd("ResetInterlockNotification",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new SetInterlockConfigurationCmd("SetInterlockConfiguration",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new EnableADCCmd("EnableADC",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new DisableADCCmd("DisableADC",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new SetTimeOnNextTriggerCmd("SetTimeOnNextTrigger",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+	command_list.push_back(new ReadFADataCmd("ReadFAData",
+		Tango::DEVVAR_LONGARRAY, Tango::DEVVAR_LONGARRAY,
+		"The reading parameters: [0]:offset in FA data block, [1]:size of elems, [2]:num of elems",
+		"The data [as an array of bytes]",
+		Tango::OPERATOR));
+	command_list.push_back(new WriteFADataCmd("WriteFAData",
+		Tango::DEVVAR_LONGARRAY, Tango::DEV_VOID,
+		"The writting parameters: [0]:offset in FA data block, bytes[1]:size of elems, [2]:num of elems, [3, ...]: actual to data to be written",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new SaveDSCParametersCmd("SaveDSCParameters",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new ReloadSystemPropertiesCmd("ReloadSystemProperties",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"n/a",
+		"n/a",
+		Tango::OPERATOR));
+	command_list.push_back(new SetRefIncoherenceCmd("SetRefIncoherence",
+		Tango::DEV_VOID, Tango::DEV_VOID,
+		"",
+		"",
+		Tango::OPERATOR));
+
+	//	add polling if any
+	for (unsigned int i=0 ; i<command_list.size(); i++)
+	{
+	}
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::get_class_property
+// 
+// description : 	Get the class property for specified name.
+//
+// in :		string	name : The property name
+//
+//+----------------------------------------------------------------------------
+Tango::DbDatum LiberaClass::get_class_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<cl_prop.size() ; i++)
+		if (cl_prop[i].name == prop_name)
+			return cl_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::get_default_device_property()
+// 
+// description : 	Return the default value for device property.
+//
+//-----------------------------------------------------------------------------
+Tango::DbDatum LiberaClass::get_default_device_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<dev_def_prop.size() ; i++)
+		if (dev_def_prop[i].name == prop_name)
+			return dev_def_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::get_default_class_property()
+// 
+// description : 	Return the default value for class property.
+//
+//-----------------------------------------------------------------------------
+Tango::DbDatum LiberaClass::get_default_class_property(string &prop_name)
+{
+	for (unsigned int i=0 ; i<cl_def_prop.size() ; i++)
+		if (cl_def_prop[i].name == prop_name)
+			return cl_def_prop[i];
+	//	if not found, return  an empty DbDatum
+	return Tango::DbDatum(prop_name);
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::device_factory
+// 
+// description : 	Create the device object(s) and store them in the 
+//			device list
+//
+// in :		Tango::DevVarStringArray *devlist_ptr : The device name list
+//
+//-----------------------------------------------------------------------------
+void LiberaClass::device_factory(const Tango::DevVarStringArray *devlist_ptr)
+{
+
+	//	Create all devices.(Automatic code generation)
+	//-------------------------------------------------------------
+	for (unsigned long i=0 ; i < devlist_ptr->length() ; i++)
+	{
+		cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl;
+						
+		// Create devices and add it into the device list
+		//----------------------------------------------------
+		device_list.push_back(new Libera(this, (*devlist_ptr)[i]));							 
+
+		// Export device to the outside world
+		// Check before if database used.
+		//---------------------------------------------
+		if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false))
+			export_device(device_list.back());
+		else
+			export_device(device_list.back(), (*devlist_ptr)[i]);
+	}
+	//	End of Automatic code generation
+	//-------------------------------------------------------------
+
+}
+//+----------------------------------------------------------------------------
+//	Method: LiberaClass::attribute_factory(vector<Tango::Attr *> &att_list)
+//-----------------------------------------------------------------------------
+void LiberaClass::attribute_factory(vector<Tango::Attr *> &att_list)
+{
+	//	Attribute : LiberaModel
+	LiberaModelAttrib	*libera_model = new LiberaModelAttrib();
+	Tango::UserDefaultAttrProp	libera_model_prop;
+	libera_model_prop.set_label("Libera Model");
+	libera_model_prop.set_unit("[0:e-, 1:br, 2:ph]");
+	libera_model_prop.set_format("%d");
+	libera_model_prop.set_description("The Libera Model: 0:Electron, 1:Brillance, 2:Photon");
+	libera_model->set_default_properties(libera_model_prop);
+	att_list.push_back(libera_model);
+
+	//	Attribute : DDEnabled
+	DDEnabledAttrib	*ddenabled = new DDEnabledAttrib();
+	Tango::UserDefaultAttrProp	ddenabled_prop;
+	ddenabled_prop.set_label("DD Enabled");
+	ddenabled_prop.set_unit("n/a");
+	ddenabled_prop.set_standard_unit("n/a");
+	ddenabled_prop.set_display_unit("n/a");
+	ddenabled_prop.set_description("DD data source activation flag");
+	ddenabled->set_default_properties(ddenabled_prop);
+	ddenabled->set_memorized();
+	ddenabled->set_memorized_init(true);
+	att_list.push_back(ddenabled);
+
+	//	Attribute : DDBufferSize
+	DDBufferSizeAttrib	*ddbuffer_size = new DDBufferSizeAttrib();
+	Tango::UserDefaultAttrProp	ddbuffer_size_prop;
+	ddbuffer_size_prop.set_label("DD Buffer Size");
+	ddbuffer_size_prop.set_unit("turns");
+	ddbuffer_size_prop.set_format("%5d");
+	ddbuffer_size_prop.set_max_value("65535");
+	ddbuffer_size_prop.set_min_value("2");
+	ddbuffer_size_prop.set_description("The number of samples to be read on DD data source.\nInfluences the size of the associated attributes [such as XPosDD for instance].");
+	ddbuffer_size->set_default_properties(ddbuffer_size_prop);
+	ddbuffer_size->set_memorized();
+	ddbuffer_size->set_memorized_init(true);
+	att_list.push_back(ddbuffer_size);
+
+	//	Attribute : DDDecimationFactor
+	DDDecimationFactorAttrib	*dddecimation_factor = new DDDecimationFactorAttrib();
+	Tango::UserDefaultAttrProp	dddecimation_factor_prop;
+	dddecimation_factor_prop.set_label("DD Decim. Factor");
+	dddecimation_factor_prop.set_unit("samples");
+	dddecimation_factor_prop.set_format("%3d");
+	dddecimation_factor_prop.set_max_value("256");
+	dddecimation_factor_prop.set_min_value("1");
+	dddecimation_factor_prop.set_description("The DD decimation factor");
+	dddecimation_factor->set_default_properties(dddecimation_factor_prop);
+	dddecimation_factor->set_memorized();
+	dddecimation_factor->set_memorized_init(true);
+	att_list.push_back(dddecimation_factor);
+
+	//	Attribute : DDTriggerOffset
+	DDTriggerOffsetAttrib	*ddtrigger_offset = new DDTriggerOffsetAttrib();
+	Tango::UserDefaultAttrProp	ddtrigger_offset_prop;
+	ddtrigger_offset_prop.set_label("DD Trigger Offset");
+	ddtrigger_offset_prop.set_unit("turns");
+	ddtrigger_offset_prop.set_format("%6d");
+	ddtrigger_offset_prop.set_description("DD data offset in num. of turns");
+	ddtrigger_offset->set_default_properties(ddtrigger_offset_prop);
+	ddtrigger_offset->set_memorized();
+	ddtrigger_offset->set_memorized_init(true);
+	att_list.push_back(ddtrigger_offset);
+
+	//	Attribute : DDBufferFreezingEnabled
+	DDBufferFreezingEnabledAttrib	*ddbuffer_freezing_enabled = new DDBufferFreezingEnabledAttrib();
+	Tango::UserDefaultAttrProp	ddbuffer_freezing_enabled_prop;
+	ddbuffer_freezing_enabled_prop.set_label("DD Buffer Freezing Enabled");
+	ddbuffer_freezing_enabled_prop.set_unit("n/a");
+	ddbuffer_freezing_enabled_prop.set_standard_unit("n/a");
+	ddbuffer_freezing_enabled_prop.set_display_unit("n/a");
+	ddbuffer_freezing_enabled_prop.set_description("DD buffer freezing activation flag");
+	ddbuffer_freezing_enabled->set_default_properties(ddbuffer_freezing_enabled_prop);
+	att_list.push_back(ddbuffer_freezing_enabled);
+
+	//	Attribute : DDBufferFrozen
+	DDBufferFrozenAttrib	*ddbuffer_frozen = new DDBufferFrozenAttrib();
+	Tango::UserDefaultAttrProp	ddbuffer_frozen_prop;
+	ddbuffer_frozen_prop.set_label("DD Buffer Frozen");
+	ddbuffer_frozen_prop.set_unit("n/a");
+	ddbuffer_frozen_prop.set_standard_unit("n/a");
+	ddbuffer_frozen_prop.set_display_unit("n/a");
+	ddbuffer_frozen_prop.set_description("DD buffer status");
+	ddbuffer_frozen->set_default_properties(ddbuffer_frozen_prop);
+	att_list.push_back(ddbuffer_frozen);
+
+	//	Attribute : DDTriggerCounter
+	DDTriggerCounterAttrib	*ddtrigger_counter = new DDTriggerCounterAttrib();
+	Tango::UserDefaultAttrProp	ddtrigger_counter_prop;
+	ddtrigger_counter_prop.set_label("Trig.Counter");
+	ddtrigger_counter_prop.set_unit("a.u.");
+	ddtrigger_counter_prop.set_standard_unit("a.u.");
+	ddtrigger_counter_prop.set_display_unit("a.u.");
+	ddtrigger_counter_prop.set_format("%8d");
+	ddtrigger_counter_prop.set_description("Number of trigger notifications received since last device <init> ");
+	ddtrigger_counter->set_default_properties(ddtrigger_counter_prop);
+	att_list.push_back(ddtrigger_counter);
+
+	//	Attribute : ExternalTriggerEnabled
+	ExternalTriggerEnabledAttrib	*external_trigger_enabled = new ExternalTriggerEnabledAttrib();
+	Tango::UserDefaultAttrProp	external_trigger_enabled_prop;
+	external_trigger_enabled_prop.set_label("Ext. Trig. Enabled");
+	external_trigger_enabled_prop.set_unit("n/a");
+	external_trigger_enabled_prop.set_standard_unit("n/a");
+	external_trigger_enabled_prop.set_display_unit("n/a");
+	external_trigger_enabled_prop.set_description("External trigger activation flag");
+	external_trigger_enabled->set_default_properties(external_trigger_enabled_prop);
+	att_list.push_back(external_trigger_enabled);
+
+	//	Attribute : ExternalTriggerDelay
+	ExternalTriggerDelayAttrib	*external_trigger_delay = new ExternalTriggerDelayAttrib();
+	Tango::UserDefaultAttrProp	external_trigger_delay_prop;
+	external_trigger_delay_prop.set_label("External Trigger Delay");
+	external_trigger_delay_prop.set_unit("ADC samples");
+	external_trigger_delay_prop.set_format("%6d");
+	external_trigger_delay_prop.set_min_value("0");
+	external_trigger_delay_prop.set_description("The external trigger signal can be internally hardware delayed. \nThe delay is set in steps of ADC samples of about 9ns.");
+	external_trigger_delay->set_default_properties(external_trigger_delay_prop);
+	external_trigger_delay->set_memorized();
+	external_trigger_delay->set_memorized_init(true);
+	att_list.push_back(external_trigger_delay);
+
+	//	Attribute : SAEnabled
+	SAEnabledAttrib	*saenabled = new SAEnabledAttrib();
+	Tango::UserDefaultAttrProp	saenabled_prop;
+	saenabled_prop.set_label("SA Enabled");
+	saenabled_prop.set_unit("n/a");
+	saenabled_prop.set_standard_unit("n/a");
+	saenabled_prop.set_display_unit("n/a");
+	saenabled_prop.set_description("SA data source activation flag");
+	saenabled->set_default_properties(saenabled_prop);
+	saenabled->set_memorized();
+	saenabled->set_memorized_init(true);
+	att_list.push_back(saenabled);
+
+	//	Attribute : VaSA
+	VaSAAttrib	*va_sa = new VaSAAttrib();
+	Tango::UserDefaultAttrProp	va_sa_prop;
+	va_sa_prop.set_label("SA Va");
+	va_sa_prop.set_unit("a.u.");
+	va_sa_prop.set_standard_unit("a.u.");
+	va_sa_prop.set_display_unit("a.u.");
+	va_sa_prop.set_format("%10.0f");
+	va_sa_prop.set_description("Slow Acquisition: Va");
+	va_sa->set_default_properties(va_sa_prop);
+	att_list.push_back(va_sa);
+
+	//	Attribute : VbSA
+	VbSAAttrib	*vb_sa = new VbSAAttrib();
+	Tango::UserDefaultAttrProp	vb_sa_prop;
+	vb_sa_prop.set_label("SA Vb");
+	vb_sa_prop.set_unit("a.u.");
+	vb_sa_prop.set_standard_unit("a.u.");
+	vb_sa_prop.set_display_unit("a.u.");
+	vb_sa_prop.set_format("%10.0f");
+	vb_sa_prop.set_description("Slow Acquisition: Vb");
+	vb_sa->set_default_properties(vb_sa_prop);
+	att_list.push_back(vb_sa);
+
+	//	Attribute : VcSA
+	VcSAAttrib	*vc_sa = new VcSAAttrib();
+	Tango::UserDefaultAttrProp	vc_sa_prop;
+	vc_sa_prop.set_label("SA Vc");
+	vc_sa_prop.set_unit("a.u.");
+	vc_sa_prop.set_standard_unit("a.u.");
+	vc_sa_prop.set_display_unit("a.u.");
+	vc_sa_prop.set_format("%10.0f");
+	vc_sa_prop.set_description("Slow Acquisition: Vc");
+	vc_sa->set_default_properties(vc_sa_prop);
+	att_list.push_back(vc_sa);
+
+	//	Attribute : VdSA
+	VdSAAttrib	*vd_sa = new VdSAAttrib();
+	Tango::UserDefaultAttrProp	vd_sa_prop;
+	vd_sa_prop.set_label("SA Vd");
+	vd_sa_prop.set_unit("a.u.");
+	vd_sa_prop.set_standard_unit("a.u.");
+	vd_sa_prop.set_display_unit("a.u.");
+	vd_sa_prop.set_format("%10.0f");
+	vd_sa_prop.set_description("Slow Acquisition: Vd");
+	vd_sa->set_default_properties(vd_sa_prop);
+	att_list.push_back(vd_sa);
+
+	//	Attribute : XPosSA
+	XPosSAAttrib	*xpos_sa = new XPosSAAttrib();
+	Tango::UserDefaultAttrProp	xpos_sa_prop;
+	xpos_sa_prop.set_label("X.Pos.SA");
+	xpos_sa_prop.set_unit("mm");
+	xpos_sa_prop.set_format("%8.2f");
+	xpos_sa_prop.set_description("Slow Acquisition: X");
+	xpos_sa->set_default_properties(xpos_sa_prop);
+	att_list.push_back(xpos_sa);
+
+	//	Attribute : ZPosSA
+	ZPosSAAttrib	*zpos_sa = new ZPosSAAttrib();
+	Tango::UserDefaultAttrProp	zpos_sa_prop;
+	zpos_sa_prop.set_label("Z.Pos.SA");
+	zpos_sa_prop.set_unit("mm");
+	zpos_sa_prop.set_format("%8.2f");
+	zpos_sa_prop.set_description("Slow Acquisition: Z");
+	zpos_sa->set_default_properties(zpos_sa_prop);
+	att_list.push_back(zpos_sa);
+
+	//	Attribute : SumSA
+	SumSAAttrib	*sum_sa = new SumSAAttrib();
+	Tango::UserDefaultAttrProp	sum_sa_prop;
+	sum_sa_prop.set_label("Sum SA");
+	sum_sa_prop.set_unit("a.u.");
+	sum_sa_prop.set_format("%10.0f");
+	sum_sa_prop.set_description("Slow Acquisition: Sum");
+	sum_sa->set_default_properties(sum_sa_prop);
+	att_list.push_back(sum_sa);
+
+	//	Attribute : QuadSA
+	QuadSAAttrib	*quad_sa = new QuadSAAttrib();
+	Tango::UserDefaultAttrProp	quad_sa_prop;
+	quad_sa_prop.set_label("Quad SA");
+	quad_sa_prop.set_unit("a.u.");
+	quad_sa_prop.set_format("%8.4f");
+	quad_sa_prop.set_description("Slow Acquisition: Quad");
+	quad_sa->set_default_properties(quad_sa_prop);
+	att_list.push_back(quad_sa);
+
+	//	Attribute : CxSA
+	CxSAAttrib	*cx_sa = new CxSAAttrib();
+	Tango::UserDefaultAttrProp	cx_sa_prop;
+	cx_sa_prop.set_label("FOFB X Correction");
+	cx_sa_prop.set_unit("a.u.");
+	cx_sa_prop.set_format("%8d");
+	cx_sa_prop.set_description("FOFB X correction sent to the power supply");
+	cx_sa->set_default_properties(cx_sa_prop);
+	att_list.push_back(cx_sa);
+
+	//	Attribute : CzSA
+	CzSAAttrib	*cz_sa = new CzSAAttrib();
+	Tango::UserDefaultAttrProp	cz_sa_prop;
+	cz_sa_prop.set_label("FOFB Z Correction");
+	cz_sa_prop.set_unit("a.u.");
+	cz_sa_prop.set_format("%8d");
+	cz_sa_prop.set_description("FOFB Z correction sent to the power supply");
+	cz_sa->set_default_properties(cz_sa_prop);
+	att_list.push_back(cz_sa);
+
+	//	Attribute : SAStatNumSamples
+	SAStatNumSamplesAttrib	*sastat_num_samples = new SAStatNumSamplesAttrib();
+	Tango::UserDefaultAttrProp	sastat_num_samples_prop;
+	sastat_num_samples_prop.set_label("SA Stats.Num.Samples.");
+	sastat_num_samples_prop.set_unit("samples");
+	sastat_num_samples_prop.set_format("%5d");
+	sastat_num_samples_prop.set_description("The number of sample in SA history used to compute the SA statistics\n(Mean, RMS, Peak pos). The most recent samples will be used.\nThe valid range is [2, SAHistoryLength property value].\n");
+	sastat_num_samples->set_default_properties(sastat_num_samples_prop);
+	att_list.push_back(sastat_num_samples);
+
+	//	Attribute : XMeanPosSA
+	XMeanPosSAAttrib	*xmean_pos_sa = new XMeanPosSAAttrib();
+	Tango::UserDefaultAttrProp	xmean_pos_sa_prop;
+	xmean_pos_sa_prop.set_label("SA X Mean Pos.");
+	xmean_pos_sa_prop.set_unit("mm");
+	xmean_pos_sa_prop.set_format("%8.4f");
+	xmean_pos_sa_prop.set_description("Slow Acquisition:  X Mean Pos.");
+	xmean_pos_sa->set_default_properties(xmean_pos_sa_prop);
+	att_list.push_back(xmean_pos_sa);
+
+	//	Attribute : ZMeanPosSA
+	ZMeanPosSAAttrib	*zmean_pos_sa = new ZMeanPosSAAttrib();
+	Tango::UserDefaultAttrProp	zmean_pos_sa_prop;
+	zmean_pos_sa_prop.set_label("SA Z Mean Pos.");
+	zmean_pos_sa_prop.set_unit("mm");
+	zmean_pos_sa_prop.set_format("%8.4f");
+	zmean_pos_sa_prop.set_description("Slow Acquisition:  Z Mean Pos.");
+	zmean_pos_sa->set_default_properties(zmean_pos_sa_prop);
+	att_list.push_back(zmean_pos_sa);
+
+	//	Attribute : XRMSPosSA
+	XRMSPosSAAttrib	*xrmspos_sa = new XRMSPosSAAttrib();
+	Tango::UserDefaultAttrProp	xrmspos_sa_prop;
+	xrmspos_sa_prop.set_label("SA X RMS Pos.");
+	xrmspos_sa_prop.set_unit("um");
+	xrmspos_sa_prop.set_format("%8.2f");
+	xrmspos_sa_prop.set_description("Slow Acquisition:  X RMS Pos.");
+	xrmspos_sa->set_default_properties(xrmspos_sa_prop);
+	att_list.push_back(xrmspos_sa);
+
+	//	Attribute : ZRMSPosSA
+	ZRMSPosSAAttrib	*zrmspos_sa = new ZRMSPosSAAttrib();
+	Tango::UserDefaultAttrProp	zrmspos_sa_prop;
+	zrmspos_sa_prop.set_label("SA Z RMS Pos.");
+	zrmspos_sa_prop.set_unit("um");
+	zrmspos_sa_prop.set_format("%8.2f");
+	zrmspos_sa_prop.set_description("Slow Acquisition: Z RMS Pos.");
+	zrmspos_sa->set_default_properties(zrmspos_sa_prop);
+	att_list.push_back(zrmspos_sa);
+
+	//	Attribute : XPeakPosSA
+	XPeakPosSAAttrib	*xpeak_pos_sa = new XPeakPosSAAttrib();
+	Tango::UserDefaultAttrProp	xpeak_pos_sa_prop;
+	xpeak_pos_sa_prop.set_label("X.Peak.Pos.SA");
+	xpeak_pos_sa_prop.set_unit("um");
+	xpeak_pos_sa_prop.set_format("%8.2f");
+	xpeak_pos_sa_prop.set_description("Slow Acquisition: X pos peak to peak amplitude");
+	xpeak_pos_sa->set_default_properties(xpeak_pos_sa_prop);
+	att_list.push_back(xpeak_pos_sa);
+
+	//	Attribute : ZPeakPosSA
+	ZPeakPosSAAttrib	*zpeak_pos_sa = new ZPeakPosSAAttrib();
+	Tango::UserDefaultAttrProp	zpeak_pos_sa_prop;
+	zpeak_pos_sa_prop.set_label("Z.Peak.Pos.SA");
+	zpeak_pos_sa_prop.set_unit("um");
+	zpeak_pos_sa_prop.set_format("%8.2f");
+	zpeak_pos_sa_prop.set_description("Slow Acquisition: X pos peak to peak amplitude");
+	zpeak_pos_sa->set_default_properties(zpeak_pos_sa_prop);
+	att_list.push_back(zpeak_pos_sa);
+
+	//	Attribute : SumMeanSA
+	SumMeanSAAttrib	*sum_mean_sa = new SumMeanSAAttrib();
+	Tango::UserDefaultAttrProp	sum_mean_sa_prop;
+	sum_mean_sa_prop.set_label("SA Sum Mean");
+	sum_mean_sa_prop.set_unit("a.u.");
+	sum_mean_sa_prop.set_standard_unit("a.u.");
+	sum_mean_sa_prop.set_display_unit("a.u.");
+	sum_mean_sa_prop.set_format("%8.1f");
+	sum_mean_sa_prop.set_description("SA: mean of sum");
+	sum_mean_sa->set_default_properties(sum_mean_sa_prop);
+	att_list.push_back(sum_mean_sa);
+
+	//	Attribute : ADCEnabled
+	ADCEnabledAttrib	*adcenabled = new ADCEnabledAttrib();
+	Tango::UserDefaultAttrProp	adcenabled_prop;
+	adcenabled_prop.set_label("ADC Enabled");
+	adcenabled_prop.set_unit("n/a");
+	adcenabled_prop.set_standard_unit("n/a");
+	adcenabled_prop.set_display_unit("n/a");
+	adcenabled_prop.set_description("ADC data source activation flag");
+	adcenabled->set_default_properties(adcenabled_prop);
+	adcenabled->set_memorized();
+	adcenabled->set_memorized_init(true);
+	att_list.push_back(adcenabled);
+
+	//	Attribute : ADCBufferSize
+	ADCBufferSizeAttrib	*adcbuffer_size = new ADCBufferSizeAttrib();
+	Tango::UserDefaultAttrProp	adcbuffer_size_prop;
+	adcbuffer_size_prop.set_label("ADC Buffer Size");
+	adcbuffer_size_prop.set_unit("samples");
+	adcbuffer_size_prop.set_format("%5d");
+	adcbuffer_size_prop.set_max_value("65535");
+	adcbuffer_size_prop.set_min_value("8");
+	adcbuffer_size_prop.set_description("The number of samples to be read on ADC data source.\nInfluences the size of the associated attributes [such as ADCChannelA for instance].");
+	adcbuffer_size->set_default_properties(adcbuffer_size_prop);
+	adcbuffer_size->set_memorized();
+	adcbuffer_size->set_memorized_init(true);
+	att_list.push_back(adcbuffer_size);
+
+	//	Attribute : PMOffset
+	PMOffsetAttrib	*pmoffset = new PMOffsetAttrib();
+	Tango::UserDefaultAttrProp	pmoffset_prop;
+	pmoffset_prop.set_label("Post Mortem Offset");
+	pmoffset_prop.set_unit("samples");
+	pmoffset_prop.set_format("%3d");
+	pmoffset_prop.set_max_value("10000");
+	pmoffset_prop.set_min_value("-10000");
+	pmoffset_prop.set_description("Internal delay of the post mortem trigger. \nCan be set in the range of +/- 10 ksamples.");
+	pmoffset->set_default_properties(pmoffset_prop);
+	pmoffset->set_memorized();
+	pmoffset->set_memorized_init(true);
+	att_list.push_back(pmoffset);
+
+	//	Attribute : PMNotified
+	PMNotifiedAttrib	*pmnotified = new PMNotifiedAttrib();
+	Tango::UserDefaultAttrProp	pmnotified_prop;
+	pmnotified_prop.set_label("Post Moterm Notified");
+	pmnotified_prop.set_unit("n/a");
+	pmnotified_prop.set_description("Post Moterm notification flag");
+	pmnotified->set_default_properties(pmnotified_prop);
+	att_list.push_back(pmnotified);
+
+	//	Attribute : PMNotificationCounter
+	PMNotificationCounterAttrib	*pmnotification_counter = new PMNotificationCounterAttrib();
+	Tango::UserDefaultAttrProp	pmnotification_counter_prop;
+	pmnotification_counter_prop.set_label("PM Notif. Counter");
+	pmnotification_counter_prop.set_format("%8d");
+	pmnotification_counter_prop.set_description("Number a PM event recieved since last Init");
+	pmnotification_counter->set_default_properties(pmnotification_counter_prop);
+	att_list.push_back(pmnotification_counter);
+
+	//	Attribute : InterlockXNotified
+	InterlockXNotifiedAttrib	*interlock_xnotified = new InterlockXNotifiedAttrib();
+	att_list.push_back(interlock_xnotified);
+
+	//	Attribute : InterlockZNotified
+	InterlockZNotifiedAttrib	*interlock_znotified = new InterlockZNotifiedAttrib();
+	att_list.push_back(interlock_znotified);
+
+	//	Attribute : InterlockAttnNotified
+	InterlockAttnNotifiedAttrib	*interlock_attn_notified = new InterlockAttnNotifiedAttrib();
+	att_list.push_back(interlock_attn_notified);
+
+	//	Attribute : InterlockADCPreFilterNotified
+	InterlockADCPreFilterNotifiedAttrib	*interlock_adcpre_filter_notified = new InterlockADCPreFilterNotifiedAttrib();
+	att_list.push_back(interlock_adcpre_filter_notified);
+
+	//	Attribute : InterlockADCPostFilterNotified
+	InterlockADCPostFilterNotifiedAttrib	*interlock_adcpost_filter_notified = new InterlockADCPostFilterNotifiedAttrib();
+	att_list.push_back(interlock_adcpost_filter_notified);
+
+	//	Attribute : XLow
+	XLowAttrib	*xlow = new XLowAttrib();
+	Tango::UserDefaultAttrProp	xlow_prop;
+	xlow_prop.set_label("X Low Int. Thres.");
+	xlow_prop.set_unit("mm");
+	xlow_prop.set_format("%8.4f");
+	xlow_prop.set_description("Lower limit of the X position interlock threshold in mm");
+	xlow->set_default_properties(xlow_prop);
+	att_list.push_back(xlow);
+
+	//	Attribute : XHigh
+	XHighAttrib	*xhigh = new XHighAttrib();
+	Tango::UserDefaultAttrProp	xhigh_prop;
+	xhigh_prop.set_label("X High Int. Thres.");
+	xhigh_prop.set_unit("mm");
+	xhigh_prop.set_format("%8.4f");
+	xhigh_prop.set_description("Upper limit of the X position interlock threshold in mm");
+	xhigh->set_default_properties(xhigh_prop);
+	att_list.push_back(xhigh);
+
+	//	Attribute : ZLow
+	ZLowAttrib	*zlow = new ZLowAttrib();
+	Tango::UserDefaultAttrProp	zlow_prop;
+	zlow_prop.set_label("Z Low Int. Thres.");
+	zlow_prop.set_unit("mm");
+	zlow_prop.set_format("%8.4f");
+	zlow_prop.set_description("Lower limit of the Z position interlock threshold in mm");
+	zlow->set_default_properties(zlow_prop);
+	att_list.push_back(zlow);
+
+	//	Attribute : ZHigh
+	ZHighAttrib	*zhigh = new ZHighAttrib();
+	Tango::UserDefaultAttrProp	zhigh_prop;
+	zhigh_prop.set_label("Z High Int. Thres.");
+	zhigh_prop.set_unit("mm");
+	zhigh_prop.set_format("%8.4f");
+	zhigh_prop.set_description("Upper limit of the Z position interlock threshold in mm");
+	zhigh->set_default_properties(zhigh_prop);
+	att_list.push_back(zhigh);
+
+	//	Attribute : AutoSwitchingEnabled
+	AutoSwitchingEnabledAttrib	*auto_switching_enabled = new AutoSwitchingEnabledAttrib();
+	Tango::UserDefaultAttrProp	auto_switching_enabled_prop;
+	auto_switching_enabled_prop.set_label("Auto switching enabled");
+	auto_switching_enabled_prop.set_unit("n/a");
+	auto_switching_enabled_prop.set_standard_unit("n/a");
+	auto_switching_enabled_prop.set_display_unit("n/a");
+	auto_switching_enabled_prop.set_description("Auto switching status (true=enabled, false=disabled)");
+	auto_switching_enabled->set_default_properties(auto_switching_enabled_prop);
+	att_list.push_back(auto_switching_enabled);
+
+	//	Attribute : Switches
+	SwitchesAttrib	*switches = new SwitchesAttrib();
+	Tango::UserDefaultAttrProp	switches_prop;
+	switches_prop.set_label("Switches");
+	switches_prop.set_unit("a.u.");
+	switches_prop.set_format("%3d");
+	switches_prop.set_max_value("255");
+	switches_prop.set_min_value("0");
+	switches_prop.set_description("Switches selection. Must be in [0, 15] or 255 for auto-switching.");
+	switches->set_default_properties(switches_prop);
+	switches->set_memorized();
+	switches->set_memorized_init(true);
+	att_list.push_back(switches);
+
+	//	Attribute : ExternalSwitching
+	ExternalSwitchingAttrib	*external_switching = new ExternalSwitchingAttrib();
+	Tango::UserDefaultAttrProp	external_switching_prop;
+	external_switching_prop.set_label("External Switching");
+	external_switching_prop.set_description("Determines whether the ADC source switching  will be triggered by the \ninternally (false) or be the externally (true) by the machine clock.");
+	external_switching->set_default_properties(external_switching_prop);
+	external_switching->set_memorized();
+	external_switching->set_memorized_init(true);
+	att_list.push_back(external_switching);
+
+	//	Attribute : SwitchingDelay
+	SwitchingDelayAttrib	*switching_delay = new SwitchingDelayAttrib();
+	Tango::UserDefaultAttrProp	switching_delay_prop;
+	switching_delay_prop.set_label("Switching Delay");
+	switching_delay_prop.set_unit("a.u.");
+	switching_delay_prop.set_display_unit("%6d");
+	switching_delay_prop.set_min_value("0");
+	switching_delay_prop.set_description("Delay for the ADC source switching.");
+	switching_delay->set_default_properties(switching_delay_prop);
+	switching_delay->set_memorized();
+	switching_delay->set_memorized_init(true);
+	att_list.push_back(switching_delay);
+
+	//	Attribute : OffsetTune
+	OffsetTuneAttrib	*offset_tune = new OffsetTuneAttrib();
+	Tango::UserDefaultAttrProp	offset_tune_prop;
+	offset_tune_prop.set_label("OffsetTune");
+	offset_tune_prop.set_unit("x 40Hz");
+	offset_tune_prop.set_format("%3d");
+	offset_tune_prop.set_max_value("500");
+	offset_tune_prop.set_min_value("-500");
+	offset_tune_prop.set_description("Determines the pll offset to tune the BPM. \nThe unit is ~40Hz.");
+	offset_tune->set_default_properties(offset_tune_prop);
+	offset_tune->set_memorized();
+	offset_tune->set_memorized_init(true);
+	att_list.push_back(offset_tune);
+
+	//	Attribute : CompensateTune
+	CompensateTuneAttrib	*compensate_tune = new CompensateTuneAttrib();
+	Tango::UserDefaultAttrProp	compensate_tune_prop;
+	compensate_tune_prop.set_label("Compensate Tune");
+	compensate_tune_prop.set_description("Determines whether single or double offset tune will be employed. \nDefault value is true, which means that the the double offset tune is employed.");
+	compensate_tune->set_default_properties(compensate_tune_prop);
+	compensate_tune->set_memorized();
+	compensate_tune->set_memorized_init(true);
+	att_list.push_back(compensate_tune);
+
+	//	Attribute : DSCMode
+	DSCModeAttrib	*dscmode = new DSCModeAttrib();
+	Tango::UserDefaultAttrProp	dscmode_prop;
+	dscmode_prop.set_label("DSC Mode");
+	dscmode_prop.set_unit("[0:OFF, 1:UNITY, 2:AUTO]");
+	dscmode_prop.set_format("%1d");
+	dscmode_prop.set_max_value("2");
+	dscmode_prop.set_min_value("0");
+	dscmode_prop.set_description("Digital Signal Conditioning mode\n0:OFF - 1:UNITY - 2:AUTO");
+	dscmode->set_default_properties(dscmode_prop);
+	att_list.push_back(dscmode);
+
+	//	Attribute : AGCEnabled
+	AGCEnabledAttrib	*agcenabled = new AGCEnabledAttrib();
+	Tango::UserDefaultAttrProp	agcenabled_prop;
+	agcenabled_prop.set_label("AGC");
+	agcenabled_prop.set_description("Enables/disables the Automatic Gain Control");
+	agcenabled->set_default_properties(agcenabled_prop);
+	agcenabled->set_memorized();
+	agcenabled->set_memorized_init(true);
+	att_list.push_back(agcenabled);
+
+	//	Attribute : Gain
+	GainAttrib	*gain = new GainAttrib();
+	Tango::UserDefaultAttrProp	gain_prop;
+	gain_prop.set_label("Gain");
+	gain_prop.set_unit("dBm");
+	gain_prop.set_standard_unit("dBm");
+	gain_prop.set_display_unit("dBm");
+	gain_prop.set_format("%2.0f");
+	gain_prop.set_max_value("0");
+	gain_prop.set_min_value("-60");
+	gain_prop.set_description("The Libera input gain. \nCan't be change while the AGC is active");
+	gain->set_default_properties(gain_prop);
+	att_list.push_back(gain);
+
+	//	Attribute : HasMAFSupport
+	HasMAFSupportAttrib	*has_mafsupport = new HasMAFSupportAttrib();
+	Tango::UserDefaultAttrProp	has_mafsupport_prop;
+	has_mafsupport_prop.set_label("Moving Average Filter Support");
+	has_mafsupport_prop.set_description("<true> if FGPA design with MAF support installed on Libera, <false> otherwise");
+	has_mafsupport->set_default_properties(has_mafsupport_prop);
+	att_list.push_back(has_mafsupport);
+
+	//	Attribute : MAFLength
+	MAFLengthAttrib	*maflength = new MAFLengthAttrib();
+	Tango::UserDefaultAttrProp	maflength_prop;
+	maflength_prop.set_label("Moving Average Filter Length");
+	maflength_prop.set_unit("ADC samples");
+	maflength_prop.set_format("%6d");
+	maflength_prop.set_min_value("1");
+	maflength_prop.set_description("MAF Delay and MAF Length are two\nparameters, added to adjustable\nDDC design. They are used to\ndetermine the position and the length\nof the acquisition window according\nto the partial fill of the accelerator.");
+	maflength->set_default_properties(maflength_prop);
+	maflength->set_memorized();
+	maflength->set_memorized_init(true);
+	att_list.push_back(maflength);
+
+	//	Attribute : MAFDelay
+	MAFDelayAttrib	*mafdelay = new MAFDelayAttrib();
+	Tango::UserDefaultAttrProp	mafdelay_prop;
+	mafdelay_prop.set_label("Moving Average Filter Delay");
+	mafdelay_prop.set_unit("ADC samples");
+	mafdelay_prop.set_format("%6d");
+	mafdelay_prop.set_min_value("0");
+	mafdelay_prop.set_description("MAF Delay and MAF Length are two\nparameters, added to adjustable\nDDC design. They are used to\ndetermine the position and the length\nof the acquisition window according\nto the partial fill of the accelerator.\n");
+	mafdelay->set_default_properties(mafdelay_prop);
+	mafdelay->set_memorized();
+	mafdelay->set_memorized_init(true);
+	att_list.push_back(mafdelay);
+
+	//	Attribute : MachineTime
+	MachineTimeAttrib	*machine_time = new MachineTimeAttrib();
+	Tango::UserDefaultAttrProp	machine_time_prop;
+	machine_time_prop.set_label("Machine Time");
+	machine_time_prop.set_unit("a.u.");
+	machine_time_prop.set_format("%9d");
+	machine_time_prop.set_min_value("0");
+	machine_time_prop.set_description("Machine Time value to be applied on the Libera when the SetTimeOnNextTrigger command is executed");
+	machine_time->set_default_properties(machine_time_prop);
+	att_list.push_back(machine_time);
+
+	//	Attribute : TimePhase
+	TimePhaseAttrib	*time_phase = new TimePhaseAttrib();
+	Tango::UserDefaultAttrProp	time_phase_prop;
+	time_phase_prop.set_label("Machine Time Phase");
+	time_phase_prop.set_unit("a.u.");
+	time_phase_prop.set_format("%6d");
+	time_phase_prop.set_description("The Machine Time Phase");
+	time_phase->set_default_properties(time_phase_prop);
+	time_phase->set_memorized();
+	time_phase->set_memorized_init(true);
+	att_list.push_back(time_phase);
+
+	//	Attribute : SystemTime
+	SystemTimeAttrib	*system_time = new SystemTimeAttrib();
+	Tango::UserDefaultAttrProp	system_time_prop;
+	system_time_prop.set_label("System Time");
+	system_time_prop.set_unit("secs since 1/1/1970");
+	system_time_prop.set_format("%10d");
+	system_time_prop.set_min_value("2000000000");
+	system_time_prop.set_description("System Time value to be applied on the Libera when the SetTimeOnNextTrigger command is executed\nUnit is num of secs since 1/1/1970 (Unix system time reference)");
+	system_time->set_default_properties(system_time_prop);
+	att_list.push_back(system_time);
+
+	//	Attribute : SCPLLStatus
+	SCPLLStatusAttrib	*scpllstatus = new SCPLLStatusAttrib();
+	Tango::UserDefaultAttrProp	scpllstatus_prop;
+	scpllstatus_prop.set_label("SC PLL Locked");
+	scpllstatus_prop.set_format("%8d");
+	scpllstatus_prop.set_description("The SC PLL lock status");
+	scpllstatus->set_default_properties(scpllstatus_prop);
+	att_list.push_back(scpllstatus);
+
+	//	Attribute : MCPLLStatus
+	MCPLLStatusAttrib	*mcpllstatus = new MCPLLStatusAttrib();
+	Tango::UserDefaultAttrProp	mcpllstatus_prop;
+	mcpllstatus_prop.set_label("MC PLL Locked");
+	mcpllstatus_prop.set_format("%8d");
+	mcpllstatus_prop.set_description("The MC PLL lock status");
+	mcpllstatus->set_default_properties(mcpllstatus_prop);
+	att_list.push_back(mcpllstatus);
+
+	//	Attribute : HWTemperature
+	HWTemperatureAttrib	*hwtemperature = new HWTemperatureAttrib();
+	Tango::UserDefaultAttrProp	hwtemperature_prop;
+	hwtemperature_prop.set_label("HW Temp.");
+	hwtemperature_prop.set_unit("deg.C");
+	hwtemperature_prop.set_format("%8d");
+	hwtemperature_prop.set_max_alarm("50");
+	hwtemperature_prop.set_description("The current Libera hardware temperature");
+	hwtemperature->set_default_properties(hwtemperature_prop);
+	att_list.push_back(hwtemperature);
+
+	//	Attribute : Fan1Speed
+	Fan1SpeedAttrib	*fan1_speed = new Fan1SpeedAttrib();
+	Tango::UserDefaultAttrProp	fan1_speed_prop;
+	fan1_speed_prop.set_label("Fan.1");
+	fan1_speed_prop.set_unit("rpm");
+	fan1_speed_prop.set_format("%8d");
+	fan1_speed_prop.set_min_alarm("1000");
+	fan1_speed_prop.set_description("The current rotation speed of the first hardware cooling fan");
+	fan1_speed->set_default_properties(fan1_speed_prop);
+	att_list.push_back(fan1_speed);
+
+	//	Attribute : Fan2Speed
+	Fan2SpeedAttrib	*fan2_speed = new Fan2SpeedAttrib();
+	Tango::UserDefaultAttrProp	fan2_speed_prop;
+	fan2_speed_prop.set_label("Fan.2");
+	fan2_speed_prop.set_unit("rpm");
+	fan2_speed_prop.set_format("%8d");
+	fan2_speed_prop.set_min_alarm("1000");
+	fan2_speed_prop.set_description("The current rotation speed of the second hardware cooling fan");
+	fan2_speed->set_default_properties(fan2_speed_prop);
+	att_list.push_back(fan2_speed);
+
+	//	Attribute : Incoherence
+	IncoherenceAttrib	*incoherence = new IncoherenceAttrib();
+	Tango::UserDefaultAttrProp	incoherence_prop;
+	incoherence_prop.set_label("Incoherence");
+	incoherence_prop.set_unit("a.u.");
+	incoherence_prop.set_format("%6.4f");
+	incoherence_prop.set_description("Result of the incoherence calculation. Am alarm will be set \non the attribute when an incoherence was detected.");
+	incoherence->set_default_properties(incoherence_prop);
+	att_list.push_back(incoherence);
+
+	//	Attribute : RefIncoherence
+	RefIncoherenceAttrib	*ref_incoherence = new RefIncoherenceAttrib();
+	Tango::UserDefaultAttrProp	ref_incoherence_prop;
+	ref_incoherence_prop.set_label("Ref. Incoherence");
+	ref_incoherence_prop.set_unit("a.u.");
+	ref_incoherence_prop.set_format("%6.4f");
+	ref_incoherence_prop.set_description("The reference incoherence value registered with the command \nSetReferenceIncoherence. The reference is used to calculate the\nalarm with the MaxIncoherenceDrift.");
+	ref_incoherence->set_default_properties(ref_incoherence_prop);
+	att_list.push_back(ref_incoherence);
+
+	//	Attribute : MaxIncoherence
+	MaxIncoherenceAttrib	*max_incoherence = new MaxIncoherenceAttrib();
+	Tango::UserDefaultAttrProp	max_incoherence_prop;
+	max_incoherence_prop.set_label("Max. incoherence");
+	max_incoherence_prop.set_unit("a.u.");
+	max_incoherence_prop.set_format("%6.4f");
+	max_incoherence_prop.set_description("Maximum incoherence value. Used to create an alarm on\nthe Incoherence attribute.");
+	max_incoherence->set_default_properties(max_incoherence_prop);
+	max_incoherence->set_memorized();
+	max_incoherence->set_memorized_init(true);
+	att_list.push_back(max_incoherence);
+
+	//	Attribute : MaxIncoherenceDrift
+	MaxIncoherenceDriftAttrib	*max_incoherence_drift = new MaxIncoherenceDriftAttrib();
+	Tango::UserDefaultAttrProp	max_incoherence_drift_prop;
+	max_incoherence_drift_prop.set_label("Max. Incoherence Drift ");
+	max_incoherence_drift_prop.set_unit("a.u.");
+	max_incoherence_drift_prop.set_format("%6.4f");
+	max_incoherence_drift_prop.set_description("Maximum incoherence drift value. Used to create an alarm on\nthe Incoherence attribute.");
+	max_incoherence_drift->set_default_properties(max_incoherence_drift_prop);
+	max_incoherence_drift->set_memorized();
+	max_incoherence_drift->set_memorized_init(true);
+	att_list.push_back(max_incoherence_drift);
+
+	//	Attribute : UpTime
+	UpTimeAttrib	*up_time = new UpTimeAttrib();
+	Tango::UserDefaultAttrProp	up_time_prop;
+	up_time_prop.set_label("Uptime");
+	up_time_prop.set_unit("secs");
+	up_time_prop.set_format("%8d");
+	up_time_prop.set_description("Number of seconds since system boot on the host running this TANGO device");
+	up_time->set_default_properties(up_time_prop);
+	att_list.push_back(up_time);
+
+	//	Attribute : CpuUsage
+	CpuUsageAttrib	*cpu_usage = new CpuUsageAttrib();
+	Tango::UserDefaultAttrProp	cpu_usage_prop;
+	cpu_usage_prop.set_label("CPU Usage");
+	cpu_usage_prop.set_unit("%");
+	cpu_usage_prop.set_format("%8d");
+	cpu_usage_prop.set_description("CPU usage on the host running this TANGO device");
+	cpu_usage->set_default_properties(cpu_usage_prop);
+	att_list.push_back(cpu_usage);
+
+	//	Attribute : FreeMemory
+	FreeMemoryAttrib	*free_memory = new FreeMemoryAttrib();
+	Tango::UserDefaultAttrProp	free_memory_prop;
+	free_memory_prop.set_label("Free Mem.");
+	free_memory_prop.set_unit("bytes");
+	free_memory_prop.set_format("%8d");
+	free_memory_prop.set_description("Amount of free memory on the host running this TANGO device");
+	free_memory->set_default_properties(free_memory_prop);
+	att_list.push_back(free_memory);
+
+	//	Attribute : RamFsUsage
+	RamFsUsageAttrib	*ram_fs_usage = new RamFsUsageAttrib();
+	Tango::UserDefaultAttrProp	ram_fs_usage_prop;
+	ram_fs_usage_prop.set_label("Ram-fs Usage");
+	ram_fs_usage_prop.set_unit("bytes");
+	ram_fs_usage_prop.set_format("%8d");
+	ram_fs_usage_prop.set_description("Amount of ram-fs allocated bytes on the host running this TANGO device ");
+	ram_fs_usage->set_default_properties(ram_fs_usage_prop);
+	att_list.push_back(ram_fs_usage);
+
+	//	Attribute : UseLiberaSAData
+	UseLiberaSADataAttrib	*use_libera_sadata = new UseLiberaSADataAttrib();
+	Tango::UserDefaultAttrProp	use_libera_sadata_prop;
+	use_libera_sadata_prop.set_label("Use Libera SA Data");
+	use_libera_sadata_prop.set_description("If set to true, the X & Z SA postions are retreived from the Libera FPGA.\nOtherwise, they are computed by the Tango device using the button values.\n ");
+	use_libera_sadata->set_default_properties(use_libera_sadata_prop);
+	use_libera_sadata->set_disp_level(Tango::EXPERT);
+	use_libera_sadata->set_memorized();
+	use_libera_sadata->set_memorized_init(true);
+	att_list.push_back(use_libera_sadata);
+
+	//	Attribute : XPosDD
+	XPosDDAttrib	*xpos_dd = new XPosDDAttrib();
+	Tango::UserDefaultAttrProp	xpos_dd_prop;
+	xpos_dd_prop.set_label("DD X Pos.");
+	xpos_dd_prop.set_unit("mm");
+	xpos_dd_prop.set_standard_unit("mm");
+	xpos_dd_prop.set_display_unit("mm");
+	xpos_dd_prop.set_format("%8.4f");
+	xpos_dd_prop.set_description("Turn by turn data: X Pos.");
+	xpos_dd->set_default_properties(xpos_dd_prop);
+	att_list.push_back(xpos_dd);
+
+	//	Attribute : ZPosDD
+	ZPosDDAttrib	*zpos_dd = new ZPosDDAttrib();
+	Tango::UserDefaultAttrProp	zpos_dd_prop;
+	zpos_dd_prop.set_label("DD Z Pos.");
+	zpos_dd_prop.set_unit("mm");
+	zpos_dd_prop.set_standard_unit("mm");
+	zpos_dd_prop.set_display_unit("mm");
+	zpos_dd_prop.set_format("%8.4f");
+	zpos_dd_prop.set_description("Turn by turn data: Z Pos.");
+	zpos_dd->set_default_properties(zpos_dd_prop);
+	att_list.push_back(zpos_dd);
+
+	//	Attribute : QuadDD
+	QuadDDAttrib	*quad_dd = new QuadDDAttrib();
+	Tango::UserDefaultAttrProp	quad_dd_prop;
+	quad_dd_prop.set_label("DD Quad");
+	quad_dd_prop.set_unit("a.u.");
+	quad_dd_prop.set_standard_unit("a.u.");
+	quad_dd_prop.set_display_unit("a.u.");
+	quad_dd_prop.set_format("%8.4f");
+	quad_dd_prop.set_description("Turn by turn data: Quad");
+	quad_dd->set_default_properties(quad_dd_prop);
+	att_list.push_back(quad_dd);
+
+	//	Attribute : SumDD
+	SumDDAttrib	*sum_dd = new SumDDAttrib();
+	Tango::UserDefaultAttrProp	sum_dd_prop;
+	sum_dd_prop.set_label("DD Sum");
+	sum_dd_prop.set_unit("mm");
+	sum_dd_prop.set_standard_unit("mm");
+	sum_dd_prop.set_display_unit("mm");
+	sum_dd_prop.set_format("%10.0f");
+	sum_dd_prop.set_description("Turn by turn data: Sum");
+	sum_dd->set_default_properties(sum_dd_prop);
+	att_list.push_back(sum_dd);
+
+	//	Attribute : VaDD
+	VaDDAttrib	*va_dd = new VaDDAttrib();
+	Tango::UserDefaultAttrProp	va_dd_prop;
+	va_dd_prop.set_label("DD Va");
+	va_dd_prop.set_unit("a.u.");
+	va_dd_prop.set_standard_unit("a.u.");
+	va_dd_prop.set_display_unit("a.u.");
+	va_dd_prop.set_format("%10.0f");
+	va_dd_prop.set_description("Turn by turn data: Va");
+	va_dd->set_default_properties(va_dd_prop);
+	att_list.push_back(va_dd);
+
+	//	Attribute : VbDD
+	VbDDAttrib	*vb_dd = new VbDDAttrib();
+	Tango::UserDefaultAttrProp	vb_dd_prop;
+	vb_dd_prop.set_label("DD Vb");
+	vb_dd_prop.set_unit("a.u.");
+	vb_dd_prop.set_standard_unit("a.u.");
+	vb_dd_prop.set_display_unit("a.u.");
+	vb_dd_prop.set_format("%10.0f");
+	vb_dd_prop.set_description("Turn by turn data: Vb");
+	vb_dd->set_default_properties(vb_dd_prop);
+	att_list.push_back(vb_dd);
+
+	//	Attribute : VcDD
+	VcDDAttrib	*vc_dd = new VcDDAttrib();
+	Tango::UserDefaultAttrProp	vc_dd_prop;
+	vc_dd_prop.set_label("DD Vc");
+	vc_dd_prop.set_unit("a.u.");
+	vc_dd_prop.set_standard_unit("a.u.");
+	vc_dd_prop.set_display_unit("a.u.");
+	vc_dd_prop.set_format("%10.0f");
+	vc_dd_prop.set_description("Turn by turn data: Vc");
+	vc_dd->set_default_properties(vc_dd_prop);
+	att_list.push_back(vc_dd);
+
+	//	Attribute : VdDD
+	VdDDAttrib	*vd_dd = new VdDDAttrib();
+	Tango::UserDefaultAttrProp	vd_dd_prop;
+	vd_dd_prop.set_label("DD Vd");
+	vd_dd_prop.set_unit("a.u.");
+	vd_dd_prop.set_standard_unit("a.u.");
+	vd_dd_prop.set_display_unit("a.u.");
+	vd_dd_prop.set_format("%10.0f");
+	vd_dd_prop.set_description("Turn by turn data: Vd");
+	vd_dd->set_default_properties(vd_dd_prop);
+	att_list.push_back(vd_dd);
+
+	//	Attribute : XPosSAHistory
+	XPosSAHistoryAttrib	*xpos_sahistory = new XPosSAHistoryAttrib();
+	Tango::UserDefaultAttrProp	xpos_sahistory_prop;
+	xpos_sahistory_prop.set_label("SA X Pos. History");
+	xpos_sahistory_prop.set_unit("mm");
+	xpos_sahistory_prop.set_standard_unit("mm");
+	xpos_sahistory_prop.set_display_unit("mm");
+	xpos_sahistory_prop.set_format("%8.4f");
+	xpos_sahistory_prop.set_description("Slow Acquisition: SA X Pos. History");
+	xpos_sahistory->set_default_properties(xpos_sahistory_prop);
+	att_list.push_back(xpos_sahistory);
+
+	//	Attribute : ZPosSAHistory
+	ZPosSAHistoryAttrib	*zpos_sahistory = new ZPosSAHistoryAttrib();
+	Tango::UserDefaultAttrProp	zpos_sahistory_prop;
+	zpos_sahistory_prop.set_label("SA Z Pos. History");
+	zpos_sahistory_prop.set_unit("mm");
+	zpos_sahistory_prop.set_standard_unit("mm");
+	zpos_sahistory_prop.set_display_unit("mm");
+	zpos_sahistory_prop.set_format("%8.4f");
+	zpos_sahistory_prop.set_description("Slow Acquisition: SA Z Pos. History");
+	zpos_sahistory->set_default_properties(zpos_sahistory_prop);
+	att_list.push_back(zpos_sahistory);
+
+	//	Attribute : SumSAHistory
+	SumSAHistoryAttrib	*sum_sahistory = new SumSAHistoryAttrib();
+	Tango::UserDefaultAttrProp	sum_sahistory_prop;
+	sum_sahistory_prop.set_label("SA Sum. History");
+	sum_sahistory_prop.set_unit("a.u.");
+	sum_sahistory_prop.set_standard_unit("a.u.");
+	sum_sahistory_prop.set_display_unit("a.u.");
+	sum_sahistory_prop.set_format("%8.4f");
+	sum_sahistory_prop.set_description("Slow Acquisition: SA Sum Pos. History");
+	sum_sahistory->set_default_properties(sum_sahistory_prop);
+	att_list.push_back(sum_sahistory);
+
+	//	Attribute : XPosPM
+	XPosPMAttrib	*xpos_pm = new XPosPMAttrib();
+	Tango::UserDefaultAttrProp	xpos_pm_prop;
+	xpos_pm_prop.set_label("X Post Mortem Data");
+	xpos_pm_prop.set_unit("mm");
+	xpos_pm_prop.set_standard_unit("mm");
+	xpos_pm_prop.set_display_unit("mm");
+	xpos_pm_prop.set_format("%8.4f");
+	xpos_pm_prop.set_description("Post Mortem : X pos.");
+	xpos_pm->set_default_properties(xpos_pm_prop);
+	att_list.push_back(xpos_pm);
+
+	//	Attribute : ZPosPM
+	ZPosPMAttrib	*zpos_pm = new ZPosPMAttrib();
+	Tango::UserDefaultAttrProp	zpos_pm_prop;
+	zpos_pm_prop.set_label("Z Post Mortem Data");
+	zpos_pm_prop.set_unit("mm");
+	zpos_pm_prop.set_standard_unit("mm");
+	zpos_pm_prop.set_display_unit("mm");
+	zpos_pm_prop.set_format("%8.4f");
+	zpos_pm_prop.set_description("Post Mortem : Z pos.");
+	zpos_pm->set_default_properties(zpos_pm_prop);
+	att_list.push_back(zpos_pm);
+
+	//	Attribute : QuadPM
+	QuadPMAttrib	*quad_pm = new QuadPMAttrib();
+	Tango::UserDefaultAttrProp	quad_pm_prop;
+	quad_pm_prop.set_label("Quad Post Mortem Data");
+	quad_pm_prop.set_unit("a.u");
+	quad_pm_prop.set_standard_unit("a.u");
+	quad_pm_prop.set_display_unit("a.u");
+	quad_pm_prop.set_format("%8.4f");
+	quad_pm_prop.set_description("Post Mortem : Quad");
+	quad_pm->set_default_properties(quad_pm_prop);
+	att_list.push_back(quad_pm);
+
+	//	Attribute : SumPM
+	SumPMAttrib	*sum_pm = new SumPMAttrib();
+	Tango::UserDefaultAttrProp	sum_pm_prop;
+	sum_pm_prop.set_label("Sum Post Mortem Data");
+	sum_pm_prop.set_unit("a.u");
+	sum_pm_prop.set_standard_unit("a.u");
+	sum_pm_prop.set_display_unit("a.u");
+	sum_pm_prop.set_format("%10.0f");
+	sum_pm_prop.set_description("Post Mortem : Sum");
+	sum_pm->set_default_properties(sum_pm_prop);
+	att_list.push_back(sum_pm);
+
+	//	Attribute : VaPM
+	VaPMAttrib	*va_pm = new VaPMAttrib();
+	Tango::UserDefaultAttrProp	va_pm_prop;
+	va_pm_prop.set_label("Va Post Mortem Data");
+	va_pm_prop.set_unit("a.u.");
+	va_pm_prop.set_standard_unit("a.u.");
+	va_pm_prop.set_display_unit("a.u.");
+	va_pm_prop.set_format("%10.0f");
+	va_pm_prop.set_description("Post Mortem : Va");
+	va_pm->set_default_properties(va_pm_prop);
+	att_list.push_back(va_pm);
+
+	//	Attribute : VbPM
+	VbPMAttrib	*vb_pm = new VbPMAttrib();
+	Tango::UserDefaultAttrProp	vb_pm_prop;
+	vb_pm_prop.set_label("Vb Post Mortem Data");
+	vb_pm_prop.set_unit("a.u.");
+	vb_pm_prop.set_standard_unit("a.u.");
+	vb_pm_prop.set_display_unit("a.u.");
+	vb_pm_prop.set_format("%10.0f");
+	vb_pm_prop.set_description("Post Mortem : Vb");
+	vb_pm->set_default_properties(vb_pm_prop);
+	att_list.push_back(vb_pm);
+
+	//	Attribute : VcPM
+	VcPMAttrib	*vc_pm = new VcPMAttrib();
+	Tango::UserDefaultAttrProp	vc_pm_prop;
+	vc_pm_prop.set_label("Post Mortem : Vc");
+	vc_pm_prop.set_unit("a.u.");
+	vc_pm_prop.set_standard_unit("a.u.");
+	vc_pm_prop.set_display_unit("a.u.");
+	vc_pm_prop.set_format("%10.0f");
+	vc_pm_prop.set_description("Post Mortem : Vc");
+	vc_pm->set_default_properties(vc_pm_prop);
+	att_list.push_back(vc_pm);
+
+	//	Attribute : VdPM
+	VdPMAttrib	*vd_pm = new VdPMAttrib();
+	Tango::UserDefaultAttrProp	vd_pm_prop;
+	vd_pm_prop.set_label("Vd Post Mortem Data");
+	vd_pm_prop.set_unit("a.u.");
+	vd_pm_prop.set_standard_unit("a.u.");
+	vd_pm_prop.set_display_unit("a.u.");
+	vd_pm_prop.set_format("%10.0f");
+	vd_pm_prop.set_description("Post Mortem : Vd");
+	vd_pm->set_default_properties(vd_pm_prop);
+	att_list.push_back(vd_pm);
+
+	//	Attribute : ADCChannelA
+	ADCChannelAAttrib	*adcchannel_a = new ADCChannelAAttrib();
+	Tango::UserDefaultAttrProp	adcchannel_a_prop;
+	adcchannel_a_prop.set_label("ADC Channel A");
+	adcchannel_a_prop.set_unit("a.u");
+	adcchannel_a_prop.set_standard_unit("a.u");
+	adcchannel_a_prop.set_display_unit("a.u");
+	adcchannel_a_prop.set_format("%8d");
+	adcchannel_a_prop.set_description("ADC values for pickup A");
+	adcchannel_a->set_default_properties(adcchannel_a_prop);
+	att_list.push_back(adcchannel_a);
+
+	//	Attribute : ADCChannelB
+	ADCChannelBAttrib	*adcchannel_b = new ADCChannelBAttrib();
+	Tango::UserDefaultAttrProp	adcchannel_b_prop;
+	adcchannel_b_prop.set_label("ADC Channel B");
+	adcchannel_b_prop.set_unit("a.u");
+	adcchannel_b_prop.set_standard_unit("a.u");
+	adcchannel_b_prop.set_display_unit("a.u");
+	adcchannel_b_prop.set_format("%8d");
+	adcchannel_b_prop.set_description("ADC values for pickup B");
+	adcchannel_b->set_default_properties(adcchannel_b_prop);
+	att_list.push_back(adcchannel_b);
+
+	//	Attribute : ADCChannelC
+	ADCChannelCAttrib	*adcchannel_c = new ADCChannelCAttrib();
+	Tango::UserDefaultAttrProp	adcchannel_c_prop;
+	adcchannel_c_prop.set_label("ADC Channel C");
+	adcchannel_c_prop.set_unit("a.u");
+	adcchannel_c_prop.set_standard_unit("a.u");
+	adcchannel_c_prop.set_display_unit("a.u");
+	adcchannel_c_prop.set_format("%8d");
+	adcchannel_c_prop.set_description("ADC values for pickup C");
+	adcchannel_c->set_default_properties(adcchannel_c_prop);
+	att_list.push_back(adcchannel_c);
+
+	//	Attribute : ADCChannelD
+	ADCChannelDAttrib	*adcchannel_d = new ADCChannelDAttrib();
+	Tango::UserDefaultAttrProp	adcchannel_d_prop;
+	adcchannel_d_prop.set_label("ADC Channel D");
+	adcchannel_d_prop.set_unit("a.u");
+	adcchannel_d_prop.set_standard_unit("a.u");
+	adcchannel_d_prop.set_display_unit("a.u");
+	adcchannel_d_prop.set_format("%8d");
+	adcchannel_d_prop.set_description("ADC values for pickup D");
+	adcchannel_d->set_default_properties(adcchannel_d_prop);
+	att_list.push_back(adcchannel_d);
+
+	//	Attribute : IaDD
+	IaDDAttrib	*ia_dd = new IaDDAttrib();
+	Tango::UserDefaultAttrProp	ia_dd_prop;
+	ia_dd_prop.set_label("DD Ia");
+	ia_dd_prop.set_unit("a.u.");
+	ia_dd_prop.set_format("%10.0f");
+	ia_dd_prop.set_description("Turn by turn data: Ia");
+	ia_dd->set_default_properties(ia_dd_prop);
+	att_list.push_back(ia_dd);
+
+	//	Attribute : IbDD
+	IbDDAttrib	*ib_dd = new IbDDAttrib();
+	Tango::UserDefaultAttrProp	ib_dd_prop;
+	ib_dd_prop.set_label("DD Ib");
+	ib_dd_prop.set_unit("a.u.");
+	ib_dd_prop.set_format("%10.0f");
+	ib_dd_prop.set_description("Turn by turn data: Ib");
+	ib_dd->set_default_properties(ib_dd_prop);
+	att_list.push_back(ib_dd);
+
+	//	Attribute : IcDD
+	IcDDAttrib	*ic_dd = new IcDDAttrib();
+	Tango::UserDefaultAttrProp	ic_dd_prop;
+	ic_dd_prop.set_label("DD Ic");
+	ic_dd_prop.set_unit("a.u.");
+	ic_dd_prop.set_format("%10.0f");
+	ic_dd_prop.set_description("Turn by turn data: Ic");
+	ic_dd->set_default_properties(ic_dd_prop);
+	att_list.push_back(ic_dd);
+
+	//	Attribute : IdDD
+	IdDDAttrib	*id_dd = new IdDDAttrib();
+	Tango::UserDefaultAttrProp	id_dd_prop;
+	id_dd_prop.set_label("DD Id");
+	id_dd_prop.set_unit("a.u.");
+	id_dd_prop.set_format("%10.0f");
+	id_dd_prop.set_description("Turn by turn data: Id");
+	id_dd->set_default_properties(id_dd_prop);
+	att_list.push_back(id_dd);
+
+	//	Attribute : QaDD
+	QaDDAttrib	*qa_dd = new QaDDAttrib();
+	Tango::UserDefaultAttrProp	qa_dd_prop;
+	qa_dd_prop.set_label("DD Qa");
+	qa_dd_prop.set_unit("a.u.");
+	qa_dd_prop.set_format("%10.0f");
+	qa_dd_prop.set_description("Turn by turn data: Qa");
+	qa_dd->set_default_properties(qa_dd_prop);
+	att_list.push_back(qa_dd);
+
+	//	Attribute : QbDD
+	QbDDAttrib	*qb_dd = new QbDDAttrib();
+	Tango::UserDefaultAttrProp	qb_dd_prop;
+	qb_dd_prop.set_label("DD Qb");
+	qb_dd_prop.set_unit("a.u.");
+	qb_dd_prop.set_format("%10.0f");
+	qb_dd_prop.set_description("Turn by turn data: Qb");
+	qb_dd->set_default_properties(qb_dd_prop);
+	att_list.push_back(qb_dd);
+
+	//	Attribute : QcDD
+	QcDDAttrib	*qc_dd = new QcDDAttrib();
+	Tango::UserDefaultAttrProp	qc_dd_prop;
+	qc_dd_prop.set_label("DD Qc");
+	qc_dd_prop.set_unit("a.u.");
+	qc_dd_prop.set_format("%10.0f");
+	qc_dd_prop.set_description("Turn by turn data: Qc");
+	qc_dd->set_default_properties(qc_dd_prop);
+	att_list.push_back(qc_dd);
+
+	//	Attribute : QdDD
+	QdDDAttrib	*qd_dd = new QdDDAttrib();
+	Tango::UserDefaultAttrProp	qd_dd_prop;
+	qd_dd_prop.set_label("DD Qd");
+	qd_dd_prop.set_unit("a.u.");
+	qd_dd_prop.set_format("%10.0f");
+	qd_dd_prop.set_description("Turn by turn data: Qd");
+	qd_dd->set_default_properties(qd_dd_prop);
+	att_list.push_back(qd_dd);
+
+	//	Attribute : UserData
+	UserDataAttrib	*user_data = new UserDataAttrib();
+	Tango::UserDefaultAttrProp	user_data_prop;
+	user_data_prop.set_description("User defined data");
+	user_data->set_default_properties(user_data_prop);
+	att_list.push_back(user_data);
+
+	//	Attribute : InterlockConfiguration
+	InterlockConfigurationAttrib	*interlock_configuration = new InterlockConfigurationAttrib();
+	Tango::UserDefaultAttrProp	interlock_configuration_prop;
+	interlock_configuration_prop.set_description("The current interlock configuration. The vector mapping is the follwoing:\n[0] Mode : [0]: disabled, [1]: enabled, [3]: enabled with gain dependency\n[1] X low threshold in mm\n[2] X high threshold in mm\n[3] Z threshold low in mm \n[4] Z high threshold in mm\n[5] Overflow limit (ADC threshold)\n[6] Overflow duration (num of overloaded ADC samples before raising interlock)\n[7] Gain limit in dBm  (no interlock under this threshold) ");
+	interlock_configuration->set_default_properties(interlock_configuration_prop);
+	att_list.push_back(interlock_configuration);
+
+	//	Attribute : logs
+	logsAttrib	*logs = new logsAttrib();
+	att_list.push_back(logs);
+
+	//	End of Automatic code generation
+	//-------------------------------------------------------------
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::get_class_property()
+// 
+// description : 	Read the class properties from database.
+//
+//-----------------------------------------------------------------------------
+void LiberaClass::get_class_property()
+{
+	//	Initialize your default values here (if not done with  POGO).
+	//------------------------------------------------------------------
+
+	//	Read class properties from database.(Automatic code generation)
+	//------------------------------------------------------------------
+	cl_prop.push_back(Tango::DbDatum("InterlockConfiguration"));
+	cl_prop.push_back(Tango::DbDatum("EnableDDOptionalData"));
+	cl_prop.push_back(Tango::DbDatum("EnableSAOptionalData"));
+	cl_prop.push_back(Tango::DbDatum("EnableSAHistoryOptionalData"));
+	cl_prop.push_back(Tango::DbDatum("EnableADCOptionalData"));
+	cl_prop.push_back(Tango::DbDatum("Institute"));
+
+	//	Call database and extract values
+	//--------------------------------------------
+	if (Tango::Util::instance()->_UseDb==true)
+		get_db_class()->get_property(cl_prop);
+	Tango::DbDatum	def_prop;
+	int	i = -1;
+
+	//	Try to extract InterlockConfiguration value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  interlockConfiguration;
+	else
+	{
+		//	Check default value for InterlockConfiguration
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  interlockConfiguration;
+			cl_prop[i]  <<  interlockConfiguration;
+		}
+	}
+
+	//	Try to extract EnableDDOptionalData value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  enableDDOptionalData;
+	else
+	{
+		//	Check default value for EnableDDOptionalData
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  enableDDOptionalData;
+			cl_prop[i]  <<  enableDDOptionalData;
+		}
+	}
+
+	//	Try to extract EnableSAOptionalData value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  enableSAOptionalData;
+	else
+	{
+		//	Check default value for EnableSAOptionalData
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  enableSAOptionalData;
+			cl_prop[i]  <<  enableSAOptionalData;
+		}
+	}
+
+	//	Try to extract EnableSAHistoryOptionalData value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  enableSAHistoryOptionalData;
+	else
+	{
+		//	Check default value for EnableSAHistoryOptionalData
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  enableSAHistoryOptionalData;
+			cl_prop[i]  <<  enableSAHistoryOptionalData;
+		}
+	}
+
+	//	Try to extract EnableADCOptionalData value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  enableADCOptionalData;
+	else
+	{
+		//	Check default value for EnableADCOptionalData
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  enableADCOptionalData;
+			cl_prop[i]  <<  enableADCOptionalData;
+		}
+	}
+
+	//	Try to extract Institute value
+	if (cl_prop[++i].is_empty()==false)	cl_prop[i]  >>  institute;
+	else
+	{
+		//	Check default value for Institute
+		def_prop = get_default_class_property(cl_prop[i].name);
+		if (def_prop.is_empty()==false)
+		{
+			def_prop  >>  institute;
+			cl_prop[i]  <<  institute;
+		}
+	}
+
+	//	End of Automatic code generation
+	//------------------------------------------------------------------
+
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 	LiberaClass::set_default_property
+// 
+// description: Set default property (class and device) for wizard.
+//              For each property, add to wizard property name and description
+//              If default value has been set, add it to wizard property and
+//              store it in a DbDatum.
+//
+//-----------------------------------------------------------------------------
+void LiberaClass::set_default_property()
+{
+	string	prop_name;
+	string	prop_desc;
+	string	prop_def;
+
+	vector<string>	vect_data;
+	//	Set Default Class Properties
+	prop_name = "InterlockConfiguration";
+	prop_desc = "The user defined interlock configuration. This is the configuration that should be applied on the Libera in case the device 'finds'\nthe Libera in its default startup configuration when it is itself starting up or executing its Init TANGO command. This configuration\ncan also be applied using the dedicated \"SetInterlockConfiguration\" expert command.\nParameters mapping:\n[0] Interlock : mode - [0]: disabled, [1]: enabled, [3]: enabled with gain dependency\n[1] Interlock : threshold : X low in mm\n[2] Interlock : threshold : X high in mm\n[3] Interlock : threshold : Z low in mm (i.e. Y low in the Libera terminology)\n[4] Interlock : threshold : Z high in mm (i.e. Y high in the Libera terminology)\n[5] Interlock : overflow limit (ADC threshold)\n[6] Interlock : overflow duration (num of overloaded ADC samples before raising intlck)\n[7] Interlock : gain limit in dBm  (intlck not active under this limit) - valid range is [-60, 0]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	prop_name = "EnableDDOptionalData";
+	prop_desc = "Enables/Disables  DD optional data (IxDD and QxDD)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	prop_name = "EnableSAOptionalData";
+	prop_desc = "Enables/disables SA optional Data (currently not used)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	prop_name = "EnableSAHistoryOptionalData";
+	prop_desc = "Enables/disables SA History optional data (sum history)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	prop_name = "EnableADCOptionalData";
+	prop_desc = "Enables/disables ADC optional data (currently not used)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	prop_name = "Institute";
+	prop_desc = "0: TANGO_INSTITUTE (GENERIC)\n1: ALBA\n2: ESRF\n3: ELETTRA\n4: SOLEIL";
+	prop_def  = "0";
+	vect_data.clear();
+	vect_data.push_back("0");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		cl_def_prop.push_back(data);
+		add_wiz_class_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_class_prop(prop_name, prop_desc);
+
+	//	Set Default Device Properties
+	prop_name = "LiberaIpAddr";
+	prop_desc = "The Libera IP address [no default value]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "LiberaPort";
+	prop_desc = "The port on which the generic server handles external requests. Defaults to 23721.";
+	prop_def  = "23271";
+	vect_data.clear();
+	vect_data.push_back("23271");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DefaultDDBufferSize";
+	prop_desc = "Default [or initial] value for attribute DDBufferSize [in samples]. Defaults to 1024.";
+	prop_def  = "1024";
+	vect_data.clear();
+	vect_data.push_back("1024");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "Switches";
+	prop_desc = "Switches configuration. The valid range is [0..15]. Defaults to 3.";
+	prop_def  = "3";
+	vect_data.clear();
+	vect_data.push_back("3");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "LiberaMulticastIpAddr";
+	prop_desc = "Asynch. notifications (e.g. trigger events) will be send to this addr [no default value]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "Location";
+	prop_desc = "The BPM location [TL1, BOOSTER, TL2 or STORAGE_RING]. No default value.";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableExternalTrigger";
+	prop_desc = "Enables (or not) the external trigger source.\nInlfuences the TANGO device behaviour not the Libera itself. Defaults to false.";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DDTaskActivityPeriod";
+	prop_desc = "Specify the watch-dog (1) or data reading period (2) in ms.\nMust be in the rangec [500, 25000] ms. Defaults to 1000.\n(1) : external trigger enabled - (2) : external trigger disabled.";
+	prop_def  = "1000";
+	vect_data.clear();
+	vect_data.push_back("1000");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "SATaskActivityPeriod";
+	prop_desc = "Specify the watch-dog (1) or data reading period (2) in ms.\nMust be in the range [100, 25000] ms. Defaults to 100.";
+	prop_def  = "100";
+	vect_data.clear();
+	vect_data.push_back("100");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableDD";
+	prop_desc = "Specifies whether or not the DD data source should be enabled at startup. Defaults to false.";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableSA";
+	prop_desc = "Specifies whether or not the SA data source should be enabled at startup. Defaults to false.";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "SAHistoryLength";
+	prop_desc = "SA history buffer length [in samples]. Defaults to 8196.";
+	prop_def  = "512";
+	vect_data.clear();
+	vect_data.push_back("512");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DDDecimationFactor";
+	prop_desc = "The DD decimation factor.\nAllowed values : 1 (no decimation) or 64 (for the so called booster normal mode)";
+	prop_def  = "1";
+	vect_data.clear();
+	vect_data.push_back("1");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableAutoSwitchingIfSAEnabled";
+	prop_desc = "When set to TRUE, auto-switching is automattically enabled when the SA data source is itself enabled";
+	prop_def  = "true";
+	vect_data.clear();
+	vect_data.push_back("true");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableDSCIfAutoSwitchingEnabled";
+	prop_desc = "When set to TRUE, the Digital Signal Conditioning is automattically enabled when the auto-switching is itself enabled";
+	prop_def  = "true";
+	vect_data.clear();
+	vect_data.push_back("true");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DefaultSAStatNumSamples";
+	prop_desc = "Default number of SA history samples to use form RMS pos. computation.\nDefaults to 10 (last second in the SA history).";
+	prop_def  = "256";
+	vect_data.clear();
+	vect_data.push_back("256");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DefaultADCBufferSize";
+	prop_desc = "Default [or initial] value for attribute ADCBufferSize [in samples]. Defaults to 1024.";
+	prop_def  = "1024";
+	vect_data.clear();
+	vect_data.push_back("1024");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "ADCTaskActivityPeriod";
+	prop_desc = "Specifies the data reading period in ms.\nMust be in the range [500, 25000] ms. Defaults to 1000.\n";
+	prop_def  = "1000";
+	vect_data.clear();
+	vect_data.push_back("1000");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableADC";
+	prop_desc = "Specifies whether or not the ADC data source should be enabled at startup. Defaults to false.";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "DefaultTimePhaseValue";
+	prop_desc = "Default value for the machine time phase. Its valid range is [0, RfSfRatio - 1] where\nRfSfRatio is a machine dependent system property.";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "InterlockConfiguration";
+	prop_desc = "The user defined interlock configuration. This is the configuration that should be applied on the Libera in case the device 'finds'\nthe Libera in its default startup configuration when it is itself starting up or executing its Init TANGO command. This configuration\ncan also be applied using the dedicated 'SetInterlockConfiguration' expert command.\nParameters mapping:\n[0] Interlock : mode - [0]: disabled, [1]: enabled, [3]: enabled with gain dependency\n[1] Interlock : threshold : X low in mm\n[2] Interlock : threshold : X high in mm\n[3] Interlock : threshold : Z low in mm (i.e. Y low in the Libera terminology)\n[4] Interlock : threshold : Z high in mm (i.e. Y high in the Libera terminology)\n[5] Interlock : overflow limit (ADC threshold)\n[6] Interlock : overflow duration (num of overloaded ADC samples before raising intlck)\n[7] Interlock : gain limit in dBm  (intlck not active under this limit) - valid range is [-60, 0]";
+	prop_def  = "";
+	vect_data.clear();
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableDDOptionalData";
+	prop_desc = "Enables/Disables  DD optional data (IxDD and QxDD)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableSAOptionalData";
+	prop_desc = "Enables/disables SA optional Data (currently not used)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableSAHistoryOptionalData";
+	prop_desc = "Enables/disables SA History optional data (sum history)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "EnableADCOptionalData";
+	prop_desc = "Enables/disables ADC optional data (currently not used)";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "Institute";
+	prop_desc = "0: TANGO_INSTITUTE (GENERIC)\n1: ALBA\n2: ESRF\n3: ELETTRA\n4: SOLEIL";
+	prop_def  = "0";
+	vect_data.clear();
+	vect_data.push_back("0");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "MaxDDBufferSizeWhenDecimationEnabled";
+	prop_desc = "Max. DD buffer size when decimation enabled on DD data source.\nDefaults to 10000";
+	prop_def  = "16384";
+	vect_data.clear();
+	vect_data.push_back("16384");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "PassBBAOffsetsToFPGA";
+	prop_desc = "Controls wether or not the BBA offsets are taken into account when computing the offsets passed to the FPGA process";
+	prop_def  = "false";
+	vect_data.clear();
+	vect_data.push_back("false");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+	prop_name = "FADataCacheRefreshPeriod";
+	prop_desc = "The <FA Data> cache refresh period in msecs.\nDefaults to 500 ms (2Hz).";
+	prop_def  = "500";
+	vect_data.clear();
+	vect_data.push_back("500");
+	if (prop_def.length()>0)
+	{
+		Tango::DbDatum	data(prop_name);
+		data << vect_data ;
+		dev_def_prop.push_back(data);
+		add_wiz_dev_prop(prop_name, prop_desc,  prop_def);
+	}
+	else
+		add_wiz_dev_prop(prop_name, prop_desc);
+
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		LiberaClass::write_class_property
+// 
+// description : 	Set class description as property in database
+//
+//-----------------------------------------------------------------------------
+void LiberaClass::write_class_property()
+{
+	//	First time, check if database used
+	//--------------------------------------------
+	if (Tango::Util::_UseDb == false)
+		return;
+
+	Tango::DbData	data;
+	string	classname = get_name();
+	string	header;
+	string::size_type	start, end;
+
+	//	Put title
+	Tango::DbDatum	title("ProjectTitle");
+	string	str_title("Libera BPM Device Server");
+	title << str_title;
+	data.push_back(title);
+
+	//	Put Description
+	Tango::DbDatum	description("Description");
+	vector<string>	str_desc;
+	str_desc.push_back("IT Libera BPM Device Server");
+	description << str_desc;
+	data.push_back(description);
+		
+	//	put cvs or svn location
+	string	filename(classname);
+	filename += "Class.cpp";
+	
+	// Create a string with the class ID to
+	// get the string into the binary
+	string	class_id(ClassId);
+	
+	// check for cvs information
+	string	src_path(CvsPath);
+	start = src_path.find("/");
+	if (start!=string::npos)
+	{
+		end   = src_path.find(filename);
+		if (end>start)
+		{
+			string	strloc = src_path.substr(start, end-start);
+			//	Check if specific repository
+			start = strloc.find("/cvsroot/");
+			if (start!=string::npos && start>0)
+			{
+				string	repository = strloc.substr(0, start);
+				if (repository.find("/segfs/")!=string::npos)
+					strloc = "ESRF:" + strloc.substr(start, strloc.length()-start);
+			}
+			Tango::DbDatum	cvs_loc("cvs_location");
+			cvs_loc << strloc;
+			data.push_back(cvs_loc);
+		}
+	}
+	// check for svn information
+	else
+	{
+		string	src_path(SvnPath);
+		start = src_path.find("://");
+		if (start!=string::npos)
+		{
+			end = src_path.find(filename);
+			if (end>start)
+			{
+				header = "$HeadURL: ";
+				start = header.length();
+				string	strloc = src_path.substr(start, (end-start));
+				
+				Tango::DbDatum	svn_loc("svn_location");
+				svn_loc << strloc;
+				data.push_back(svn_loc);
+			}
+		}
+	}
+
+	//	Get CVS or SVN revision tag
+	
+	// CVS tag
+	string	tagname(TagName);
+	header = "$Name: ";
+	start = header.length();
+	string	endstr(" $");
+	
+	end   = tagname.find(endstr);
+	if (end!=string::npos && end>start)
+	{
+		string	strtag = tagname.substr(start, end-start);
+		Tango::DbDatum	cvs_tag("cvs_tag");
+		cvs_tag << strtag;
+		data.push_back(cvs_tag);
+	}
+	
+	// SVN tag
+	string	svnpath(SvnPath);
+	header = "$HeadURL: ";
+	start = header.length();
+	
+	end   = svnpath.find(endstr);
+	if (end!=string::npos && end>start)
+	{
+		string	strloc = svnpath.substr(start, end-start);
+		
+		string tagstr ("/tags/");
+		start = strloc.find(tagstr);
+		if ( start!=string::npos )
+		{
+			start = start + tagstr.length();
+			end   = strloc.find(filename);
+			string	strtag = strloc.substr(start, end-start-1);
+			
+			Tango::DbDatum	svn_tag("svn_tag");
+			svn_tag << strtag;
+			data.push_back(svn_tag);
+		}
+	}
+
+	//	Get URL location
+	string	httpServ(HttpServer);
+	if (httpServ.length()>0)
+	{
+		Tango::DbDatum	db_doc_url("doc_url");
+		db_doc_url << httpServ;
+		data.push_back(db_doc_url);
+	}
+
+	//  Put inheritance
+	Tango::DbDatum	inher_datum("InheritedFrom");
+	vector<string> inheritance;
+	inheritance.push_back("Device_4Impl");
+	inher_datum << inheritance;
+	data.push_back(inher_datum);
+
+	//	Call database and and values
+	//--------------------------------------------
+	get_db_class()->put_property(data);
+}
+
+}	// namespace
diff --git a/src/LiberaClass.h b/src/LiberaClass.h
new file mode 100644
index 0000000000000000000000000000000000000000..d84c6beace760b3154cb3432849403c8e6349775
--- /dev/null
+++ b/src/LiberaClass.h
@@ -0,0 +1,1907 @@
+//=============================================================================
+//
+// file :         LiberaClass.h
+//
+// description :  Include for the LiberaClass root class.
+//                This class is represents the singleton class for
+//                the Libera device class.
+//                It contains all properties and methods which the
+//                Libera requires only once e.g. the commands.
+//
+// project :      TANGO Device Server
+//
+// $Author: nleclercq $
+//
+// copyleft :     Synchrotron SOLEIL
+//                L'Orme des Merisiers
+//                Saint-Aubin - BP 48
+//
+//=============================================================================
+//
+//      This file is generated by POGO
+//  (Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#ifndef _LIBERACLASS_H
+#define _LIBERACLASS_H
+
+#include <tango.h>
+#include <Libera.h>
+
+namespace Libera_ns
+{
+//=====================================
+//	Define classes for attributes
+//=====================================
+class logsAttrib: public Tango::SpectrumAttr
+{
+public:
+	logsAttrib():SpectrumAttr("logs", Tango::DEV_STRING, Tango::READ, 2048) {};
+	~logsAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_logs(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_logs_allowed(ty);}
+};
+
+class InterlockConfigurationAttrib: public Tango::SpectrumAttr
+{
+public:
+	InterlockConfigurationAttrib():SpectrumAttr("InterlockConfiguration", Tango::DEV_DOUBLE, Tango::READ, 8) {};
+	~InterlockConfigurationAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockConfiguration(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockConfiguration_allowed(ty);}
+};
+
+class UserDataAttrib: public Tango::SpectrumAttr
+{
+public:
+	UserDataAttrib():SpectrumAttr("UserData", Tango::DEV_SHORT, Tango::READ, 256) {};
+	~UserDataAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_UserData(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_UserData_allowed(ty);}
+};
+
+class QdDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	QdDDAttrib():SpectrumAttr("QdDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~QdDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QdDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QdDD_allowed(ty);}
+};
+
+class QcDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	QcDDAttrib():SpectrumAttr("QcDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~QcDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QcDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QcDD_allowed(ty);}
+};
+
+class QbDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	QbDDAttrib():SpectrumAttr("QbDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~QbDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QbDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QbDD_allowed(ty);}
+};
+
+class QaDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	QaDDAttrib():SpectrumAttr("QaDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~QaDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QaDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QaDD_allowed(ty);}
+};
+
+class IdDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	IdDDAttrib():SpectrumAttr("IdDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~IdDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_IdDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_IdDD_allowed(ty);}
+};
+
+class IcDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	IcDDAttrib():SpectrumAttr("IcDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~IcDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_IcDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_IcDD_allowed(ty);}
+};
+
+class IbDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	IbDDAttrib():SpectrumAttr("IbDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~IbDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_IbDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_IbDD_allowed(ty);}
+};
+
+class IaDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	IaDDAttrib():SpectrumAttr("IaDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~IaDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_IaDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_IaDD_allowed(ty);}
+};
+
+class ADCChannelDAttrib: public Tango::SpectrumAttr
+{
+public:
+	ADCChannelDAttrib():SpectrumAttr("ADCChannelD", Tango::DEV_SHORT, Tango::READ, 250000) {};
+	~ADCChannelDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCChannelD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCChannelD_allowed(ty);}
+};
+
+class ADCChannelCAttrib: public Tango::SpectrumAttr
+{
+public:
+	ADCChannelCAttrib():SpectrumAttr("ADCChannelC", Tango::DEV_SHORT, Tango::READ, 250000) {};
+	~ADCChannelCAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCChannelC(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCChannelC_allowed(ty);}
+};
+
+class ADCChannelBAttrib: public Tango::SpectrumAttr
+{
+public:
+	ADCChannelBAttrib():SpectrumAttr("ADCChannelB", Tango::DEV_SHORT, Tango::READ, 250000) {};
+	~ADCChannelBAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCChannelB(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCChannelB_allowed(ty);}
+};
+
+class ADCChannelAAttrib: public Tango::SpectrumAttr
+{
+public:
+	ADCChannelAAttrib():SpectrumAttr("ADCChannelA", Tango::DEV_SHORT, Tango::READ, 250000) {};
+	~ADCChannelAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCChannelA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCChannelA_allowed(ty);}
+};
+
+class VdPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	VdPMAttrib():SpectrumAttr("VdPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~VdPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VdPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VdPM_allowed(ty);}
+};
+
+class VcPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	VcPMAttrib():SpectrumAttr("VcPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~VcPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VcPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VcPM_allowed(ty);}
+};
+
+class VbPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	VbPMAttrib():SpectrumAttr("VbPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~VbPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VbPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VbPM_allowed(ty);}
+};
+
+class VaPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	VaPMAttrib():SpectrumAttr("VaPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~VaPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VaPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VaPM_allowed(ty);}
+};
+
+class SumPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	SumPMAttrib():SpectrumAttr("SumPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~SumPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SumPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SumPM_allowed(ty);}
+};
+
+class QuadPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	QuadPMAttrib():SpectrumAttr("QuadPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~QuadPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QuadPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QuadPM_allowed(ty);}
+};
+
+class ZPosPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	ZPosPMAttrib():SpectrumAttr("ZPosPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~ZPosPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZPosPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZPosPM_allowed(ty);}
+};
+
+class XPosPMAttrib: public Tango::SpectrumAttr
+{
+public:
+	XPosPMAttrib():SpectrumAttr("XPosPM", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~XPosPMAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XPosPM(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XPosPM_allowed(ty);}
+};
+
+class SumSAHistoryAttrib: public Tango::SpectrumAttr
+{
+public:
+	SumSAHistoryAttrib():SpectrumAttr("SumSAHistory", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~SumSAHistoryAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SumSAHistory(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SumSAHistory_allowed(ty);}
+};
+
+class ZPosSAHistoryAttrib: public Tango::SpectrumAttr
+{
+public:
+	ZPosSAHistoryAttrib():SpectrumAttr("ZPosSAHistory", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~ZPosSAHistoryAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZPosSAHistory(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZPosSAHistory_allowed(ty);}
+};
+
+class XPosSAHistoryAttrib: public Tango::SpectrumAttr
+{
+public:
+	XPosSAHistoryAttrib():SpectrumAttr("XPosSAHistory", Tango::DEV_DOUBLE, Tango::READ, 16384) {};
+	~XPosSAHistoryAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XPosSAHistory(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XPosSAHistory_allowed(ty);}
+};
+
+class VdDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	VdDDAttrib():SpectrumAttr("VdDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~VdDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VdDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VdDD_allowed(ty);}
+};
+
+class VcDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	VcDDAttrib():SpectrumAttr("VcDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~VcDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VcDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VcDD_allowed(ty);}
+};
+
+class VbDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	VbDDAttrib():SpectrumAttr("VbDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~VbDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VbDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VbDD_allowed(ty);}
+};
+
+class VaDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	VaDDAttrib():SpectrumAttr("VaDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~VaDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VaDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VaDD_allowed(ty);}
+};
+
+class SumDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	SumDDAttrib():SpectrumAttr("SumDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~SumDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SumDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SumDD_allowed(ty);}
+};
+
+class QuadDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	QuadDDAttrib():SpectrumAttr("QuadDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~QuadDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QuadDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QuadDD_allowed(ty);}
+};
+
+class ZPosDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	ZPosDDAttrib():SpectrumAttr("ZPosDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~ZPosDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZPosDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZPosDD_allowed(ty);}
+};
+
+class XPosDDAttrib: public Tango::SpectrumAttr
+{
+public:
+	XPosDDAttrib():SpectrumAttr("XPosDD", Tango::DEV_DOUBLE, Tango::READ, 250000) {};
+	~XPosDDAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XPosDD(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XPosDD_allowed(ty);}
+};
+
+class UseLiberaSADataAttrib: public Tango::Attr
+{
+public:
+	UseLiberaSADataAttrib():Attr("UseLiberaSAData", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~UseLiberaSADataAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_UseLiberaSAData(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_UseLiberaSAData(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_UseLiberaSAData_allowed(ty);}
+};
+
+class RamFsUsageAttrib: public Tango::Attr
+{
+public:
+	RamFsUsageAttrib():Attr("RamFsUsage", Tango::DEV_LONG, Tango::READ) {};
+	~RamFsUsageAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_RamFsUsage(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_RamFsUsage_allowed(ty);}
+};
+
+class FreeMemoryAttrib: public Tango::Attr
+{
+public:
+	FreeMemoryAttrib():Attr("FreeMemory", Tango::DEV_LONG, Tango::READ) {};
+	~FreeMemoryAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_FreeMemory(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_FreeMemory_allowed(ty);}
+};
+
+class CpuUsageAttrib: public Tango::Attr
+{
+public:
+	CpuUsageAttrib():Attr("CpuUsage", Tango::DEV_LONG, Tango::READ) {};
+	~CpuUsageAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_CpuUsage(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_CpuUsage_allowed(ty);}
+};
+
+class UpTimeAttrib: public Tango::Attr
+{
+public:
+	UpTimeAttrib():Attr("UpTime", Tango::DEV_LONG, Tango::READ) {};
+	~UpTimeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_UpTime(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_UpTime_allowed(ty);}
+};
+
+class MaxIncoherenceDriftAttrib: public Tango::Attr
+{
+public:
+	MaxIncoherenceDriftAttrib():Attr("MaxIncoherenceDrift", Tango::DEV_DOUBLE, Tango::READ_WRITE) {};
+	~MaxIncoherenceDriftAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MaxIncoherenceDrift(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_MaxIncoherenceDrift(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MaxIncoherenceDrift_allowed(ty);}
+};
+
+class MaxIncoherenceAttrib: public Tango::Attr
+{
+public:
+	MaxIncoherenceAttrib():Attr("MaxIncoherence", Tango::DEV_DOUBLE, Tango::READ_WRITE) {};
+	~MaxIncoherenceAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MaxIncoherence(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_MaxIncoherence(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MaxIncoherence_allowed(ty);}
+};
+
+class RefIncoherenceAttrib: public Tango::Attr
+{
+public:
+	RefIncoherenceAttrib():Attr("RefIncoherence", Tango::DEV_DOUBLE, Tango::READ) {};
+	~RefIncoherenceAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_RefIncoherence(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_RefIncoherence_allowed(ty);}
+};
+
+class IncoherenceAttrib: public Tango::Attr
+{
+public:
+	IncoherenceAttrib():Attr("Incoherence", Tango::DEV_DOUBLE, Tango::READ) {};
+	~IncoherenceAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_Incoherence(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_Incoherence_allowed(ty);}
+};
+
+class Fan2SpeedAttrib: public Tango::Attr
+{
+public:
+	Fan2SpeedAttrib():Attr("Fan2Speed", Tango::DEV_SHORT, Tango::READ) {};
+	~Fan2SpeedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_Fan2Speed(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_Fan2Speed_allowed(ty);}
+};
+
+class Fan1SpeedAttrib: public Tango::Attr
+{
+public:
+	Fan1SpeedAttrib():Attr("Fan1Speed", Tango::DEV_SHORT, Tango::READ) {};
+	~Fan1SpeedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_Fan1Speed(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_Fan1Speed_allowed(ty);}
+};
+
+class HWTemperatureAttrib: public Tango::Attr
+{
+public:
+	HWTemperatureAttrib():Attr("HWTemperature", Tango::DEV_SHORT, Tango::READ) {};
+	~HWTemperatureAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_HWTemperature(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_HWTemperature_allowed(ty);}
+};
+
+class MCPLLStatusAttrib: public Tango::Attr
+{
+public:
+	MCPLLStatusAttrib():Attr("MCPLLStatus", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~MCPLLStatusAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MCPLLStatus(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MCPLLStatus_allowed(ty);}
+};
+
+class SCPLLStatusAttrib: public Tango::Attr
+{
+public:
+	SCPLLStatusAttrib():Attr("SCPLLStatus", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~SCPLLStatusAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SCPLLStatus(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SCPLLStatus_allowed(ty);}
+};
+
+class SystemTimeAttrib: public Tango::Attr
+{
+public:
+	SystemTimeAttrib():Attr("SystemTime", Tango::DEV_DOUBLE, Tango::READ_WRITE) {};
+	~SystemTimeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SystemTime(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_SystemTime(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SystemTime_allowed(ty);}
+};
+
+class TimePhaseAttrib: public Tango::Attr
+{
+public:
+	TimePhaseAttrib():Attr("TimePhase", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~TimePhaseAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_TimePhase(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_TimePhase(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_TimePhase_allowed(ty);}
+};
+
+class MachineTimeAttrib: public Tango::Attr
+{
+public:
+	MachineTimeAttrib():Attr("MachineTime", Tango::DEV_DOUBLE, Tango::READ_WRITE) {};
+	~MachineTimeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MachineTime(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_MachineTime(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MachineTime_allowed(ty);}
+};
+
+class MAFDelayAttrib: public Tango::Attr
+{
+public:
+	MAFDelayAttrib():Attr("MAFDelay", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~MAFDelayAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MAFDelay(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_MAFDelay(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MAFDelay_allowed(ty);}
+};
+
+class MAFLengthAttrib: public Tango::Attr
+{
+public:
+	MAFLengthAttrib():Attr("MAFLength", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~MAFLengthAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_MAFLength(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_MAFLength(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_MAFLength_allowed(ty);}
+};
+
+class HasMAFSupportAttrib: public Tango::Attr
+{
+public:
+	HasMAFSupportAttrib():Attr("HasMAFSupport", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~HasMAFSupportAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_HasMAFSupport(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_HasMAFSupport_allowed(ty);}
+};
+
+class GainAttrib: public Tango::Attr
+{
+public:
+	GainAttrib():Attr("Gain", Tango::DEV_DOUBLE, Tango::READ_WRITE) {};
+	~GainAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_Gain(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_Gain(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_Gain_allowed(ty);}
+};
+
+class AGCEnabledAttrib: public Tango::Attr
+{
+public:
+	AGCEnabledAttrib():Attr("AGCEnabled", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~AGCEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_AGCEnabled(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_AGCEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_AGCEnabled_allowed(ty);}
+};
+
+class DSCModeAttrib: public Tango::Attr
+{
+public:
+	DSCModeAttrib():Attr("DSCMode", Tango::DEV_SHORT, Tango::READ_WRITE) {};
+	~DSCModeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DSCMode(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_DSCMode(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DSCMode_allowed(ty);}
+};
+
+class CompensateTuneAttrib: public Tango::Attr
+{
+public:
+	CompensateTuneAttrib():Attr("CompensateTune", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~CompensateTuneAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_CompensateTune(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_CompensateTune(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_CompensateTune_allowed(ty);}
+};
+
+class OffsetTuneAttrib: public Tango::Attr
+{
+public:
+	OffsetTuneAttrib():Attr("OffsetTune", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~OffsetTuneAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_OffsetTune(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_OffsetTune(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_OffsetTune_allowed(ty);}
+};
+
+class SwitchingDelayAttrib: public Tango::Attr
+{
+public:
+	SwitchingDelayAttrib():Attr("SwitchingDelay", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~SwitchingDelayAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SwitchingDelay(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_SwitchingDelay(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SwitchingDelay_allowed(ty);}
+};
+
+class ExternalSwitchingAttrib: public Tango::Attr
+{
+public:
+	ExternalSwitchingAttrib():Attr("ExternalSwitching", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~ExternalSwitchingAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ExternalSwitching(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_ExternalSwitching(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ExternalSwitching_allowed(ty);}
+};
+
+class SwitchesAttrib: public Tango::Attr
+{
+public:
+	SwitchesAttrib():Attr("Switches", Tango::DEV_SHORT, Tango::READ_WRITE) {};
+	~SwitchesAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_Switches(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_Switches(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_Switches_allowed(ty);}
+};
+
+class AutoSwitchingEnabledAttrib: public Tango::Attr
+{
+public:
+	AutoSwitchingEnabledAttrib():Attr("AutoSwitchingEnabled", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~AutoSwitchingEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_AutoSwitchingEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_AutoSwitchingEnabled_allowed(ty);}
+};
+
+class ZHighAttrib: public Tango::Attr
+{
+public:
+	ZHighAttrib():Attr("ZHigh", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZHighAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZHigh(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZHigh_allowed(ty);}
+};
+
+class ZLowAttrib: public Tango::Attr
+{
+public:
+	ZLowAttrib():Attr("ZLow", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZLowAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZLow(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZLow_allowed(ty);}
+};
+
+class XHighAttrib: public Tango::Attr
+{
+public:
+	XHighAttrib():Attr("XHigh", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XHighAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XHigh(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XHigh_allowed(ty);}
+};
+
+class XLowAttrib: public Tango::Attr
+{
+public:
+	XLowAttrib():Attr("XLow", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XLowAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XLow(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XLow_allowed(ty);}
+};
+
+class InterlockADCPostFilterNotifiedAttrib: public Tango::Attr
+{
+public:
+	InterlockADCPostFilterNotifiedAttrib():Attr("InterlockADCPostFilterNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~InterlockADCPostFilterNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockADCPostFilterNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockADCPostFilterNotified_allowed(ty);}
+};
+
+class InterlockADCPreFilterNotifiedAttrib: public Tango::Attr
+{
+public:
+	InterlockADCPreFilterNotifiedAttrib():Attr("InterlockADCPreFilterNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~InterlockADCPreFilterNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockADCPreFilterNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockADCPreFilterNotified_allowed(ty);}
+};
+
+class InterlockAttnNotifiedAttrib: public Tango::Attr
+{
+public:
+	InterlockAttnNotifiedAttrib():Attr("InterlockAttnNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~InterlockAttnNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockAttnNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockAttnNotified_allowed(ty);}
+};
+
+class InterlockZNotifiedAttrib: public Tango::Attr
+{
+public:
+	InterlockZNotifiedAttrib():Attr("InterlockZNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~InterlockZNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockZNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockZNotified_allowed(ty);}
+};
+
+class InterlockXNotifiedAttrib: public Tango::Attr
+{
+public:
+	InterlockXNotifiedAttrib():Attr("InterlockXNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~InterlockXNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_InterlockXNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_InterlockXNotified_allowed(ty);}
+};
+
+class PMNotificationCounterAttrib: public Tango::Attr
+{
+public:
+	PMNotificationCounterAttrib():Attr("PMNotificationCounter", Tango::DEV_SHORT, Tango::READ) {};
+	~PMNotificationCounterAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_PMNotificationCounter(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_PMNotificationCounter_allowed(ty);}
+};
+
+class PMNotifiedAttrib: public Tango::Attr
+{
+public:
+	PMNotifiedAttrib():Attr("PMNotified", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~PMNotifiedAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_PMNotified(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_PMNotified_allowed(ty);}
+};
+
+class PMOffsetAttrib: public Tango::Attr
+{
+public:
+	PMOffsetAttrib():Attr("PMOffset", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~PMOffsetAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_PMOffset(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_PMOffset(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_PMOffset_allowed(ty);}
+};
+
+class ADCBufferSizeAttrib: public Tango::Attr
+{
+public:
+	ADCBufferSizeAttrib():Attr("ADCBufferSize", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~ADCBufferSizeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCBufferSize(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_ADCBufferSize(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCBufferSize_allowed(ty);}
+};
+
+class ADCEnabledAttrib: public Tango::Attr
+{
+public:
+	ADCEnabledAttrib():Attr("ADCEnabled", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~ADCEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ADCEnabled(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_ADCEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ADCEnabled_allowed(ty);}
+};
+
+class SumMeanSAAttrib: public Tango::Attr
+{
+public:
+	SumMeanSAAttrib():Attr("SumMeanSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~SumMeanSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SumMeanSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SumMeanSA_allowed(ty);}
+};
+
+class ZPeakPosSAAttrib: public Tango::Attr
+{
+public:
+	ZPeakPosSAAttrib():Attr("ZPeakPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZPeakPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZPeakPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZPeakPosSA_allowed(ty);}
+};
+
+class XPeakPosSAAttrib: public Tango::Attr
+{
+public:
+	XPeakPosSAAttrib():Attr("XPeakPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XPeakPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XPeakPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XPeakPosSA_allowed(ty);}
+};
+
+class ZRMSPosSAAttrib: public Tango::Attr
+{
+public:
+	ZRMSPosSAAttrib():Attr("ZRMSPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZRMSPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZRMSPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZRMSPosSA_allowed(ty);}
+};
+
+class XRMSPosSAAttrib: public Tango::Attr
+{
+public:
+	XRMSPosSAAttrib():Attr("XRMSPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XRMSPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XRMSPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XRMSPosSA_allowed(ty);}
+};
+
+class ZMeanPosSAAttrib: public Tango::Attr
+{
+public:
+	ZMeanPosSAAttrib():Attr("ZMeanPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZMeanPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZMeanPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZMeanPosSA_allowed(ty);}
+};
+
+class XMeanPosSAAttrib: public Tango::Attr
+{
+public:
+	XMeanPosSAAttrib():Attr("XMeanPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XMeanPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XMeanPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XMeanPosSA_allowed(ty);}
+};
+
+class SAStatNumSamplesAttrib: public Tango::Attr
+{
+public:
+	SAStatNumSamplesAttrib():Attr("SAStatNumSamples", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~SAStatNumSamplesAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SAStatNumSamples(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_SAStatNumSamples(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SAStatNumSamples_allowed(ty);}
+};
+
+class CzSAAttrib: public Tango::Attr
+{
+public:
+	CzSAAttrib():Attr("CzSA", Tango::DEV_LONG, Tango::READ) {};
+	~CzSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_CzSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_CzSA_allowed(ty);}
+};
+
+class CxSAAttrib: public Tango::Attr
+{
+public:
+	CxSAAttrib():Attr("CxSA", Tango::DEV_LONG, Tango::READ) {};
+	~CxSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_CxSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_CxSA_allowed(ty);}
+};
+
+class QuadSAAttrib: public Tango::Attr
+{
+public:
+	QuadSAAttrib():Attr("QuadSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~QuadSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_QuadSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_QuadSA_allowed(ty);}
+};
+
+class SumSAAttrib: public Tango::Attr
+{
+public:
+	SumSAAttrib():Attr("SumSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~SumSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SumSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SumSA_allowed(ty);}
+};
+
+class ZPosSAAttrib: public Tango::Attr
+{
+public:
+	ZPosSAAttrib():Attr("ZPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~ZPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ZPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ZPosSA_allowed(ty);}
+};
+
+class XPosSAAttrib: public Tango::Attr
+{
+public:
+	XPosSAAttrib():Attr("XPosSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~XPosSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_XPosSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_XPosSA_allowed(ty);}
+};
+
+class VdSAAttrib: public Tango::Attr
+{
+public:
+	VdSAAttrib():Attr("VdSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~VdSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VdSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VdSA_allowed(ty);}
+};
+
+class VcSAAttrib: public Tango::Attr
+{
+public:
+	VcSAAttrib():Attr("VcSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~VcSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VcSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VcSA_allowed(ty);}
+};
+
+class VbSAAttrib: public Tango::Attr
+{
+public:
+	VbSAAttrib():Attr("VbSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~VbSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VbSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VbSA_allowed(ty);}
+};
+
+class VaSAAttrib: public Tango::Attr
+{
+public:
+	VaSAAttrib():Attr("VaSA", Tango::DEV_DOUBLE, Tango::READ) {};
+	~VaSAAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_VaSA(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_VaSA_allowed(ty);}
+};
+
+class SAEnabledAttrib: public Tango::Attr
+{
+public:
+	SAEnabledAttrib():Attr("SAEnabled", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~SAEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_SAEnabled(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_SAEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_SAEnabled_allowed(ty);}
+};
+
+class ExternalTriggerDelayAttrib: public Tango::Attr
+{
+public:
+	ExternalTriggerDelayAttrib():Attr("ExternalTriggerDelay", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~ExternalTriggerDelayAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ExternalTriggerDelay(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_ExternalTriggerDelay(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ExternalTriggerDelay_allowed(ty);}
+};
+
+class ExternalTriggerEnabledAttrib: public Tango::Attr
+{
+public:
+	ExternalTriggerEnabledAttrib():Attr("ExternalTriggerEnabled", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~ExternalTriggerEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_ExternalTriggerEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_ExternalTriggerEnabled_allowed(ty);}
+};
+
+class DDTriggerCounterAttrib: public Tango::Attr
+{
+public:
+	DDTriggerCounterAttrib():Attr("DDTriggerCounter", Tango::DEV_LONG, Tango::READ) {};
+	~DDTriggerCounterAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDTriggerCounter(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDTriggerCounter_allowed(ty);}
+};
+
+class DDBufferFrozenAttrib: public Tango::Attr
+{
+public:
+	DDBufferFrozenAttrib():Attr("DDBufferFrozen", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~DDBufferFrozenAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDBufferFrozen(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDBufferFrozen_allowed(ty);}
+};
+
+class DDBufferFreezingEnabledAttrib: public Tango::Attr
+{
+public:
+	DDBufferFreezingEnabledAttrib():Attr("DDBufferFreezingEnabled", Tango::DEV_BOOLEAN, Tango::READ) {};
+	~DDBufferFreezingEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDBufferFreezingEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDBufferFreezingEnabled_allowed(ty);}
+};
+
+class DDTriggerOffsetAttrib: public Tango::Attr
+{
+public:
+	DDTriggerOffsetAttrib():Attr("DDTriggerOffset", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~DDTriggerOffsetAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDTriggerOffset(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_DDTriggerOffset(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDTriggerOffset_allowed(ty);}
+};
+
+class DDDecimationFactorAttrib: public Tango::Attr
+{
+public:
+	DDDecimationFactorAttrib():Attr("DDDecimationFactor", Tango::DEV_USHORT, Tango::READ_WRITE) {};
+	~DDDecimationFactorAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDDecimationFactor(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_DDDecimationFactor(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDDecimationFactor_allowed(ty);}
+};
+
+class DDBufferSizeAttrib: public Tango::Attr
+{
+public:
+	DDBufferSizeAttrib():Attr("DDBufferSize", Tango::DEV_LONG, Tango::READ_WRITE) {};
+	~DDBufferSizeAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDBufferSize(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_DDBufferSize(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDBufferSize_allowed(ty);}
+};
+
+class DDEnabledAttrib: public Tango::Attr
+{
+public:
+	DDEnabledAttrib():Attr("DDEnabled", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {};
+	~DDEnabledAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_DDEnabled(att);}
+	virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att)
+	{(static_cast<Libera *>(dev))->write_DDEnabled(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_DDEnabled_allowed(ty);}
+};
+
+class LiberaModelAttrib: public Tango::Attr
+{
+public:
+	LiberaModelAttrib():Attr("LiberaModel", Tango::DEV_USHORT, Tango::READ) {};
+	~LiberaModelAttrib() {};
+	
+	virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att)
+	{(static_cast<Libera *>(dev))->read_LiberaModel(att);}
+	virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty)
+	{return (static_cast<Libera *>(dev))->is_LiberaModel_allowed(ty);}
+};
+
+//=========================================
+//	Define classes for commands
+//=========================================
+class SetRefIncoherenceCmd : public Tango::Command
+{
+public:
+	SetRefIncoherenceCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	SetRefIncoherenceCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~SetRefIncoherenceCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_SetRefIncoherence_allowed(any);}
+};
+
+
+
+class ReloadSystemPropertiesCmd : public Tango::Command
+{
+public:
+	ReloadSystemPropertiesCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	ReloadSystemPropertiesCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~ReloadSystemPropertiesCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_ReloadSystemProperties_allowed(any);}
+};
+
+
+
+class SaveDSCParametersCmd : public Tango::Command
+{
+public:
+	SaveDSCParametersCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	SaveDSCParametersCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~SaveDSCParametersCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_SaveDSCParameters_allowed(any);}
+};
+
+
+
+class WriteFADataCmd : public Tango::Command
+{
+public:
+	WriteFADataCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	WriteFADataCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~WriteFADataCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_WriteFAData_allowed(any);}
+};
+
+
+
+class ReadFADataCmd : public Tango::Command
+{
+public:
+	ReadFADataCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	ReadFADataCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~ReadFADataCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_ReadFAData_allowed(any);}
+};
+
+
+
+class SetTimeOnNextTriggerCmd : public Tango::Command
+{
+public:
+	SetTimeOnNextTriggerCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	SetTimeOnNextTriggerCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~SetTimeOnNextTriggerCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_SetTimeOnNextTrigger_allowed(any);}
+};
+
+
+
+class DisableADCCmd : public Tango::Command
+{
+public:
+	DisableADCCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	DisableADCCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~DisableADCCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_DisableADC_allowed(any);}
+};
+
+
+
+class EnableADCCmd : public Tango::Command
+{
+public:
+	EnableADCCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	EnableADCCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~EnableADCCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_EnableADC_allowed(any);}
+};
+
+
+
+class SetInterlockConfigurationCmd : public Tango::Command
+{
+public:
+	SetInterlockConfigurationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	SetInterlockConfigurationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~SetInterlockConfigurationCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_SetInterlockConfiguration_allowed(any);}
+};
+
+
+
+class ResetInterlockNotificationCmd : public Tango::Command
+{
+public:
+	ResetInterlockNotificationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	ResetInterlockNotificationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~ResetInterlockNotificationCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_ResetInterlockNotification_allowed(any);}
+};
+
+
+
+class ResetPMNotificationCmd : public Tango::Command
+{
+public:
+	ResetPMNotificationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	ResetPMNotificationCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~ResetPMNotificationCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_ResetPMNotification_allowed(any);}
+};
+
+
+
+class DisableSACmd : public Tango::Command
+{
+public:
+	DisableSACmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	DisableSACmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~DisableSACmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_DisableSA_allowed(any);}
+};
+
+
+
+class EnableSACmd : public Tango::Command
+{
+public:
+	EnableSACmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	EnableSACmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~EnableSACmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_EnableSA_allowed(any);}
+};
+
+
+
+class DisableDDCmd : public Tango::Command
+{
+public:
+	DisableDDCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	DisableDDCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~DisableDDCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_DisableDD_allowed(any);}
+};
+
+
+
+class EnableDDCmd : public Tango::Command
+{
+public:
+	EnableDDCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	EnableDDCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~EnableDDCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_EnableDD_allowed(any);}
+};
+
+
+
+class DisableDDBufferFreezingCmd : public Tango::Command
+{
+public:
+	DisableDDBufferFreezingCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	DisableDDBufferFreezingCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~DisableDDBufferFreezingCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_DisableDDBufferFreezing_allowed(any);}
+};
+
+
+
+class EnableDDBufferFreezingCmd : public Tango::Command
+{
+public:
+	EnableDDBufferFreezingCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	EnableDDBufferFreezingCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~EnableDDBufferFreezingCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_EnableDDBufferFreezing_allowed(any);}
+};
+
+
+
+class UnfreezeDDBufferCmd : public Tango::Command
+{
+public:
+	UnfreezeDDBufferCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	UnfreezeDDBufferCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~UnfreezeDDBufferCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_UnfreezeDDBuffer_allowed(any);}
+};
+
+
+
+class GetParametersCmd : public Tango::Command
+{
+public:
+	GetParametersCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out,
+				   const char        *in_desc,
+				   const char        *out_desc,
+				   Tango::DispLevel  level)
+	:Command(name,in,out,in_desc,out_desc, level)	{};
+
+	GetParametersCmd(const char   *name,
+	               Tango::CmdArgType in,
+				   Tango::CmdArgType out)
+	:Command(name,in,out)	{};
+	~GetParametersCmd() {};
+	
+	virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any);
+	virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any)
+	{return (static_cast<Libera *>(dev))->is_GetParameters_allowed(any);}
+};
+
+
+
+//
+// The LiberaClass singleton definition
+//
+
+class
+#ifdef WIN32
+	__declspec(dllexport)
+#endif
+	LiberaClass : public Tango::DeviceClass
+{
+public:
+//	properties member data
+/**
+ *	The user defined interlock configuration. This is the configuration that should be applied on the Libera in case the device 'finds'
+the Libera in its default startup configuration when it is itself starting up or executing its Init TANGO command. This configuration
+can also be applied using the dedicated "SetInterlockConfiguration" expert command.
+Parameters mapping:
+[0] Interlock : mode - [0]: disabled, [1]: enabled, [3]: enabled with gain dependency
+[1] Interlock : threshold : X low in mm
+[2] Interlock : threshold : X high in mm
+[3] Interlock : threshold : Z low in mm (i.e. Y low in the Libera terminology)
+[4] Interlock : threshold : Z high in mm (i.e. Y high in the Libera terminology)
+[5] Interlock : overflow limit (ADC threshold)
+[6] Interlock : overflow duration (num of overloaded ADC samples before raising intlck)
+[7] Interlock : gain limit in dBm  (intlck not active under this limit) - valid range is [-60, 0]
+ */
+	vector<double>	interlockConfiguration;
+/**
+ *	Enables/Disables  DD optional data (IxDD and QxDD)
+ */
+	Tango::DevBoolean	enableDDOptionalData;
+/**
+ *	Enables/disables SA optional Data (currently not used)
+ */
+	Tango::DevBoolean	enableSAOptionalData;
+/**
+ *	Enables/disables SA History optional data (sum history)
+ */
+	Tango::DevBoolean	enableSAHistoryOptionalData;
+/**
+ *	Enables/disables ADC optional data (currently not used)
+ */
+	Tango::DevBoolean	enableADCOptionalData;
+/**
+ *	0: TANGO_INSTITUTE (GENERIC)
+1: ALBA
+2: ESRF
+3: ELETTRA
+4: SOLEIL
+ */
+	Tango::DevShort	institute;
+
+//	add your own data members here
+//------------------------------------
+
+public:
+	Tango::DbData	cl_prop;
+	Tango::DbData	cl_def_prop;
+	Tango::DbData	dev_def_prop;
+
+//	Method prototypes
+	static LiberaClass *init(const char *);
+	static LiberaClass *instance();
+	~LiberaClass();
+	Tango::DbDatum	get_class_property(string &);
+	Tango::DbDatum	get_default_device_property(string &);
+	Tango::DbDatum	get_default_class_property(string &);
+	
+protected:
+	LiberaClass(string &);
+	static LiberaClass *_instance;
+	void command_factory();
+	void get_class_property();
+	void attribute_factory(vector<Tango::Attr *> &);
+	void write_class_property();
+	void set_default_property();
+	string get_cvstag();
+	string get_cvsroot();
+
+private:
+	void device_factory(const Tango::DevVarStringArray *);
+};
+
+
+}	//	namespace Libera_ns
+
+#endif // _LIBERACLASS_H
diff --git a/src/LiberaEvents.cpp b/src/LiberaEvents.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd0623d1d73058bdae58ef20b543513b554f1c19
--- /dev/null
+++ b/src/LiberaEvents.cpp
@@ -0,0 +1,683 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+
+#if defined(_EMBEDDED_DEVICE_)
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include "LiberaEvents.h"
+
+namespace bpm {
+
+// ============================================================================
+// DEFINEs
+// ============================================================================
+#define LIBERA_EVENT_FIFO_PATHNAME	"/dev/libera.event"
+//-----------------------------------------------------------------------------
+#define LIBERA_SERVER_PID_PATHNAME  "/var/run/liberad.pid"
+//-----------------------------------------------------------------------------
+#define LIBERA_EVENTD_PID_PATHNAME  "/var/run/leventd.pid"
+//-----------------------------------------------------------------------------
+
+// ============================================================================
+// Static members
+// ============================================================================
+Tango::DevFailed LiberaEventsManager::error;
+ 
+// ============================================================================
+// LiberaEventsManager::LiberaEventsManager (SINGLETON)
+// ============================================================================
+LiberaEventsManager::LiberaEventsManager (const LiberaEventsManagerConfig& cfg)
+  : Thread(cfg.host_device), cfg_(cfg), fifo_fd_(-1), go_on_(true)
+{
+  //- noop
+}
+
+// ============================================================================
+// LiberaEventsManager::~LiberaEventsManager
+// ============================================================================
+LiberaEventsManager::~LiberaEventsManager ()
+{
+  //- noop
+}
+
+// ============================================================================
+// LiberaEventsManager::is_eventd_running
+// ============================================================================
+bool LiberaEventsManager::is_eventd_running (bool kill_if_running)
+    throw (Tango::DevFailed)
+{
+  //- std::cout << "LiberaEventsManager::is_eventd_running <->" << std::endl;
+  
+  return LiberaEventsManager::deamon_running_i(LIBERA_SERVER_PID_PATHNAME, kill_if_running);
+}
+
+// ============================================================================
+// LiberaEventsManager::is_liberad_running
+// ============================================================================
+bool LiberaEventsManager::is_liberad_running (bool kill_if_running)
+    throw (Tango::DevFailed)
+{
+  //- std::cout << "LiberaEventsManager::is_liberad_running <->" << std::endl;
+  
+  return LiberaEventsManager::deamon_running_i(LIBERA_EVENTD_PID_PATHNAME, kill_if_running);
+}
+
+// ============================================================================
+// LiberaEventsManager::deamon_running_i
+// ============================================================================
+bool LiberaEventsManager::deamon_running_i (const char * pid_file, bool kill_if_running)
+    throw (Tango::DevFailed)
+{
+  //- std::cout << "LiberaEventsManager::deamon_running_i <-" << std::endl;
+
+  bool daemon_running =  false;
+  
+  FILE *fp = ::fopen(pid_file, "r");
+  if (! fp)
+  {
+    if (errno != ENOENT)
+    {
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("could not check Libera daemon status [system call failed]"),
+                                     _CPTC("LiberaEventsManager::deamon_running_i"));
+    }
+    //- std::cout << "LiberaEventsManager::is_eventd_running::no Libera daemon pid file found [not running]" << std::endl;
+    return daemon_running;
+  }
+  
+  //- std::cout << "LiberaEventsManager::deamon_running_i::found existing daemon pid file" << std::endl;
+
+  int rc = 0;
+  char *line = 0;
+  size_t size = 0;
+
+  if (::getline(&line, &size, fp) != -1)
+  {
+    //- get eventd pid
+    const pid_t pid = ::atol(line);
+    //- select signal to send to the eventd
+    const int no_signal = kill_if_running ? 9 : 0;
+    if (! kill_if_running)
+    {
+      //- std::cout << "LiberaEventsManager::deamon_running_i::sending signal 0 to daemon" << std::endl;
+      //- just "ping" the eventd
+      if (::kill( pid, no_signal) == 0)
+        daemon_running = true;
+      //- std::cout << "LiberaEventsManager::deamon_running_i::daemon is alive!" << std::endl;
+    }
+    else
+    {
+      //- std::cout << "LiberaEventsManager::deamon_running_i::sending SIGINT to daemon" << std::endl;
+      //- send SIGINT to the eventd
+      if (::kill(pid, no_signal) == 0)
+        daemon_running = false;
+      //- std::cout << "LiberaEventsManager::deamon_running_i::daemon killed" << std::endl;
+    }
+  }
+  
+  //- 
+  if (line)
+    ::free(line);
+
+  //- close pid file
+  ::fclose(fp);
+
+  //- (try to) erase pid file
+  if (kill_if_running)
+    ::unlink(pid_file);
+
+  //- std::cout << "LiberaEventsManager::deamon_running_i ->" << std::endl;
+  
+  return daemon_running;
+}
+
+
+// ============================================================================
+// LiberaEventsManager::go
+// ============================================================================
+void LiberaEventsManager::go ()
+{
+  DEBUG_STREAM << "LiberaEventsManager::go <-" << std::endl;
+  this->start_undetached();
+  DEBUG_STREAM << "LiberaEventsManager::go ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::exit
+// ============================================================================
+void LiberaEventsManager::exit ()
+{
+  DEBUG_STREAM << "LiberaEventsManager::exit <->" << std::endl;
+  this->go_on_ = false;
+  Thread::IOArg ioa = 0;
+  this->join(&ioa);
+  //- don't even try to log something after join!
+}
+
+// ============================================================================
+// LiberaEventsManager::init_i
+// ============================================================================
+void LiberaEventsManager::init_i ()
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "LiberaEventsManager::init_i <-" << std::endl;
+
+  //- already connected?
+  if (this->fifo_fd_ != -1)	
+    return;
+                                   
+	// open Libera event device in RW mode to gain exclusive
+	// access to the event fifo. this is also more effective
+	// than the check above and makes it kind of redundant!
+	this->fifo_fd_ = ::open(LIBERA_EVENT_FIFO_PATHNAME, O_RDWR);
+	if (this->fifo_fd_ == -1)	
+	{
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("could not open the Libera event FIFO [try to reload Libera driver]"),
+                                   _CPTC("LiberaEventsManager::init"));
+	}
+
+  //- set initial mask
+	this->set_events_mask_i(0);
+  this->cfg_.evts_mask = 0;
+
+  
+  DEBUG_STREAM << "LiberaEventsManager::init_i ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::close_i
+// ============================================================================
+void LiberaEventsManager::close_i ()
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "LiberaEventsManager::close_i <-" << std::endl;
+
+  //- are we actually coonected to Libera event fifo?
+  if (this->fifo_fd_ == -1)
+    return;
+    
+	//- disable events
+  size_t mask = 0;
+  this->set_events_mask_i(0);
+  
+	//- close event fifo
+	if (::close(this->fifo_fd_))	
+	{
+    //- anyway... mark event fifo as closed
+    this->fifo_fd_ = -1;
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("could not close the Libera event FIFO"),
+                                   _CPTC("LiberaEventsManager::close"));
+  }
+  
+  //- mark event fifo as closed
+  this->fifo_fd_ = -1;
+
+  DEBUG_STREAM << "LiberaEventsManager::close_i ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::set_events_mask
+// ============================================================================
+void LiberaEventsManager::set_events_mask (int _evts_mask)
+    throw (Tango::DevFailed)
+{
+  bpm::AutoMutex<bpm::Mutex> guard(this->m_lock);
+  
+  this->set_events_mask_i(_evts_mask);
+}
+
+// ============================================================================
+// LiberaEventsManager::set_events_mask_i
+// ============================================================================
+void LiberaEventsManager::set_events_mask_i (int _evts_mask)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "LiberaEventsManager::set_events_mask_i <-" << std::endl;
+
+	DEBUG_ASSERT(this->fifo_fd_ != -1);
+    
+	if (::ioctl(this->fifo_fd_, LIBERA_EVENT_SET_MASK, &_evts_mask))	
+	{
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("could not change Libera event mask"),
+                                   _CPTC("LiberaEventsManager::set_event_mask"));
+  }
+
+  this->cfg_.evts_mask = _evts_mask;
+
+  DEBUG_STREAM << "LiberaEventsManager::set_events_mask_i ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::get_events_mask
+// ============================================================================
+int LiberaEventsManager::get_events_mask () const
+{
+  return this->cfg_.evts_mask;
+}
+
+// ============================================================================
+// LiberaEventsManager::enable_events
+// ============================================================================
+void LiberaEventsManager::enable_events (int _evts_mask)
+    throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "LiberaEventsManager::enable_events <-" << std::endl;
+
+  bpm::AutoMutex<bpm::Mutex> guard(this->m_lock);
+
+  int evts_mask = this->cfg_.evts_mask;
+  
+  if (_evts_mask & CSPI_EVENT_OVERFLOW)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_OVERFLOW enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_OVERFLOW;
+  }
+
+  if (_evts_mask & CSPI_EVENT_CFG)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_CFG enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_CFG;
+  }
+
+  if (_evts_mask & CSPI_EVENT_SA)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_SA enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_SA;
+  }
+
+  if (_evts_mask & CSPI_EVENT_INTERLOCK)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_INTERLOCK enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_INTERLOCK;
+  }
+
+  if (_evts_mask & CSPI_EVENT_PM)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_PM enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_PM;
+  }
+
+  if (_evts_mask & CSPI_EVENT_FA)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_FA enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_FA;
+  }
+
+  if (_evts_mask & CSPI_EVENT_TRIGGET)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_TRIGGET enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_TRIGGET;
+  }
+
+  if (_evts_mask & CSPI_EVENT_TRIGSET)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::enable_events::CSPI_EVENT_TRIGSET enabled" << std::endl;
+    evts_mask |= CSPI_EVENT_TRIGSET;
+  }
+  
+  this->set_events_mask_i(evts_mask);
+
+  this->cfg_.evts_mask = evts_mask;
+
+  DEBUG_STREAM << "LiberaEventsManager::enable_events ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::disable_events
+// ============================================================================
+void LiberaEventsManager::disable_events (int _evts_mask)
+    throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "LiberaEventsManager::disable_events <-" << std::endl;
+
+  bpm::AutoMutex<bpm::Mutex> guard(this->m_lock);
+
+  int evts_mask = this->cfg_.evts_mask;
+
+  if (_evts_mask & CSPI_EVENT_OVERFLOW)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_OVERFLOW disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_OVERFLOW;
+  }
+
+  if (_evts_mask & CSPI_EVENT_CFG)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_CFG disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_CFG;
+  }
+
+  if (_evts_mask & CSPI_EVENT_SA)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_SA disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_SA;
+  }
+  
+  if (_evts_mask & CSPI_EVENT_INTERLOCK)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_INTERLOCK disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_INTERLOCK;
+  }
+
+  if (_evts_mask & CSPI_EVENT_PM)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_PM disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_PM;
+  }
+
+  if (_evts_mask & CSPI_EVENT_FA)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_FA disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_FA;
+  }
+
+  if (_evts_mask & CSPI_EVENT_TRIGGET)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_TRIGGET disabled" << std::endl;
+    evts_mask &= ~CSPI_EVENT_TRIGGET;
+  }
+  
+  if (_evts_mask & CSPI_EVENT_TRIGSET)
+  {
+    DEBUG_STREAM << "LiberaEventsManager::disable_events::CSPI_EVENT_TRIGSET disabled" << std::endl;
+    evts_mask &= ~LIBERA_EVENT_TRIGSET;
+  }
+  
+  this->set_events_mask_i(evts_mask);
+
+  this->cfg_.evts_mask = evts_mask;
+
+  DEBUG_STREAM << "LiberaEventsManager::disable_events ->" << std::endl;
+}
+
+// ============================================================================
+// LiberaEventsManager::run
+// ============================================================================
+Thread::IOArg LiberaEventsManager::run_undetached (Thread::IOArg _arg)
+{
+	fd_set rfds;
+	size_t nleft = 0;
+
+  DEBUG_STREAM << "LiberaEventsManager::run_undetached <-" << std::endl;
+                       
+  try
+  {
+    //- initialization
+    this->init_i();
+  }
+  catch (const Tango::DevFailed& df)
+  {
+    //- store error
+    LiberaEventsManager::error = df;
+    //- notify user
+    this->notify_error_i();
+    try
+    {
+      //- cleanup
+      bpm::AutoMutex<bpm::Mutex> guard(this->m_lock);
+      this->close_i();
+    }
+    catch (...)
+    {
+      //- ignore error
+    }
+    //- exit thread
+    return 0;
+  }
+
+	//- while no quit request...
+  while (this->go_on_) 
+	{
+    try
+    {
+      //- reset
+		  FD_ZERO(&rfds);
+		  
+		  //- add request fifo descriptor to the set of descriptors to watch
+		  FD_SET(this->fifo_fd_, &rfds);
+		  
+      //- setup select timeout
+      struct timeval tv;
+      tv.tv_sec = 1;
+      tv.tv_usec = 0;
+
+		  //- watch the descriptor set for available input
+		  int rc = ::select(this->fifo_fd_ + 1, &rfds, 0, 0, &tv);
+		  if (rc == -1) 
+		  {
+        //- error or interrupted by signal
+			  if (errno == EINTR && this->go_on_)
+			    continue;
+		  }
+      else if (! rc)
+      {
+        //- timeout
+			  if (! this->go_on_)
+          break;
+        else
+          continue;
+      }
+
+      //- if fifo has pending event
+		  ssize_t nread = -1;
+		  if (FD_ISSET(this->fifo_fd_, &rfds)) 
+		  {
+        //- read pending event
+			  libera_event_t evt;
+			  nread = this->read_fifo_i(&evt, sizeof(evt), &nleft);
+			  if (nread == -1 && errno != EINTR)
+	      {
+          Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                         _CPTC("could not read Libera event FIFO [try to reload Libera driver]"),
+                                         _CPTC("LiberaEventsManager::run_undetached"));
+        }
+        //- handle event
+			  if (! nleft)
+			    handle_event_i(evt);
+		  }
+    }
+    catch (const Tango::DevFailed& df)
+    {
+      //- store error
+      LiberaEventsManager::error = df;
+      //- notify user
+      this->notify_error_i();
+      //- exit while loop
+      break;
+    }
+	}
+
+  try
+  {
+    //- cleanup
+    bpm::AutoMutex<bpm::Mutex> guard(this->m_lock);
+    DEBUG_STREAM << "LiberaEventsManager::run_undetached::closing connection to Libera events FIFO" << std::endl;
+    this->close_i();
+    DEBUG_STREAM << "LiberaEventsManager::run_undetached::connection to events FIFO closed" << std::endl;
+  }
+  catch (const Tango::DevFailed& df)
+  {
+    //- store error but do not overwrite initial error
+    if (LiberaEventsManager::error.errors.length() == 0)
+      LiberaEventsManager::error = df;
+    //- doesn't make sense to notify user!
+  }
+
+  DEBUG_STREAM << "LiberaEventsManager::run_undetached ->" << std::endl;
+
+  return 0;
+}
+
+// ============================================================================
+// LiberaEventsManager::read_fifo_i
+// ============================================================================
+int LiberaEventsManager::read_fifo_i (void * buf, const size_t ntotal, size_t * nleft)
+    throw (Tango::DevFailed)
+{
+	DEBUG_ASSERT(buf);
+	DEBUG_ASSERT(nleft );
+	DEBUG_ASSERT(*nleft <= ntotal);
+
+	//- reset nleft if we just completed reading ntotal bytes.
+	if (*nleft == 0) 
+	  *nleft = ntotal;
+	  
+	const ssize_t nread = ::read(this->fifo_fd_, (char*)buf + (ntotal - *nleft), *nleft);
+
+  //- remove consumed bytes
+	if (nread > 0) 
+	  *nleft -= nread;
+	  
+	return nread;
+}
+
+// ============================================================================
+// LiberaEventsManager::handle_event_i
+// ============================================================================
+void LiberaEventsManager::handle_event_i (const libera_event_t &_evt)
+{
+/*
+  switch (_evt.id)
+  {
+    case CSPI_EVENT_USER:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_USER"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_OVERFLOW:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_OVERFLOW"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_CFG:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_CFG"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_SA:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_SA"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_INTERLOCK:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_INTERLOCK"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_PM:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_PM"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_FA:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_FA"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_TRIGGET:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_TRIGGET"
+                   << std::endl;
+      break;
+    case CSPI_EVENT_TRIGSET:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling CSPI_EVENT_TRIGSET"
+                   << std::endl;
+      break;
+    default:
+      DEBUG_STREAM << "LiberaEventsManager::handle_event_i::handling UNKNOWN evt [id: "
+                   << _evt.id
+                   << "]"
+                   << std::endl;
+      break;
+  }
+*/  
+
+	//- this will block until PM data buffered
+	if (_evt.id == CSPI_EVENT_PM) 
+    ::ioctl(this->fifo_fd_, LIBERA_EVENT_ACQ_PM);
+
+  //- forward evt to user 
+  if (this->cfg_.evt_handler)
+  {
+    //- setup evt
+    CSPI_EVENT cpsi_evt;
+    cpsi_evt.hdr.id = _evt.id;
+    cpsi_evt.hdr.param = _evt.param;
+    cpsi_evt.user_data = this->cfg_.user_data; 
+    try
+	  {
+      //- call event handler
+      this->cfg_.evt_handler(&cpsi_evt);
+	  }
+	  catch (...)
+	  {
+	    //- ignore error - can't do anything here!
+	  }
+  }
+}
+
+// ============================================================================
+// LiberaEventsManager::notify_error_i
+// ============================================================================
+void LiberaEventsManager::notify_error_i ()
+{
+  //- forward evt to user 
+  if (this->cfg_.evt_handler)
+  {
+    //- setup evt
+    CSPI_EVENT cpsi_evt;
+    cpsi_evt.hdr.id = CSPI_EVENTS_MANAGER_ERROR;
+    cpsi_evt.hdr.param = 0;
+    cpsi_evt.user_data = this->cfg_.user_data;
+    //- call event handler
+    try
+    {
+      this->cfg_.evt_handler(&cpsi_evt);
+    }
+    catch (...)
+    {
+      //- ignore error - can't do anything here!
+    }
+  }
+}
+  
+} //- namespace bpm
+
+#endif // _EMBEDDED_DEVICE
+
diff --git a/src/LiberaEvents.h b/src/LiberaEvents.h
new file mode 100644
index 0000000000000000000000000000000000000000..a27d27046a1e0e3d3135d08b7767b0a056d15c28
--- /dev/null
+++ b/src/LiberaEvents.h
@@ -0,0 +1,180 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#include "CommonHeader.h"
+
+#if defined(_EMBEDDED_DEVICE_)
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Thread.h"
+
+namespace bpm
+{
+
+// ============================================================================
+// SOME VERY SPECIAL EVENTS
+// ============================================================================
+#define CSPI_EVENTS_MANAGER_ERROR -1
+
+// ============================================================================
+// Libera event handler signature
+// ============================================================================
+typedef int (*LiberaEventHandler) (CSPI_EVENT *);
+  
+// ============================================================================
+//! LiberaEventsManagerConfig class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+struct LiberaEventsManagerConfig
+{
+  LiberaEventsManagerConfig ()
+    : evt_handler(0), user_data(0), evts_mask(0), host_device(0)
+  {
+    //- noop
+  }
+  LiberaEventsManagerConfig (const LiberaEventsManagerConfig& src)
+  {
+    *this = src;
+  }
+  const LiberaEventsManagerConfig& operator= (const LiberaEventsManagerConfig& src)
+  {
+    if (&src == this)
+      return *this;
+    ::memcpy(this, &src, sizeof(LiberaEventsManagerConfig));
+    return *this;
+  }
+  //- Libera event handler (called upon receipt of a Libera event)
+  LiberaEventHandler evt_handler;
+  //- abstract user data (passed back with each event)
+  void * user_data;
+  //- events mask
+  int evts_mask;
+  //- host device (logging)
+  Tango::DeviceImpl * host_device;
+};
+
+// ============================================================================
+//! LiberaEventsManager class.
+// ============================================================================
+//!
+//! detailed description to be written
+//!
+// ============================================================================
+class LiberaEventsManager : public Thread
+{
+  friend class BPM;
+  
+protected:
+  //- ctor
+  LiberaEventsManager (const LiberaEventsManagerConfig & cfg);
+
+  //- dtor
+  ~LiberaEventsManager ();
+
+  //- returns true if the generic server is running on the Libera (should not!)
+  static bool is_liberad_running (bool kill_if_running = false)
+    throw (Tango::DevFailed);
+
+  //- returns true if the eventd is running on the Libera (should not!)
+  static bool is_eventd_running (bool kill_if_running = false)
+    throw (Tango::DevFailed);
+
+  //- start the underlying thread
+  void go ();
+
+  //- stop then join with the underlying thread
+  virtual void exit ();
+  
+  //- change events mask
+  void set_events_mask (int evts_mask)
+    throw (Tango::DevFailed);
+    
+  //- returns current events mask
+  int get_events_mask () const;
+    
+  //- enable the specified events
+  void enable_events (int evts_mask)
+    throw (Tango::DevFailed);
+
+  //- enable the specified events
+  void disable_events (int evts_mask)
+    throw (Tango::DevFailed);
+  
+  //- thread entry point
+  virtual IOArg run_undetached (IOArg);
+  
+private:
+  //- initializer
+  void init_i ()
+    throw (Tango::DevFailed);
+
+  //- close
+  void close_i ()
+    throw (Tango::DevFailed);
+
+  //- change events mask (thread unsafe)
+  void set_events_mask_i (int _evts_mask)
+    throw (Tango::DevFailed);
+    
+  //- read Libera event FIFO
+  int read_fifo_i (void * buf, const size_t ntotal, size_t * nleft)
+    throw (Tango::DevFailed);
+
+  //- handle Libera event
+  void handle_event_i (const libera_event_t &_evt);
+  
+  //- notify error
+  void notify_error_i ();
+
+  //- returns true if the specified daemon is running on the Libera
+  static bool deamon_running_i (const char * pid_file, bool kill_if_running)
+    throw (Tango::DevFailed);
+
+  //- config
+  LiberaEventsManagerConfig cfg_;
+  
+  //- Libera event FIFO descriptor
+  int fifo_fd_;
+
+  //- thread ctrl flag
+  bool go_on_;
+
+  //- reason why the thread died
+  static Tango::DevFailed error;
+};
+
+} //- namespace bpm
+
+#endif // _EMBEDDED_DEVICE
+
diff --git a/src/LiberaStateMachine.cpp b/src/LiberaStateMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7fb45aabf0a7206c730130a748ede8f981429ff0
--- /dev/null
+++ b/src/LiberaStateMachine.cpp
@@ -0,0 +1,2413 @@
+//+=============================================================================
+//
+// file :         LiberaStateMachine.cpp
+//
+// description :  C++ source for the Libera and its alowed. 
+//                method for commands and attributes
+//
+// project :      TANGO Device Server
+//
+// $Author: nleclercq $
+//
+// copyleft :     European Synchrotron Radiation Facility
+//                BP 220, Grenoble 38043
+//                FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#include <tango.h>
+#include <Libera.h>
+#include <LiberaClass.h>
+
+/*====================================================================
+ *	This file contains the methods to allow commands and attributes
+ * read or write execution.
+ *
+ * If you wand to add your own code, add it between 
+ * the "End/Re-Start of Generated Code" comments.
+ *
+ * If you want, you can also add your own methods.
+ *====================================================================
+ */
+
+namespace Libera_ns
+{
+
+//=================================================
+//		Attributes Allowed Methods
+//=================================================
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ExternalTriggerEnabled_allowed
+// 
+// description : 	Read/Write allowed for ExternalTriggerEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ExternalTriggerEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDBufferSize_allowed
+// 
+// description : 	Read/Write allowed for DDBufferSize attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDBufferSize_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XPosDD_allowed
+// 
+// description : 	Read/Write allowed for XPosDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XPosDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZPosDD_allowed
+// 
+// description : 	Read/Write allowed for ZPosDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZPosDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QuadDD_allowed
+// 
+// description : 	Read/Write allowed for QuadDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QuadDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SumDD_allowed
+// 
+// description : 	Read/Write allowed for SumDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SumDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VaDD_allowed
+// 
+// description : 	Read/Write allowed for VaDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VaDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VbDD_allowed
+// 
+// description : 	Read/Write allowed for VbDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VbDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VcDD_allowed
+// 
+// description : 	Read/Write allowed for VcDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VcDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VdDD_allowed
+// 
+// description : 	Read/Write allowed for VdDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VdDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDTriggerCounter_allowed
+// 
+// description : 	Read/Write allowed for DDTriggerCounter attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDTriggerCounter_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDBufferFreezingEnabled_allowed
+// 
+// description : 	Read/Write allowed for DDBufferFreezingEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDBufferFreezingEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDBufferFrozen_allowed
+// 
+// description : 	Read/Write allowed for DDBufferFrozen attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDBufferFrozen_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDEnabled_allowed
+// 
+// description : 	Read/Write allowed for DDEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SAEnabled_allowed
+// 
+// description : 	Read/Write allowed for SAEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SAEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCEnabled_allowed
+// 
+// description : 	Read/Write allowed for ADCEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZPosSAHistory_allowed
+// 
+// description : 	Read/Write allowed for ZPosSAHistory attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZPosSAHistory_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VaSA_allowed
+// 
+// description : 	Read/Write allowed for VaSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VaSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VbSA_allowed
+// 
+// description : 	Read/Write allowed for VbSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VbSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VcSA_allowed
+// 
+// description : 	Read/Write allowed for VcSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VcSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VdSA_allowed
+// 
+// description : 	Read/Write allowed for VdSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VdSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XPosSA_allowed
+// 
+// description : 	Read/Write allowed for XPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZPosSA_allowed
+// 
+// description : 	Read/Write allowed for ZPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SumSA_allowed
+// 
+// description : 	Read/Write allowed for SumSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SumSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QuadSA_allowed
+// 
+// description : 	Read/Write allowed for QuadSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QuadSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XPosPM_allowed
+// 
+// description : 	Read/Write allowed for XPosPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XPosPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZPosPM_allowed
+// 
+// description : 	Read/Write allowed for ZPosPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZPosPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QuadPM_allowed
+// 
+// description : 	Read/Write allowed for QuadPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QuadPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SumPM_allowed
+// 
+// description : 	Read/Write allowed for SumPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SumPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VaPM_allowed
+// 
+// description : 	Read/Write allowed for VaPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VaPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VbPM_allowed
+// 
+// description : 	Read/Write allowed for VbPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VbPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VcPM_allowed
+// 
+// description : 	Read/Write allowed for VcPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VcPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_VdPM_allowed
+// 
+// description : 	Read/Write allowed for VdPM attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_VdPM_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_PMNotified_allowed
+// 
+// description : 	Read/Write allowed for PMNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_PMNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockXNotified_allowed
+// 
+// description : 	Read/Write allowed for InterlockXNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockXNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockZNotified_allowed
+// 
+// description : 	Read/Write allowed for InterlockZNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockZNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockAttnNotified_allowed
+// 
+// description : 	Read/Write allowed for InterlockAttnNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockAttnNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockADCPreFilterNotified_allowed
+// 
+// description : 	Read/Write allowed for InterlockADCPreFilterNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockADCPreFilterNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockADCPostFilterNotified_allowed
+// 
+// description : 	Read/Write allowed for InterlockADCPostFilterNotified attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockADCPostFilterNotified_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDTriggerOffset_allowed
+// 
+// description : 	Read/Write allowed for DDTriggerOffset attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDTriggerOffset_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XLow_allowed
+// 
+// description : 	Read/Write allowed for XLow attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XLow_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XHigh_allowed
+// 
+// description : 	Read/Write allowed for XHigh attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XHigh_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZLow_allowed
+// 
+// description : 	Read/Write allowed for ZLow attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZLow_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZHigh_allowed
+// 
+// description : 	Read/Write allowed for ZHigh attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZHigh_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_AutoSwitchingEnabled_allowed
+// 
+// description : 	Read/Write allowed for AutoSwitchingEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_AutoSwitchingEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_InterlockConfiguration_allowed
+// 
+// description : 	Read/Write allowed for InterlockConfiguration attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_InterlockConfiguration_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_AGCEnabled_allowed
+// 
+// description : 	Read/Write allowed for AGCEnabled attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_AGCEnabled_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DSCMode_allowed
+// 
+// description : 	Read/Write allowed for DSCMode attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DSCMode_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_Gain_allowed
+// 
+// description : 	Read/Write allowed for Gain attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_Gain_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XPosSAHistory_allowed
+// 
+// description : 	Read/Write allowed for XPosSAHistory attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XPosSAHistory_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SAStatNumSamples_allowed
+// 
+// description : 	Read/Write allowed for SAStatNumSamples attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SAStatNumSamples_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XRMSPosSA_allowed
+// 
+// description : 	Read/Write allowed for XRMSPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XRMSPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZRMSPosSA_allowed
+// 
+// description : 	Read/Write allowed for ZRMSPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZRMSPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCBufferSize_allowed
+// 
+// description : 	Read/Write allowed for ADCBufferSize attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCBufferSize_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCChannelA_allowed
+// 
+// description : 	Read/Write allowed for ADCChannelA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCChannelA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCChannelB_allowed
+// 
+// description : 	Read/Write allowed for ADCChannelB attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCChannelB_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCChannelC_allowed
+// 
+// description : 	Read/Write allowed for ADCChannelC attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCChannelC_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ADCChannelD_allowed
+// 
+// description : 	Read/Write allowed for ADCChannelD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ADCChannelD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MachineTime_allowed
+// 
+// description : 	Read/Write allowed for MachineTime attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MachineTime_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SystemTime_allowed
+// 
+// description : 	Read/Write allowed for SystemTime attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SystemTime_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_TimePhase_allowed
+// 
+// description : 	Read/Write allowed for TimePhase attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_TimePhase_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_HWTemperature_allowed
+// 
+// description : 	Read/Write allowed for HWTemperature attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_HWTemperature_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_Fan1Speed_allowed
+// 
+// description : 	Read/Write allowed for Fan1Speed attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_Fan1Speed_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_Fan2Speed_allowed
+// 
+// description : 	Read/Write allowed for Fan2Speed attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_Fan2Speed_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SCPLLStatus_allowed
+// 
+// description : 	Read/Write allowed for SCPLLStatus attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SCPLLStatus_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MCPLLStatus_allowed
+// 
+// description : 	Read/Write allowed for MCPLLStatus attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MCPLLStatus_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XMeanPosSA_allowed
+// 
+// description : 	Read/Write allowed for XMeanPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XMeanPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZMeanPosSA_allowed
+// 
+// description : 	Read/Write allowed for ZMeanPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZMeanPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_XPeakPosSA_allowed
+// 
+// description : 	Read/Write allowed for XPeakPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_XPeakPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ZPeakPosSA_allowed
+// 
+// description : 	Read/Write allowed for ZPeakPosSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ZPeakPosSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_CxSA_allowed
+// 
+// description : 	Read/Write allowed for CxSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_CxSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_CzSA_allowed
+// 
+// description : 	Read/Write allowed for CzSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_CzSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_PMNotificationCounter_allowed
+// 
+// description : 	Read/Write allowed for PMNotificationCounter attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_PMNotificationCounter_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_UserData_allowed
+// 
+// description : 	Read/Write allowed for UserData attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_UserData_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_CpuUsage_allowed
+// 
+// description : 	Read/Write allowed for CpuUsage attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_CpuUsage_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_FreeMemory_allowed
+// 
+// description : 	Read/Write allowed for FreeMemory attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_FreeMemory_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_RamFsUsage_allowed
+// 
+// description : 	Read/Write allowed for RamFsUsage attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_RamFsUsage_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_UpTime_allowed
+// 
+// description : 	Read/Write allowed for UpTime attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_UpTime_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MAFLength_allowed
+// 
+// description : 	Read/Write allowed for MAFLength attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MAFLength_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MAFDelay_allowed
+// 
+// description : 	Read/Write allowed for MAFDelay attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MAFDelay_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ExternalSwitching_allowed
+// 
+// description : 	Read/Write allowed for ExternalSwitching attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ExternalSwitching_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SwitchingDelay_allowed
+// 
+// description : 	Read/Write allowed for SwitchingDelay attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SwitchingDelay_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_CompensateTune_allowed
+// 
+// description : 	Read/Write allowed for CompensateTune attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_CompensateTune_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_OffsetTune_allowed
+// 
+// description : 	Read/Write allowed for OffsetTune attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_OffsetTune_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ExternalTriggerDelay_allowed
+// 
+// description : 	Read/Write allowed for ExternalTriggerDelay attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ExternalTriggerDelay_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_PMOffset_allowed
+// 
+// description : 	Read/Write allowed for PMOffset attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_PMOffset_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_Incoherence_allowed
+// 
+// description : 	Read/Write allowed for Incoherence attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_Incoherence_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_RefIncoherence_allowed
+// 
+// description : 	Read/Write allowed for RefIncoherence attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_RefIncoherence_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MaxIncoherence_allowed
+// 
+// description : 	Read/Write allowed for MaxIncoherence attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MaxIncoherence_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_MaxIncoherenceDrift_allowed
+// 
+// description : 	Read/Write allowed for MaxIncoherenceDrift attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_MaxIncoherenceDrift_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SumMeanSA_allowed
+// 
+// description : 	Read/Write allowed for SumMeanSA attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SumMeanSA_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_IaDD_allowed
+// 
+// description : 	Read/Write allowed for IaDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_IaDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_IbDD_allowed
+// 
+// description : 	Read/Write allowed for IbDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_IbDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_IcDD_allowed
+// 
+// description : 	Read/Write allowed for IcDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_IcDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_IdDD_allowed
+// 
+// description : 	Read/Write allowed for IdDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_IdDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QaDD_allowed
+// 
+// description : 	Read/Write allowed for QaDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QaDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QbDD_allowed
+// 
+// description : 	Read/Write allowed for QbDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QbDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QcDD_allowed
+// 
+// description : 	Read/Write allowed for QcDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QcDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_QdDD_allowed
+// 
+// description : 	Read/Write allowed for QdDD attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_QdDD_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SumSAHistory_allowed
+// 
+// description : 	Read/Write allowed for SumSAHistory attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SumSAHistory_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_logs_allowed
+// 
+// description : 	Read/Write allowed for logs attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_logs_allowed(Tango::AttReqType type)
+{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_HasMAFSupport_allowed
+// 
+// description : 	Read/Write allowed for HasMAFSupport attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_HasMAFSupport_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_UseLiberaSAData_allowed
+// 
+// description : 	Read/Write allowed for UseLiberaSAData attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_UseLiberaSAData_allowed(Tango::AttReqType type)
+{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_LiberaModel_allowed
+// 
+// description : 	Read/Write allowed for LiberaModel attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_LiberaModel_allowed(Tango::AttReqType type)
+{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+	return true;
+}
+
+//=================================================
+//		Commands Allowed Methods
+//=================================================
+
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_GetParameters_allowed
+// 
+// description : 	Execution allowed for GetParameters command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_GetParameters_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_EnableDD_allowed
+// 
+// description : 	Execution allowed for EnableDD command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_EnableDD_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DisableDD_allowed
+// 
+// description : 	Execution allowed for DisableDD command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DisableDD_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_EnableSA_allowed
+// 
+// description : 	Execution allowed for EnableSA command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_EnableSA_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DisableSA_allowed
+// 
+// description : 	Execution allowed for DisableSA command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DisableSA_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_UnfreezeDDBuffer_allowed
+// 
+// description : 	Execution allowed for UnfreezeDDBuffer command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_UnfreezeDDBuffer_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_EnableDDBufferFreezing_allowed
+// 
+// description : 	Execution allowed for EnableDDBufferFreezing command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_EnableDDBufferFreezing_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DisableDDBufferFreezing_allowed
+// 
+// description : 	Execution allowed for DisableDDBufferFreezing command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DisableDDBufferFreezing_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ResetPMNotification_allowed
+// 
+// description : 	Execution allowed for ResetPMNotification command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ResetPMNotification_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ResetInterlockNotification_allowed
+// 
+// description : 	Execution allowed for ResetInterlockNotification command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ResetInterlockNotification_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_Switches_allowed
+// 
+// description : 	Read/Write allowed for Switches attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_Switches_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DDDecimationFactor_allowed
+// 
+// description : 	Read/Write allowed for DDDecimationFactor attribute.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DDDecimationFactor_allowed(Tango::AttReqType type)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SetInterlockConfiguration_allowed
+// 
+// description : 	Execution allowed for SetInterlockConfiguration command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SetInterlockConfiguration_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_EnableADC_allowed
+// 
+// description : 	Execution allowed for EnableADC command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_EnableADC_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_DisableADC_allowed
+// 
+// description : 	Execution allowed for DisableADC command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_DisableADC_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SetTimeOnNextTrigger_allowed
+// 
+// description : 	Execution allowed for SetTimeOnNextTrigger command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SetTimeOnNextTrigger_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ReadFAData_allowed
+// 
+// description : 	Execution allowed for ReadFAData command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ReadFAData_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_WriteFAData_allowed
+// 
+// description : 	Execution allowed for WriteFAData command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_WriteFAData_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SaveDSCParameters_allowed
+// 
+// description : 	Execution allowed for SaveDSCParameters command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SaveDSCParameters_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_ReloadSystemProperties_allowed
+// 
+// description : 	Execution allowed for ReloadSystemProperties command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_ReloadSystemProperties_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+//+----------------------------------------------------------------------------
+//
+// method : 		Libera::is_SetRefIncoherence_allowed
+// 
+// description : 	Execution allowed for SetRefIncoherence command.
+//
+//-----------------------------------------------------------------------------
+bool Libera::is_SetRefIncoherence_allowed(const CORBA::Any &any)
+{
+	if (get_state() == Tango::UNKNOWN	||
+		get_state() == Tango::FAULT)
+	{
+		//	End of Generated Code
+
+		//	Re-Start of Generated Code
+		return false;
+	}
+	return true;
+}
+
+}	// namespace Libera_ns
diff --git a/src/Makefile.linux b/src/Makefile.linux
new file mode 100644
index 0000000000000000000000000000000000000000..ac773855126bd0436b3ab4bef72130917c5efd36
--- /dev/null
+++ b/src/Makefile.linux
@@ -0,0 +1,220 @@
+#------------------------------------------------------------------------------
+# This file is part of the Libera Tango Device
+#------------------------------------------------------------------------------
+#
+# Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+#
+# Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+# Diamond Light Source Ltd. See ./ma/README for details. 
+#
+# The Libera Tango Device 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.
+#
+# The Libera Tango Device 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., 51
+# Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Contact:
+#      Nicolas Leclercq
+#      Synchrotron SOLEIL
+#      libera-sofware<AT>esrf<DOT>fr
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# DEVICE SERVER BINARY NAME
+#------------------------------------------------------------------------------
+BINARY = ds_BPMLibera
+
+#------------------------------------------------------------------------------
+# IMPLEMENTATION OPTIONS
+#------------------------------------------------------------------------------
+#- export floating point device attributes as DevFloat (instead of DevDouble)
+USE_FLOAT_ATTRIBUTES = 0
+
+#- use cspi SA events (not recommended!)
+USE_SA_EVENTS = 0
+
+#------------------------------------------------------------------------------
+# SET <DEBUG> TO <1> IN ORDER TO COMPIL FOR DEBUGGING
+#------------------------------------------------------------------------------
+DEBUG = 0
+
+#------------------------------------------------------------------------------
+# VERBOSE - comment the following line if you want a verbose compilation
+#------------------------------------------------------------------------------
+.SILENT:
+
+#------------------------------------------------------------------------------
+# TANGO PATH
+#------------------------------------------------------------------------------
+ifndef TANGO_ROOT
+TANGO_ROOT=$(SOLEIL_ROOT)/sw-support/Tango
+endif
+
+#------------------------------------------------------------------------------
+# OMNIORB PATH
+#------------------------------------------------------------------------------
+ifndef OMNIORB_ROOT
+OMNIORB_ROOT=$(SOLEIL_ROOT)/sw-support/OmniORB
+endif
+
+ZEROMQ_ROOT = /usr/local/zeromq-4.0.8
+
+#------------------------------------------------------------------------------
+# I-TECH CSPI PATH
+#------------------------------------------------------------------------------
+ITECH_ROOT=../i-tech
+
+#------------------------------------------------------------------------------
+# Headers paths
+#------------------------------------------------------------------------------
+INCLUDE_DIRS = -I$(TANGO_ROOT)/include/tango \
+               -I$(OMNIORB_ROOT)/include \
+               -I$(ZEROMQ_ROOT)/include \
+               -I$(ITECH_ROOT)/cspi/include \
+               -I$(ITECH_ROOT)/driver/include \
+               -I$(ITECH_ROOT)/server/include \
+               -I.
+
+#------------------------------------------------------------------------------
+# LIBS PATHS
+#------------------------------------------------------------------------------
+LIB_DIRS =  -L$(OMNIORB_ROOT)/lib \
+            -L$(ZEROMQ_ROOT)/lib \
+            -L$(TANGO_ROOT)/lib \
+            -L$(ITECH_ROOT)/server/lib
+			
+#------------------------------------------------------------------------------
+# BINARY OUTPUT DIR
+#------------------------------------------------------------------------------
+ifndef OUTPUT_DIR
+OUTPUT_DIR=~/DeviceServers
+endif
+
+#------------------------------------------------------------------------------
+# COMPILER BINARIES
+#------------------------------------------------------------------------------
+CC = gcc
+CXX = g++
+
+#------------------------------------------------------------------------------
+# CXXFLAGS
+#------------------------------------------------------------------------------
+ifndef DEBUG
+	DEBUG = 0
+endif
+
+ifeq ($(DEBUG),0)
+	CXXFLAGS = -O2
+else
+	CXXFLAGS = -g -D_DEBUG
+endif
+
+CXXFLAGS +=  -std=c++0x -D_REENTRANT -fpermissive
+CXXFLAGS += -fno-enforce-eh-specs
+CXXFLAGS += -W -Wno-uninitialized
+
+CXXFLAGS += -DEBPP
+
+ifeq ($(USE_FLOAT_FP_DATA),1)
+	CXXFLAGS += -D_USE_FLOAT_FP_DATA_
+endif
+
+ifeq ($(USE_SA_EVENTS),1)
+	CXXFLAGS += -D_USE_SA_EVENTS_
+endif
+
+CXXFLAGS += $(INCLUDE_DIRS)
+			
+#------------------------------------------------------------------------------
+# LDFLAGS 
+#------------------------------------------------------------------------------
+LDFLAGS = $(LIB_DIRS) -ltango \
+                     	-lomniORB4 \
+                     	-lomniDynamic4 \
+                     	-lCOS4 \
+                     	-lomnithread \
+                        -lzmq \
+                     	-lpthread \
+                     	-lclient \
+                     	-lm
+							
+#------------------------------------------------------------------------------
+# SOURCES
+#------------------------------------------------------------------------------
+OBJS =  main.o 	\
+        ClassFactory.o 	\
+        LiberaClass.o  \
+        LiberaStateMachine.o 	\
+        Libera.o \
+        StringTokenizer.o  \
+        BPM.o \
+        BPMConfig.o  \
+        BPMBuffer.o  \
+        BPMData.o \
+        BPMSensors.o \
+        Offsets.o  \
+        DataProcessing.o  \
+        DynamicAttr.o  \
+        DynamicAttrHelper.o  \
+        InnerAppender.o  \
+        threading/SharedObject.o  \
+        threading/Message.o  \
+        threading/MessageQ.o  \
+        threading/Task.o  \
+        threading/impl/PosixThreadingImpl.o
+
+#------------------------------------------------------------------------------
+# TARGETS AND RULES
+#------------------------------------------------------------------------------
+.SUFFIXES: .o .cpp
+
+.cpp.o:
+	echo "Compiling $<..."
+	$(CC) $(CXXFLAGS) -c $< -o $*.o
+
+all: log_in $(BINARY) log_out
+
+log_in:
+	echo "Compiling <$(BINARY)> for the <x86> platform"
+ifeq ($(DEBUG),1)
+	echo " '-> debug enabled"
+else
+	echo " '-> debug disabled"
+endif
+ifeq ($(USE_FLOAT_ATTRIBUTES),1)
+	echo " '-> 32 bits float attributes enabled"
+else
+	echo " '-> 32 bits float attributes disabled"
+endif
+ifeq ($(USE_SA_EVENTS),1)
+	echo " '-> SA events enabled"
+else
+	echo " '-> SA events disabled"
+endif
+
+log_out:
+	echo "Done!"
+
+$(BINARY): $(OBJS)
+	echo "Linking device server..."
+	$(CXX) $(OBJS) -o $(BINARY) $(LDFLAGS)
+	cp $(BINARY) $(OUTPUT_DIR)
+	echo "<"$(BINARY)"> for <x86> successfully build"
+
+install: $(BINARY)
+	cp $(BINARY) $(OUTPUT_DIR)
+
+clean:
+	/bin/rm -f *.o *~ $(BINARY)
+	/bin/rm -f ./ma/*.o ./ma/*~
+	/bin/rm -f ./threading/*.o ./threading/*~
+	/bin/rm -f ./threading/impl/*.o  ./threading/impl/*~
+
diff --git a/src/Message.cpp b/src/Message.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cdc365dd3123f5bfb2c9793ab7c5211290bf539e
--- /dev/null
+++ b/src/Message.cpp
@@ -0,0 +1,210 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#include "CommonHeader.h"
+#include "threading/Message.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/Message.i"
+#endif // __INLINE_IMPL__
+
+namespace bpm
+{
+
+// ============================================================================
+// Message::allocate 
+// ============================================================================
+Message * Message::allocate (size_t _msg_type, size_t _msg_priority, bool _waitable)
+  throw (Tango::DevFailed)
+{
+  bpm::Message * msg = 0;
+     
+  try
+  {
+    msg = new bpm::Message (_msg_type, _msg_priority, _waitable);
+  	if (msg == 0)
+      throw std::bad_alloc();
+  }
+  catch (const std::bad_alloc&)
+  {
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("Message allocation failed"),
+                                   _CPTC("Message::allocate"));
+	}
+  catch (...)
+  {
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("Message allocation failed [unknown exception caught]"),
+                                   _CPTC("Message::allocate"));
+	}
+
+  return msg;
+}
+
+// ============================================================================
+// Message::Message
+// ============================================================================
+Message::Message (CSPI_EVENT * e, size_t p, bool w)
+  : SharedObject (),
+    type_ (CSPI_USER),
+    priority_ (p),
+    user_data_ (e->user_data),
+    msg_data_ (0),
+    cspi_data_ (e->hdr.param),
+    cond_ (0),
+    has_waiter_ (false),
+    has_error_ (false)
+{
+  switch (e->hdr.id)
+  {
+    case CSPI_EVENT_USER:
+      this->type_ = CSPI_USER;
+      break;
+    case CSPI_EVENT_OVERFLOW:
+      switch (e->hdr.param)
+      {
+      case CSPI_OVERFLOW_DD_FPGA:
+        this->type_ = CSPI_DD_FPGA_OVERFLOW;
+        break;
+      case CSPI_OVERFLOW_SA_FPGA:
+        this->type_ = CSPI_SA_FPGA_OVERFLOW;
+        break;
+      case CSPI_OVERFLOW_SA_DRV:
+        this->type_ = CSPI_SA_DRVR_OVERFLOW;
+        break;
+      }
+      break;
+    case CSPI_EVENT_CFG:
+      this->type_ = CSPI_CONFIG_CHANGE;
+      break;
+    case CSPI_EVENT_SA:
+      this->type_ = CSPI_SA;
+      break;
+    case CSPI_EVENT_INTERLOCK:
+      this->type_ = CSPI_INTERLOCK;
+      break;
+    case CSPI_EVENT_PM:
+      this->type_ = CSPI_PM;
+      break;
+    case CSPI_EVENT_FA:
+      this->type_ = CSPI_FA;
+      break;
+    case CSPI_EVENT_TRIGGET:
+      this->type_ = CSPI_TRIGGET;
+      break;
+    case CSPI_EVENT_TRIGSET:
+      this->type_ = CSPI_TRIGSET;
+      break;
+  }
+  
+  if (w)
+    this->make_waitable();
+}
+
+// ============================================================================
+// Message::Message
+// ============================================================================
+Message::Message (size_t t, size_t p, bool _w)
+  : SharedObject (),
+    type_ (t),
+    priority_ (p),
+    user_data_ (0), 
+    msg_data_ (0),
+    cspi_data_ (0),
+    cond_ (0),
+    has_waiter_ (false),
+    has_error_ (false),
+    processed_ (false)
+{
+  if (_w)
+    this->make_waitable();
+}
+
+// ============================================================================
+// Message::~Message
+// ============================================================================
+Message::~Message ()
+{
+  //-note: exception_ contains some Tango::DevError which itself 
+  //-note: contains CORBA::string_member which releases the 
+  //-note: associated memory (i.e. char*)
+
+	if (this->msg_data_)
+  {
+		delete this->msg_data_;
+    this->msg_data_ = 0;
+  }
+  
+  DEBUG_ASSERT(this->processed_ ? true : (this->has_waiter_ ? false : true));
+  
+	if (this->cond_)
+  {
+    if (! this->processed_)
+    {
+      AutoMutex<Mutex> guard(this->lock_);
+      this->cond_->broadcast();
+    }
+		delete this->cond_;
+  }
+}
+
+// ============================================================================
+// Message::make_waitable 
+// ============================================================================
+void Message::make_waitable (void)
+  throw (Tango::DevFailed)
+{ 
+  if (this->cond_)
+    return;
+
+  try
+  {
+    this->cond_ = new Condition(this->lock_);
+    if (this->cond_ == 0)
+      throw std::bad_alloc();
+  }
+  catch (const std::bad_alloc&)
+  {
+    Tango::Except::throw_exception(_CPTC("MEMORY_ERROR"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("Message::make_waitable"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("Message::make_waitable"));
+  }
+}
+
+} // namespace bpm
diff --git a/src/Message.h b/src/Message.h
new file mode 100644
index 0000000000000000000000000000000000000000..793a3f43b5d84507a3aff74d6b0a62a5b49520e5
--- /dev/null
+++ b/src/Message.h
@@ -0,0 +1,332 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MSG_H_
+#define _BPM_MSG_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+#include "threading/Semaphore.h"
+#include "threading/SharedObject.h"
+#include "threading/GenericContainer.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define HIGHEST_MSG_PRIORITY  0xFFFF
+#define LOWEST_MSG_PRIORITY   0
+#define INIT_MSG_PRIORITY     HIGHEST_MSG_PRIORITY
+#define EXIT_MSG_PRIORITY     HIGHEST_MSG_PRIORITY
+#define MAX_USER_PRIORITY     (HIGHEST_MSG_PRIORITY - 20)
+#define DEFAULT_MSG_PRIORITY  LOWEST_MSG_PRIORITY
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// enum: MessageType
+// ============================================================================
+typedef enum
+{
+  //--------------------
+  CSPI_USER = 0,
+  CSPI_DD_FPGA_OVERFLOW,
+  CSPI_SA_FPGA_OVERFLOW,
+  CSPI_SA_DRVR_OVERFLOW,
+  CSPI_CONFIG_CHANGE,
+  CSPI_SA,
+  CSPI_INTERLOCK,
+  CSPI_PM,
+  CSPI_FA,
+  CSPI_TRIGGET,
+  CSPI_TRIGSET,
+  //--------------------
+  TASK_INIT,
+  TASK_TIMEOUT,
+  TASK_PERIODIC,
+  TASK_EXIT,
+  //--------------------
+  FIRST_USER_MSG = 1000
+} MessageType;
+
+// ============================================================================
+//  struct: Message
+// ============================================================================
+class Message : private SharedObject
+{
+  friend class Task;
+  friend class Thread;
+  
+public:
+
+	//---------------------------------------------
+	// Message::factory
+	//---------------------------------------------
+  static Message * allocate (size_t msg_type, 
+                             size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                             bool waitable = false)
+    throw (Tango::DevFailed);
+
+
+  //---------------------------------------------
+  // Message::ctor
+  //---------------------------------------------
+  explicit Message (CSPI_EVENT * evt, 
+                    size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                    bool waitable = false);
+
+  //---------------------------------------------
+  // Message::ctor
+  //---------------------------------------------
+  explicit Message (size_t msg_type, 
+                    size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                    bool waitable = false);
+
+  //---------------------------------------------
+  // Message::dtor
+  //---------------------------------------------
+  virtual ~Message ();
+
+  //---------------------------------------------
+  // Message::to_string
+  //---------------------------------------------
+  const char * to_string (void) const;
+
+  //---------------------------------------------
+  // Message::is_ctrl_message
+  //---------------------------------------------
+  bool is_ctrl_message (void);
+  
+  //---------------------------------------------
+  // Message::duplicate
+  //---------------------------------------------
+  Message * duplicate (void);
+  
+  //---------------------------------------------
+  // Message::release
+  //---------------------------------------------
+  void release (void);
+  
+	//---------------------------------------------
+	// Message::type
+	//---------------------------------------------
+	size_t type (void) const;
+
+	//---------------------------------------------
+	// Message::type
+	//---------------------------------------------
+  size_t priority (void) const;
+  
+	//---------------------------------------------
+	// Message::user_data
+	//---------------------------------------------
+  void * user_data (void) const;
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  void user_data (void * user_data);
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  int cspi_data (void) const;
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  void cspi_data (int _cspi_data);
+
+  //---------------------------------------------
+	// Message::attach_data - gets ownership
+	//---------------------------------------------
+  template <typename T> void attach_data (T * _data, bool _ownership = true)
+    throw (Tango::DevFailed)
+  {
+    Container * md = new GenericContainer<T>(_data, _ownership);
+    if (md == 0)
+    {
+     Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                     _CPTC("MessageData allocation failed"),
+                                     _CPTC("Message::attach_data"));
+    }
+    this->msg_data_ = md;
+  }
+
+  //---------------------------------------------
+	// Message::attach_data - makes a copy
+	//---------------------------------------------
+  template <typename T> void attach_data (const T & _data)
+    throw (Tango::DevFailed)
+  {
+    Container * md = new GenericContainer<T>(_data);
+    if (md == 0)
+    {
+     Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                     _CPTC("MessageData allocation failed"),
+                                     _CPTC("Message::attach_data"));
+    }
+    this->msg_data_ = md;
+  }
+  
+  //---------------------------------------------
+  // Message::get_data
+  //---------------------------------------------
+  template <typename T> T& get_data () const
+    throw (Tango::DevFailed)
+  {
+    GenericContainer<T> * c = 0;
+    try
+    {
+      c = dynamic_cast<GenericContainer<T>*>(this->msg_data_);
+      if (c == 0)
+      {
+        Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                        _CPTC("could not extract data from message [unexpected content]"),
+                                        _CPTC("Message::msg_data"));
+      }
+    }
+    catch(const std::bad_cast&)
+    {
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from message [unexpected content]"),
+                                      _CPTC("Message::msg_data"));
+    }
+    return c->content();
+  }
+  
+	//---------------------------------------------
+	// Message::detach_data
+	//---------------------------------------------
+  template <typename T> void detach_data (T*& _data) const
+    throw (Tango::DevFailed)
+  {
+    try
+    {
+    	GenericContainer<T> * c = dynamic_cast<GenericContainer<T>*>(this->msg_data_);
+      if (c == 0)
+  	  {
+        Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                        _CPTC("could not extract data from message [unexpected content]"),
+                                        _CPTC("Message::msg_data"));
+  	  }
+  	  _data = c->content(true);
+    }
+    catch(const std::bad_cast&)
+    {
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from message [unexpected content]"),
+                                      _CPTC("Message::msg_data"));
+    }
+  }
+
+	//---------------------------------------------
+	// Message::make_waitable
+	//--------------------------------------------
+  void make_waitable (void)
+    throw (Tango::DevFailed);
+    
+	//---------------------------------------------
+	// Message::waitable
+	//--------------------------------------------
+  bool waitable (void) const;
+  
+  //---------------------------------------------
+  // Message::wait_processed
+  //---------------------------------------------
+  bool wait_processed (unsigned long tmo_ms);
+    
+ 	//---------------------------------------------
+	// Message::processed
+	//---------------------------------------------
+  void processed (void); 
+  
+	//---------------------------------------------
+	// Message::has_error
+	//---------------------------------------------
+  bool has_error (void) const;
+
+	//---------------------------------------------
+	// Message::set_error
+	//---------------------------------------------
+  void set_error (const Tango::DevFailed & e);
+
+	//---------------------------------------------
+	// Message::get_error
+	//---------------------------------------------
+  const Tango::DevFailed & get_error (void) const;
+  
+private:
+  //- the notification type
+  int type_;
+  
+	//- the msg priority
+	size_t priority_;
+	
+  //- the associated user data (common to all messages)
+  void * user_data_;
+  
+	//- the msg data (specific to a given message)
+	Container * msg_data_;
+	
+	//- the cspi data (from cspi evt)
+  int cspi_data_;
+  
+  //- condition variable (for waitable msgs)
+	Condition * cond_;
+	
+  //- true if a thread is "waiting" for the message to be handled
+  bool has_waiter_;
+  
+  //- true if an error occured during message handling
+  bool has_error_;
+  
+  //- true if msg has been processed
+  bool processed_;
+  
+  //- TANGO exception local storage
+  Tango::DevFailed exception_;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  Message & operator= (const Message &);
+  Message (const Message &);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/Message.i"
+#endif 
+
+#endif // _BPM_MSG_H_
diff --git a/src/MessageQ.cpp b/src/MessageQ.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38f0c837fb758c5cf77d9634dda44a8ebe31139d
--- /dev/null
+++ b/src/MessageQ.cpp
@@ -0,0 +1,425 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/MessageQ.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/MessageQ.i"
+#endif // __INLINE_IMPL__
+
+namespace bpm
+{
+
+// ============================================================================
+// MessageQ::MessageQ
+// ============================================================================
+MessageQ::MessageQ (size_t _lo_wm, size_t _hi_wm, bool _throw_on_post_tmo)
+  : msg_q_ (0),
+    msg_producer_sync_ (lock_),
+    msg_consumer_sync_ (lock_),
+		state_(MessageQ::OPEN),
+		enable_timeout_msg_ (false),
+    enable_periodic_msg_ (false),
+    lo_wm_ (_lo_wm),
+    hi_wm_ (_hi_wm),
+    saturated_ (false),
+    throw_on_post_msg_timeout_ (_throw_on_post_tmo),
+    last_returned_msg_periodic_ (true)
+{
+  this->last_periodic_msg_ts_.tv_sec = 0;
+  this->last_periodic_msg_ts_.tv_usec = 0;
+}
+
+// ============================================================================
+// MessageQ::~MessageQ
+// ============================================================================
+MessageQ::~MessageQ (void)
+{
+  bpm::AutoMutex<bpm::Mutex> (this->lock_);
+
+  this->state_ = MessageQ::CLOSED;
+
+  this->clear_i();
+}
+
+// ============================================================================
+// MessageQ::clear_i
+// ============================================================================
+size_t MessageQ::clear_i (void)
+{
+  size_t num_msg_in_q = this->msg_q_.size();
+
+  while (! this->msg_q_.empty())
+  {
+	  Message * m = this->msg_q_.front ();
+    if (m) m->release();
+	  this->msg_q_.pop_front();
+  }
+
+  return num_msg_in_q;
+}
+
+// ============================================================================
+// MessageQ::close
+// ============================================================================
+void MessageQ::close (void)
+{
+  bpm::AutoMutex<bpm::Mutex> (this->lock_);
+  
+	this->state_ = MessageQ::CLOSED;
+}
+
+// ============================================================================
+// MessageQ::post
+// ============================================================================
+void MessageQ::post (bpm::Message * msg, size_t _tmo_msecs)
+  throw (Tango::DevFailed)
+{
+  //- check input
+  if (! msg) return;
+  
+  //- caller can't post any TIMEOUT or PERIODIC msg
+  if (msg->type() == TASK_TIMEOUT || msg->type() == TASK_PERIODIC)
+  {
+	  //- silently trash the message
+	  msg->release();
+	  return;
+  }
+  
+  //- enter critical section (required for cond.var. to work properly)
+  bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+
+  //- can only post a msg on an opened MsgQ
+  if (this->state_ != MessageQ::OPEN)
+  {
+	  //- silently trash the message (should we throw an exception instead?)
+	  msg->release();
+	  return;
+  }
+
+  //- we force post of ctrl message even if the msQ is saturated
+  if (msg->is_ctrl_message()) 
+  {
+    //- insert msg according to its priority
+    try
+    {
+      this->insert_i(msg);
+    }
+    catch (...)
+    {
+      //- insert_i released the message (no memory leak)
+      Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                      _CPTC ("could not post ctrl message [msgQ insertion error]"),
+                                      _CPTC ("MessageQ::post"));
+    }
+    //- wakeup msg consumers (tell them there is a message to handle)
+    //- this will work since we are under critical section 
+    msg_consumer_sync_.signal();
+    //- done (skip remaining code)
+    return;
+  }
+
+  //- is the messageQ saturated?
+  if (! this->saturated_ && (this->msg_q_.size() == this->hi_wm_))
+  {
+    //- mark msgQ as saturated
+    this->saturated_ = true;
+  }
+
+  //- msg is not a ctrl message...
+  //- wait for the messageQ to have room for new messages
+  if (! this->wait_not_full_i(_tmo_msecs))
+  {
+    //- can't post msg, destroy it in order to avoid memory leak
+    msg->release(); 
+    //- throw exception if the messageQ is configured to do so
+    if (this->throw_on_post_msg_timeout_)
+    {
+      Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"),
+                                      _CPTC ("could not post message [timeout expired]"),
+                                      _CPTC ("MessageQ::post"));
+    }
+    //- return if we didn't throw an exception
+    return;
+  }
+  
+  DEBUG_ASSERT(this->msg_q_.size() <= this->hi_wm_);
+
+  //- insert the message according to its priority
+  try
+  {
+    this->insert_i(msg);
+  }
+  catch (...)
+  {
+    //- insert_i released the message (no memory leak)
+    Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                    _CPTC ("could not post message [msgQ insertion error]"),
+                                    _CPTC ("MessageQ::post"));
+  }
+
+  //- wakeup msg consumers (tell them there is a new message to handle)
+  //- this will work since we are still under critical section
+  //--------------------------------------------------
+  //-TODO: avoid using this under sys signal callback!
+  //--------------------------------------------------
+  msg_consumer_sync_.signal ();
+}
+
+// ============================================================================
+// MessageQ::post
+// ============================================================================
+void MessageQ::post (CSPI_EVENT * _evt, size_t _tmo_msecs)
+  throw (Tango::DevFailed)
+{
+  //- check input
+  if (! _evt) return;
+
+  bpm::Message * msg = 0;
+
+  try
+  {
+    msg = new bpm::Message (_evt);
+    if (msg == 0)
+      throw std::bad_alloc ();
+  }
+  catch (const std::bad_alloc &)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                    _CPTC ("memory allocation failed"),
+                                    _CPTC ("MessageQ::post"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                    _CPTC ("memory allocation failed"),
+                                    _CPTC ("MessageQ::post"));
+  }
+  
+  this->post(msg, _tmo_msecs);
+}
+
+// ============================================================================
+// MessageQ::next_message
+// ============================================================================ 
+bpm::Message * MessageQ::next_message (size_t _tmo_msecs)
+{
+  //- enter critical section (required for cond.var. to work properly)
+	bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+
+  //- the msg
+  bpm::Message * msg = 0;
+  
+  //- wait for the messageQ to contain at least one message
+  //- bpm::Timer t;
+  //- std:cout << "[this:" << (long)this << "]" << " - wait_not_empty_i waiting for msg [tmo is " << _tmo_msecs << "]" << std::endl;
+  if (! this->wait_not_empty_i(_tmo_msecs))
+  {
+    //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned false after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl;
+    //- <wait_not_empty_i> returned <false> : means no msg in msg queue after <_tmo_msecs>
+    //- it may be time to return a periodic message
+    if (this->enable_periodic_msg_ && this->periodic_tmo_expired(_tmo_msecs))
+    {
+      this->last_returned_msg_periodic_ = true; 
+      GET_TIME(this->last_periodic_msg_ts_);
+      //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC" << std::endl; 
+      return new Message(TASK_PERIODIC); 
+    }
+    //- else return a timeout msg 
+    if (this->enable_timeout_msg_)  
+    {
+      this->last_returned_msg_periodic_ = false;
+      //- std::cout << "MessageQ::next_message::returning TASK_TIMEOUT" << std::endl; 
+      return new Message(TASK_TIMEOUT);
+    }
+    //- no msg 
+    //- std::cout << "MessageQ::next_message::returning NULL msg" << std::endl; 
+    this->last_returned_msg_periodic_ = false; 
+    return 0;
+  }
+    
+  //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned true after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl;
+  
+  //- ok, there should be at least one message in the messageQ
+  DEBUG_ASSERT(this->msg_q_.empty() == false);
+
+  //- we are still under critical section since the "Condition::timed_wait" 
+  //- located in "wait_not_empty_i" garantee that the associated mutex (i.e. 
+  //- this->lock_ in the present case) is acquired when the function returns
+
+	//- get msg from Q
+  msg = this->msg_q_.front();
+
+  //- parano. debugging
+  DEBUG_ASSERT(msg != 0);
+
+  //- if the msg is a ctrl msg...
+  if (msg->is_ctrl_message())
+  {
+    //... then extract it from the Q and return it
+	  this->msg_q_.pop_front();
+    //- if we reach the low water mark, then wakeup msg producer(s) 
+    if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_)
+    {
+      //- no longer saturated
+      this->saturated_ = false;
+      //- this will work since we are still under critical section
+      this->msg_producer_sync_.broadcast();
+    }
+    //- we are about to return a ctrl msg so...
+    this->last_returned_msg_periodic_ = false;
+    //- return ctrl message
+    //- std::cout << "MessageQ::next_message::returning a CTRL msg" << std::endl; 
+	  return msg;
+  }
+
+  //- avoid PERIODIC msg starvation (see note above)
+  if (
+       this->enable_periodic_msg_ 
+         &&
+       this->periodic_tmo_expired(_tmo_msecs) 
+         && 
+       this->last_returned_msg_periodic_ == false
+     )
+  {
+      //- we didn't actually extract the <msg> from the Q.
+      //- we just "accessed it using "pop_front" so no need to reinject it into the Q
+      this->last_returned_msg_periodic_ = true;
+      GET_TIME(this->last_periodic_msg_ts_);
+      //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC msg" << std::endl; 
+      return new Message(TASK_PERIODIC); 
+  }
+  
+  //- we are about to return a msg from the Q so...
+  this->last_returned_msg_periodic_ = false;
+  
+  //- then extract it from the Q and return it
+  this->msg_q_.pop_front();
+  
+  //- if we reach the low water mark, then wakeup msg producer(s) 
+  if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_)
+  {
+    //- no longer saturated
+    this->saturated_ = false;
+    //- this will work since we are still under critical section
+    this->msg_producer_sync_.broadcast(); 
+  }
+	
+	//- std::cout << "MessageQ::next_message::returning USER msg" << std::endl; 
+	
+	return msg;
+}
+
+// ============================================================================
+// MessageQ::wait_not_empty_i
+// ============================================================================
+bool MessageQ::wait_not_empty_i (size_t _tmo_msecs)
+{
+	//- <this->lock_> MUST be locked by the calling thread
+  //----------------------------------------------------
+
+  //- while the messageQ is empty...
+  while (this->msg_q_.empty())
+  {
+ 	  //- wait for a msg or tmo expiration 
+    if (! this->msg_consumer_sync_.timed_wait(_tmo_msecs))
+      return false; 
+  }
+
+  //- at least one message available in the MsgQ
+  return true;
+} 
+
+// ============================================================================
+// MessageQ::wait_not_full_i
+// ============================================================================
+bool MessageQ::wait_not_full_i (size_t _tmo_msecs)
+{
+	//- <this->lock_> MUST be locked by the calling thread
+  //----------------------------------------------------
+
+  //- while the messageQ is full...
+  while (this->saturated_)
+  {
+ 	  //- wait for some msgs to be consumed or tmo expiration 
+    if (! this->msg_producer_sync_.timed_wait(_tmo_msecs))
+      return false; 
+  }
+
+  //- at least one message available in the MsgQ
+  return true;
+}
+
+// ============================================================================
+// Binary predicate
+// ============================================================================
+static bool insert_msg_criterion (Message * const m1, Message * const m2)
+{
+  return m2->priority() < m1->priority();  
+}
+ 
+// ============================================================================
+// MessageQ::insert_i
+// ============================================================================
+void MessageQ::insert_i (Message * _msg)
+  throw (Tango::DevFailed)
+{
+  try
+  {
+    if (this->msg_q_.empty())
+    {
+      //- optimization: no need to take count of the msg priority
+      this->msg_q_.push_front (_msg);
+    }
+    else
+    { 
+      //- insert msg according to its priority
+      MessageQImpl::iterator pos = std::upper_bound(this->msg_q_.begin(),
+                                                    this->msg_q_.end(),
+                                                    _msg,
+                                                    insert_msg_criterion);
+      this->msg_q_.insert(pos, _msg);
+    }
+  }
+  catch (...)
+  {
+    _msg->processed();
+    _msg->release();
+    Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                    _CPTC ("could insert message into the message queue"),
+                                    _CPTC ("MessageQ::insert_i"));
+ 
+  }
+}
+
+} // namespace bpm
diff --git a/src/MessageQ.h b/src/MessageQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee8af1d8f7aab0b6bd4fa49d2267158a0834823f
--- /dev/null
+++ b/src/MessageQ.h
@@ -0,0 +1,200 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MSGQ_H_
+#define _BPM_MSGQ_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <list>
+#include "CommonHeader.h"
+#include "threading/Message.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_THD_TMO_MSECS 1000
+#if defined(kDEFAULT_MSG_TMO_MSECS)
+# undef kDEFAULT_MSG_TMO_MSECS
+#endif
+#define kDEFAULT_MSG_TMO_MSECS 2500
+//-----------------------------------------------------------------------------
+#define kDEFAULT_POST_MSG_TMO   1000
+#define kDEFAULT_LO_WATER_MARK  256
+#define kDEFAULT_HI_WATER_MARK  512
+#define kMIN_LO_WATER_MARK      kDEFAULT_LO_WATER_MARK
+#define kMIN_WATER_MARKS_DIFF   kDEFAULT_LO_WATER_MARK
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// class: MessageQ
+// ============================================================================
+class MessageQ
+{
+  friend class Task;
+
+  typedef std::list<bpm::Message *> MessageQImpl;
+
+public:
+
+  //- MessageQ has a state
+  typedef enum
+  {
+    OPEN,
+    CLOSED
+  } State;
+
+  //- post a bpm::Message into the msgQ
+  void post (bpm::Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) 
+    throw (Tango::DevFailed);
+
+  //- post a cspi event into the msgQ
+  void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) 
+    throw (Tango::DevFailed);
+
+  //- extract next message from the msgQ
+  bpm::Message * next_message (size_t tmo_msecs);
+  
+  //- low water mark mutator
+  void lo_wm (size_t _lo_wm);
+
+  //- low water mark accessor
+  size_t lo_wm () const;
+
+  //- high water mark mutator
+  void hi_wm (size_t _hi_wm);
+
+  //- high water mark accessor
+  size_t hi_wm () const;
+
+  //- should the msgQ throw an exception on post msg tmo expiration?
+  void throw_on_post_msg_timeout (bool _strategy);
+  
+  //- clear msgQ content 
+	void clear();
+	
+  //- close the msqQ
+  void close (void);
+
+  //- enable/disable timeout msg 
+  void enable_timeout_msg (bool b);
+  bool timeout_msg_enabled () const;
+  
+  //- enable/disable handling flag
+  void enable_periodic_msg (bool b);
+  bool periodic_msg_enabled () const;
+  
+private:
+  //- private ctor
+  MessageQ (size_t lo_wm = kDEFAULT_LO_WATER_MARK,
+            size_t hi_wm = kDEFAULT_HI_WATER_MARK,
+            bool throw_on_post_tmo = false);
+            
+  //- private ctor
+  virtual ~MessageQ ();
+            
+  //- check the periodic msg timeout
+  bool periodic_tmo_expired (double tmo_msecs) const;
+
+  //- clears msgQ content (returns num of trashed messages)
+	size_t clear_i();
+
+  //- waits for the msQ to contain at least one msg
+  //- returns false if tmo expired, true otherwise.
+  bool wait_not_empty_i (size_t tmo_msecs);
+
+  //- waits for the msQ to have room for new messages
+  //- returns false if tmo expired, true otherwise.
+  bool wait_not_full_i (size_t tmo_msecs);
+
+  //- insert a msg according to its priority
+  void insert_i (Message * msg)
+    throw (Tango::DevFailed);
+
+	//- use a std::deque to implement msgQ
+	MessageQImpl msg_q_;
+
+	//- sync. object in order to make the msgQ thread safe
+	bpm::Mutex lock_;
+
+	//- Producer(s) synch object
+	bpm::Condition msg_producer_sync_;
+
+	//- Consumer synch object
+	bpm::Condition msg_consumer_sync_;
+	
+	//- state
+	MessageQ::State state_;
+
+  //- timeout msg handling flag
+  bool enable_timeout_msg_;
+
+  //- periodic msg handling flag
+  bool enable_periodic_msg_;
+
+  //- last returned PERIODIC msg timestamp
+  TIME_VAL last_periodic_msg_ts_;
+
+  //- low water marks
+  size_t lo_wm_;
+
+  //- high water marks
+  size_t hi_wm_;
+
+  //- msqQ saturation flag
+  bool saturated_;
+
+  //- expection activation flag
+  bool throw_on_post_msg_timeout_;
+  
+  //- flag indicating whether or not the last returned msg was a periodoc msg
+  //- we use this flag in order to avoid PERIODIC event flooding in case
+  //- the PERIODIC event frequency is really high - which could prevent other
+  //- messages from being handled. reciprocally, a very high msg posting freq.
+  //- could prevent the PERIODIC msg from being handled. the following tries
+  //- to ensure that any msg is "finally" handled.
+  bool last_returned_msg_periodic_;
+  
+  // = Disallow these operations.
+  //--------------------------------------------
+  MessageQ & operator= (const MessageQ &);
+  MessageQ (const MessageQ &);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/MessageQ.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_MSGQ_H_
diff --git a/src/Mutex.h b/src/Mutex.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1fd465d4e30697e324d930a67f92d183f4225d0
--- /dev/null
+++ b/src/Mutex.h
@@ -0,0 +1,237 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MUTEX_H_
+#define _BPM_MUTEX_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Utilities.h"
+#include "threading/Implementation.h"
+
+// ============================================================================
+// Implementation-specific header file.
+// ============================================================================
+#if ! defined(__MUTEX_IMPLEMENTATION)
+# error "implementation header file incomplete [no mutex implementation]"
+#endif
+
+namespace bpm {
+
+// ============================================================================
+//! <BPM_MUTEX>::try_lock may return one of the following MutexState
+// ============================================================================
+typedef enum
+{
+  MUTEX_LOCKED,
+  MUTEX_BUSY,
+} MutexState;
+
+// ============================================================================
+//! The BPM NullMutex class
+// ============================================================================
+class NullMutex
+{
+  //! This is the yat NullMutex class.
+  //!
+  //! Provides a "do nothing" Mutex impl. May be used as template argument
+  //! in order to control the template instanciation and avoiding locking
+  //! overhead where thread safety is not required.
+  //!
+  //! template <typename LOCK> class OptionalThreadSafetyImpl
+  //! {
+  //! public:
+  //!   inline void do_something (void)
+  //!   {
+  //!      yat::AutoMutex<LOCK>(this->m_mutex);
+  //!      ...
+  //!   }
+  //! private:
+  //    LOCK m_mutex;
+  //! }
+  //!
+  //! OptionalThreadSafetyImpl<yat::Mutex> will be thread safe while...
+  //! OptionalThreadSafetyImpl<yat::NullMutex> will not be!
+  //!
+  //! This class is not supposed to be derived.
+
+public:
+  //! Constructor.
+  NullMutex (void);
+
+  //! Destructor.
+  ~NullMutex (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void lock (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void acquire (void);
+
+  //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED.
+  MutexState try_lock (void);
+
+  //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED.
+  MutexState try_acquire (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void unlock (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void release (void);
+
+private:
+  //! Not implemented private member
+  NullMutex (const NullMutex&);
+  //! Not implemented private member
+  NullMutex & operator= (const NullMutex&);
+};
+
+// ============================================================================
+//! The BPM Mutex class
+// ============================================================================
+class Mutex
+{
+  //! This is the yat Mutex implementation.
+  //!
+  //! This class is not supposed to be derived (no virtual destructor).
+
+public:
+  //! Constructor.
+  Mutex (void);
+
+  //! Destructor.
+  ~Mutex (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void lock (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void acquire (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  //! Returns MUTEX_LOCKED in case the mutex was successfully locked.
+  //! Returns MUTEX_BUSY if it is already owned by another thread.
+  MutexState try_lock (void);
+  
+  //! Locks (i.e. acquires) the mutex.
+  //! Returns MUTEX_LOCKED in case the mutex was successfully locked.
+  //! Returns MUTEX_BUSY if it is already owned by another thread.
+  MutexState try_acquire (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void unlock (void);
+  
+  //! Unlocks (i.e. releases) the mutex.
+  void release (void);
+
+private:
+  //! Not implemented private member
+  Mutex (const Mutex&);
+  //! Not implemented private member
+  Mutex & operator= (const Mutex&);
+
+  //- platform specific implementation
+  __MUTEX_IMPLEMENTATION;
+};
+
+// ============================================================================
+//! The BPM "auto mutex" class
+// ============================================================================
+template <typename LOCK_TYPE = bpm::Mutex> class AutoMutex
+{
+  //! An "auto mutex" providing an auto lock/unlock mechanism.
+  //!
+  //! The AutoMutex is ideal in context where some exceptions may be thrown.
+  //! Whatever is the exit path of your code, the <AutoMutex> will garantee
+  //! that the associated <Mutex> is properly unlock.
+  //!
+  //! This class is template since it may be used in contexts in which the
+  //! thread safety is optionnal (see yat::NullMutex for an example).
+  //!
+  //! AutoMutex provides an efficient and safe alternative to:
+  //!
+  //! { //- enter critical section
+  //!   my_mutex.lock();
+  //!   ...your critical section code goes here (may throw an exception)...
+  //!   my_mutex.unlock();
+  //! } //- leave critical section
+  //!
+  //! In such a context, you can use a instance AutoMutex as follows:
+  //!
+  //! { //- enter critical section
+  //!   yat::AutoMutex<> guard(my_mutex);
+  //!   ...your critical section code goes here (may throw an exception)...
+  //! } //- leave critical section
+  //!
+  //! This has the advantage that my_mutex.unlock() will be called automatically
+  //! even if an exception is thrown. Since the AutoMutex is created on the stack
+  //! its destructor will be called whatever is the exit path of critical section.
+  //!
+  //! Note that AutoMutex can be used with any "LOCK_TYPE" which interface contains
+  //! both a lock(void) and a unlock(void) method. The yat::SharedObject class of
+  //! such a compatible "LOCK_TYPE". 
+  //!
+public:
+  //! Constructor (locks the associated Mutex)
+  AutoMutex (LOCK_TYPE & _lock)
+    : m_lock (_lock)
+  {
+    m_lock.lock();
+  }
+
+  //! Destructor (unlocks the associated Mutex)
+  ~AutoMutex (void)
+  {
+    m_lock.unlock();
+  }
+
+private:
+  //! The associated Mutex
+  LOCK_TYPE & m_lock;
+
+  //! Not implemented private member
+  AutoMutex (const AutoMutex&);
+  //! Not implemented private member
+  AutoMutex & operator= (const AutoMutex&);
+};
+
+// ============================================================================
+//! MutexLock: an AutoMutex specialisation (for backforward compatibility)
+// ============================================================================
+typedef AutoMutex<Mutex> MutexLock;
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+#  include "threading/impl/PosixMutexImpl.i"
+#endif
+
+#endif //- _BPM_MUTEX_H_
diff --git a/src/Offsets.cpp b/src/Offsets.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2dc7aae742eeef61bdf490225cfe8b01400f509
--- /dev/null
+++ b/src/Offsets.cpp
@@ -0,0 +1,576 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "StringTokenizer.h"
+#include "Offsets.h"
+
+
+#if !defined (__INLINE_IMPL__)
+# include "Offsets.i"
+#endif // __INLINE_IMPL__
+
+// ============================================================================
+// RETURN_PARAM_OR_THROW_EX
+// ============================================================================
+/*
+#define RETURN_PARAM_OR_THROW_EXCEPT(_PARAMS_, _IDX_) \
+case _IDX_: \
+  if (_PARAMS_[_IDX_] != -1) return _PARAMS_[_IDX_]; \
+  Tango::Except::throw_exception(_CPTC("SOFTWARE_FAILURE"), \
+                                 _CPTC("invalid BPM parameter [undefined]"), \
+                                 _CPTC("BPMOffsets::operator[]")); \
+  break; \
+*/
+// ============================================================================
+#define RETURN_PARAM(_IDX_) \
+  case _IDX_: \
+    return this->bpm_params[_IDX_]; \
+    break;
+// ============================================================================
+#define RETURN_PARAM_NAME( _IDX_) \
+  case _IDX_: \
+    return BPMOffsets::bpm_params_names[_IDX_]; \
+    break;
+// ============================================================================
+#define LOG_PARAM(_TYPE_, _IDX_) \
+// std::cout << _TYPE_ 
+//           << BPMOffsets::bpm_params_names[_IDX_] 
+//           << "::" 
+//           << this->bpm_params[_IDX_] 
+//           << std::endl;
+
+// ============================================================================
+#define SEP ":"
+// ----------------------------------------------------------------------------
+#define NUM_BLOCK_PARAMS   (Z_ALARM - GEOMETRY + 1)
+#define NUM_HW_PARAMS      (Z_OFFSET_5 - KX + 1)
+// ----------------------------------------------------------------------------
+#define DEVICE_PARAMS_PROPERTY_NUM_TOKENS  3
+#define KX_KZ_PARAMS_PROPERTY_NUM_TOKENS   3
+#define BLOCK_PARAMS_PROPERTY_NUM_TOKENS   (NUM_BLOCK_PARAMS + 1)
+#define HW_PARAMS_PROPERTY_NUM_TOKENS      (NUM_HW_PARAMS - 2 + 1)
+// ----------------------------------------------------------------------------
+
+namespace
+      bpm
+{
+
+// ============================================================================
+// BPM parameter names
+// ============================================================================
+const char *
+BPMOffsets::bpm_params_names[] =
+  {
+    //- hw params
+    "GEOMETRY",
+    "Q_OFFSET_1",
+    "A_OFFSET_E",
+    "B_OFFSET_E",
+    "C_OFFSET_E",
+    "D_OFFSET_E",
+    "X_OFFSET_1",
+    "X_OFFSET_BBA",
+    "Z_OFFSET_1",
+    "Z_OFFSET_BBA",
+    "X_LOW",
+    "Z_LOW",
+    "X_HIGH",
+    "Z_HIGH",
+    "X_WARN",
+    "Z_WARN",
+    "X_ALARM",
+    "Z_ALARM",
+    //- hw params
+    "KX",
+    "KZ",
+    "Q_OFFSET_2",
+    "A_OFFSET_C",
+    "B_OFFSET_C",
+    "C_OFFSET_C",
+    "D_OFFSET_C",
+    "X_OFFSET_3",
+    "RESERVED_1",
+    "RESERVED_2",
+    "X_OFFSET_4",
+    "X_OFFSET_5",
+    "Z_OFFSET_3",
+    "RESERVED_3",
+    "RESERVED_4",
+    "Z_OFFSET_4",
+    "Z_OFFSET_5"
+  };
+
+// ============================================================================
+// BPMOffsets::BPMOffsets
+// ============================================================================
+BPMOffsets::BPMOffsets (void)
+{
+  this->device = 0;
+  this->block_id = "unspecified";
+  this->hw_id = "unspecified";
+  this->bpm_params.resize (LAST_PARAMETER);
+  this->bpm_params.assign (this->bpm_params.size (), 0);
+}
+
+// ============================================================================
+// BPMOffsets::BPMOffsets
+// ============================================================================
+BPMOffsets::BPMOffsets (const BPMOffsets & _src)
+{
+  //- delegate copy to operator=
+  *this = _src;
+}
+
+// ============================================================================
+// BPMOffsets::~BPMOffsets
+// ============================================================================
+BPMOffsets::~BPMOffsets (void)
+{
+  //- noop dtor
+}
+
+// ============================================================================
+// BPMOffsets::operator=
+// ============================================================================
+BPMOffsets & BPMOffsets::operator= (const BPMOffsets & _src)
+{
+  //- avoid self copy
+  if (&_src == this)
+    return *this;
+  this->device = _src.device;
+  this->block_id = _src.block_id;
+  this->hw_id = _src.hw_id;
+  this->bpm_params = _src.bpm_params;
+  return *this;
+}
+
+// ============================================================================
+// BPMOffsets::operator==
+// ============================================================================
+bool BPMOffsets::operator== (const BPMOffsets & _src)
+{
+  return this->bpm_params == _src.bpm_params;
+}
+
+// ============================================================================
+// BPMOffsets::operator!=
+// ============================================================================
+bool BPMOffsets::operator!= (const BPMOffsets & _src)
+{
+  return this->bpm_params != _src.bpm_params;
+}
+
+// ============================================================================
+// BPMOffsets::read_from_tango_db
+// ============================================================================
+void
+BPMOffsets::read_from_tango_db (BPMLocation _location, Tango::DeviceImpl * _device)
+throw (Tango::DevFailed)
+{
+  //- store device locally
+  this->device = _device;
+
+  //- be sure device is valid
+  if (this->device == 0)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("unexpected null parameter"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+
+  //- obtain a reference to the TANGO database
+  Tango::Database * db = device->get_db_device ()->get_dbase ();
+  if (db == 0)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("unexpected null reference to TANGO database"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+
+  //----------------------------------------------------------------------
+  //- get kx & kz - SOLEIL system property: KxKzParameters
+  //----------------------------------------------------------------------
+  // this system property is a vector of strings (one entry per device)
+  // for a given device the string contains the location id and the kx
+  // and kz parameters. The following syntax is used:
+  // <location>:kx:kz
+  //----------------------------------------------------------------------
+  bool found = false;
+  Tango::DbData bpm_dbdata;
+  try
+  {
+    //- get value from database
+    bpm_dbdata.push_back (Tango::DbDatum (KX_KZ_PARAMS_PROPERTY));
+    db->get_property (BPM_ROOT_PROPERTY, bpm_dbdata);
+  }
+  catch (Tango::DevFailed & df)
+  {
+    Tango::Except::re_throw_exception (df, 
+                                       _CPTC ("SOFTWARE_FAILURE"), 
+                                       _CPTC ("TANGO exception caught while trying to read BPM Kx/Kz parameters [system property]"), 
+                                       _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- set location we search
+  std::string searched_location;
+  switch (_location)
+  {
+  case BPM_LOC_TL1:
+    searched_location = LOCATION_TL1;
+    break;
+  case BPM_LOC_BOOSTER:
+    searched_location = LOCATION_BOOSTER;
+    break;
+  case BPM_LOC_TL2:
+    searched_location = LOCATION_TL2;
+    break;
+  case BPM_LOC_STORAGE_RING:
+    searched_location = LOCATION_STORAGE_RING;
+    break;
+  case BPM_LOC_UNKNOWN:
+    Tango::Except::throw_exception (_CPTC ("unexpected location"), 
+                                    _CPTC ("unknown BPM location"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+    break;
+  }
+  //- tmp log
+  //- std::cout << "BPM::KxKzParameters::searched_location::" << searched_location << std::endl;
+  //- extract value as a vector of strings
+  std::vector < std::string > bpm_params_prop;
+  if ((bpm_dbdata[0] >> bpm_params_prop) == false)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("TANGO exception caught while trying to extract data from BPM Kx/Kz parameters [system property]"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- get properties for this->device
+  for (size_t i = 0; i < bpm_params_prop.size (); i++)
+  {
+    StringTokenizer
+    tokens (bpm_params_prop[i], SEP);
+    //- tmp log
+    //- std::cout << "BPM::KxKzParameters::entry-" << i << "::" << bpm_params_prop[i] << std::endl;
+    //- get number of tokens in current entry
+    int
+    num_tokens = tokens.countTokens ();
+    //- tmp log
+    //- std::cout << "BPM::KxKzParameters::entry-" << i << " contains " << num_tokens << " tokens" << std::endl;
+    //- token-1: device name
+    std::string location = tokens.nextToken ();
+    if (location == searched_location)
+    {
+      //- tokens should cointains 3 tokens
+      if (num_tokens != KX_KZ_PARAMS_PROPERTY_NUM_TOKENS)
+      {
+        Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                        _CPTC ("invalid BPM Kx/Kz parameters [system property syntax error]"), 
+                                        _CPTC ("BPMOffsets::read_from_tango_db"));
+      }
+      //- mark as found
+      found = true;
+      //- token-2: kx
+      this->bpm_params[KX] = tokens.nextFPToken ();
+      //- tmp log
+      //- std::cout << "BPM::KxKzParameters::entry-" << i << "::Kx:" << this->bpm_params[KX] << std::endl;
+      //- token-2: kz
+      this->bpm_params[KZ] = tokens.nextFPToken ();
+      //- tmp log
+      //- std::cout << "BPM::KxKzParameters::entry-" << i << "::Kz:" << this->bpm_params[KZ] << std::endl;
+      //- found... so abort
+      break;
+    }
+  }
+  //- could not found device parameters for this->device
+  if (!found)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("no BPM Kx/Kz parameters found for this location"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+
+  //----------------------------------------------------------------------
+  //- get block id - SOLEIL system property: DeviceParameters
+  //----------------------------------------------------------------------
+  // this system property is a vector of strings (one entry per device)
+  // for a given device the string contains the blcok id and the libera
+  // serial number. The following syntax is used:
+  // <dev-name-prefix/xxx/xxx>:block-id:serial-num
+  //----------------------------------------------------------------------
+  found = false;
+  try
+  {
+    //- get value from database
+    bpm_dbdata.clear ();
+    bpm_dbdata.push_back (Tango::DbDatum (DEVICE_PARAMS_PROPERTY));
+    db->get_property (BPM_ROOT_PROPERTY, bpm_dbdata);
+  }
+  catch (Tango::DevFailed & df)
+  {
+    Tango::Except::re_throw_exception (df, 
+                                      _CPTC ("SOFTWARE_FAILURE"), 
+                                      _CPTC ("TANGO exception caught while trying to read BPM device parameters [system property]"), 
+                                      _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- extract value as a vector of strings
+  bpm_params_prop.clear ();
+  if ((bpm_dbdata[0] >> bpm_params_prop) == false)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("TANGO exception caught while trying to extract data from BPM device parameters [system property]"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- actual device name
+  std::string adn = this->device->name ();
+  std::transform (adn.begin (), adn.end (), adn.begin (),::tolower);
+  //- get properties for this->device
+  for (size_t i = 0; i < bpm_params_prop.size (); i++)
+  {
+    StringTokenizer
+    tokens (bpm_params_prop[i], SEP);
+    //- tmp log
+    //- std::cout << "BPM::DeviceParameters::entry-" << i << "::" << bpm_params_prop[i] << std::endl;
+    //- get number of tokens in current entry
+    int
+    num_tokens = tokens.countTokens ();
+    //- tmp log
+    //- std::cout << "BPM::DeviceParameters::entry-" << i << " contains " << num_tokens << " tokens" << std::endl;
+    //- token-1: device name
+    std::string tdn = tokens.nextToken ();
+    std::transform (tdn.begin (), tdn.end (), tdn.begin (),::tolower);
+    if (tdn == adn)
+    {
+      //- tokens should cointains LAST_DEVICE_PARAMETER tokens
+      if (num_tokens != DEVICE_PARAMS_PROPERTY_NUM_TOKENS)
+      {
+        Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                        _CPTC ("invalid BPM device parameters [system property syntax error]"), 
+                                        _CPTC ("BPMOffsets::read_from_tango_db"));
+      }
+      //- mark as found
+      found = true;
+      //- token-2: block id
+      this->block_id = tokens.nextToken ();
+      //- tmp log
+      //- std::cout << "BPM::DeviceParameters::entry-" << i << "::block-id:" << this->block_id << std::endl;
+      //- token-3: libera hw id
+      this->hw_id = tokens.nextToken ();
+      //- tmp log
+      //- std::cout << "BPM::DeviceParameters::entry-" << i << "::hw-serial#:" << this->hw_id << std::endl;
+      //- found... so abort
+      break;
+    }
+  }
+  //- could not found device parameters for this->device
+  if (!found)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("no BPM device parameters found in system property"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+
+  //----------------------------------------------------------------------
+  //- get block parameters - SOLEIL system property: BlockParameters
+  //----------------------------------------------------------------------
+  // this system property is a vector of strings (one entry per device)
+  // for a given device the string contains all the block parmeters. The
+  // following syntax is used:
+  // block-id:p1-name:p1-value:p1-name:p2-value:....
+  //----------------------------------------------------------------------
+  found = false;
+  try
+  {
+    //- get value from database
+    bpm_dbdata.clear ();
+    bpm_dbdata.push_back (Tango::DbDatum (BLOCK_PARAMS_PROPERTY));
+    db->get_property (BPM_ROOT_PROPERTY, bpm_dbdata);
+  }
+  catch (Tango::DevFailed & df)
+  {
+    Tango::Except::re_throw_exception (df, 
+                                       _CPTC ("SOFTWARE_FAILURE"), 
+                                       _CPTC ("TANGO exception caught while trying to read BPM block parameters [system property]"), 
+                                       _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- extract value as a vector of strings
+  bpm_params_prop.clear ();
+  if ((bpm_dbdata[0] >> bpm_params_prop) == false)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("TANGO exception caught while trying to extract data from BPM block parameters [system property]"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- get properties for this->device
+  for (size_t i = 0; i < bpm_params_prop.size (); i++)
+  {
+    StringTokenizer
+    tokens (bpm_params_prop[i], SEP);
+    //- tmp log
+    //- std::cout << "BPM::BlockParameters::entry-" << i << "::" << bpm_params_prop[i] << std::endl;
+    //- get number of tokens in current entry
+    int
+    num_tokens = tokens.countTokens ();
+    //- tmp log
+    //- std::cout << "BPM::BlockParameters::entry-" << i << " contains " << num_tokens << " tokens" << std::endl;
+    //- token-1: block id
+    std::string bid = tokens.nextToken ();
+    if (bid == this->block_id)
+    {
+      //- tokens should cointains [LAST_BLOCK_PARAMETER + 1] tokens
+      if (num_tokens != BLOCK_PARAMS_PROPERTY_NUM_TOKENS)
+      {
+        Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                        _CPTC ("invalid BPM block parameters [system property syntax error]"), 
+                                        _CPTC ("BPMOffsets::read_from_tango_db"));
+      }
+      //- mark as found
+      found = true;
+      //- get block parameter
+      size_t
+      max = GEOMETRY + NUM_BLOCK_PARAMS;
+      for (size_t p = GEOMETRY; p < max; p++)
+      {
+        //- store parameter in local vector
+        this->bpm_params[p] = (BPMOffsets::FpOffsetsType) tokens.nextFPToken();
+        //- tmp log
+        LOG_PARAM ("BLOCK::", p);
+      }
+      //- found... so abort
+      break;
+    }
+  }
+
+  //----------------------------------------------------------------------
+  //- get hw parameters - SOLEIL system property: BPMHwParameters
+  //----------------------------------------------------------------------
+  // this system property is a vector of strings (one entry per device)
+  // for a given device the string contains all the libera hw parmeters.
+  // The following syntax is used:
+  // libera-hw-serial-num:p1-name:p1-value:p1-name:p2-value:....
+  //----------------------------------------------------------------------
+  found = false;
+  try
+  {
+    //- get value from database
+    bpm_dbdata.clear ();
+    bpm_dbdata.push_back (Tango::DbDatum (HW_PARAMS_PROPERTY));
+    db->get_property (BPM_ROOT_PROPERTY, bpm_dbdata);
+  }
+  catch (Tango::DevFailed & df)
+  {
+    Tango::Except::re_throw_exception (df, 
+                                       _CPTC ("SOFTWARE_FAILURE"), 
+                                       _CPTC ("TANGO exception caught while trying to read BPM hardware parameters [system property]"), 
+                                       _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- extract value as a vector of strings
+  bpm_params_prop.clear ();
+  if ((bpm_dbdata[0] >> bpm_params_prop) == false)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("TANGO exception caught while trying to extract data from BPM hardware parameters [system property]"), 
+                                    _CPTC ("BPMOffsets::read_from_tango_db"));
+  }
+  //- get properties for this->device
+  for (size_t i = 0; i < bpm_params_prop.size (); i++)
+  {
+    StringTokenizer
+    tokens (bpm_params_prop[i], SEP);
+    //- tmp log
+    //- std::cout << "BPM::HwParameters::entry-" << i << "::" << bpm_params_prop[i] << std::endl;
+    //- get number of tokens in current entry
+    int
+    num_tokens = tokens.countTokens ();
+    //- tmp log
+    //- std::cout << "BPM::HwParameters::entry-" << i << " contains " << num_tokens << " tokens" << std::endl;
+    //- token-1: libera hw id
+    std::string hwid = tokens.nextToken ();
+    if (hwid == this->hw_id)
+    {
+      //- tokens should cointains HW_PARAMS_PROPERTY_NUM_TOKENS
+      if (num_tokens != HW_PARAMS_PROPERTY_NUM_TOKENS)
+      {
+        Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                        _CPTC ("invalid BPM hardware parameters [system property syntax error]"), 
+                                        _CPTC ("BPMOffsets::read_from_tango_db"));
+      }
+      //- mark as found
+      found = true;
+      //- get block parameter
+      size_t
+      max = Q_OFFSET_2 + NUM_HW_PARAMS - 2;
+      for (size_t p = Q_OFFSET_2; p < max; p++)
+      {
+        //- store parameter in local vector
+        this->bpm_params[p] = 
+                static_cast<BPMOffsets::FpOffsetsType>(tokens.nextFPToken ());
+        //- tmp log
+        LOG_PARAM ("HW::", p);
+      }
+      //- found... so abort
+      break;
+    }
+  }
+
+}
+
+// ============================================================================
+// BPMOffsets::operator[]
+// ============================================================================
+BPMOffsets::FpOffsetsType BPMOffsets::operator[](int idx) const
+throw (Tango::DevFailed)
+{
+  if (idx < GEOMETRY || idx >= LAST_PARAMETER)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("unknown BPM parameter [invalid id specified]"), 
+                                    _CPTC ("BPMOffsets::operator[]"));
+  }
+  return this->bpm_params[idx];
+}
+
+// ============================================================================
+// BPMOffsets::parameter_name
+// ============================================================================
+const char *
+BPMOffsets::parameter_name (int idx) const
+throw (Tango::DevFailed)
+{
+  if (idx < GEOMETRY || idx >= LAST_PARAMETER)
+  {
+    Tango::Except::throw_exception (_CPTC ("SOFTWARE_FAILURE"), 
+                                    _CPTC ("unknown BPM parameter [invalid id specified]"), 
+                                    _CPTC ("BPMOffsets::parameter_name"));
+  }
+  return BPMOffsets::bpm_params_names[idx];
+}
+
+}                               // namespace bpm
diff --git a/src/Offsets.h b/src/Offsets.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aaea771282d719dfe0afbd2705756c14ef37a72
--- /dev/null
+++ b/src/Offsets.h
@@ -0,0 +1,195 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_OFFSETS_H_
+#define _BPM_OFFSETS_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "BPMLocation.h"
+
+// ============================================================================
+// SYSTEM WIDE PROPERTIES
+// ============================================================================
+#define BPM_ROOT_PROPERTY       "BPM"
+#define KX_KZ_PARAMS_PROPERTY   "KxKzParameters"
+#define DEVICE_PARAMS_PROPERTY  "DeviceParameters"
+#define BLOCK_PARAMS_PROPERTY   "BlockParameters"
+#define HW_PARAMS_PROPERTY      "HwParameters"
+// ----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+//! Offests abstraction class.
+// ============================================================================
+//!
+//! detailed description to be defined
+//!
+// ============================================================================
+class BPMOffsets
+{
+  friend class BPM;
+
+public:
+
+  typedef FPDataType FpOffsetsType;
+
+  //- BPM parameters IDs ----------------------------------
+  enum
+  {
+    //- block parameters
+    GEOMETRY,
+    Q_OFFSET_1,
+    A_BLOCK_GAIN_CORRECTION,
+    B_BLOCK_GAIN_CORRECTION,
+    C_BLOCK_GAIN_CORRECTION,
+    D_BLOCK_GAIN_CORRECTION,
+    X_OFFSET_1,
+    X_OFFSET_BBA,
+    Z_OFFSET_1,
+    Z_OFFSET_BBA,
+    X_LOW,
+    Z_LOW,
+    X_HIGH,
+    Z_HIGH,
+    X_WARN,
+    Z_WARN,
+    X_ALARM,
+    Z_ALARM,
+    //- hw parameters
+    KX,
+    KZ,
+    Q_OFFSET_2,
+    A_HW_GAIN_CORRECTION,
+    B_HW_GAIN_CORRECTION,
+    C_HW_GAIN_CORRECTION,
+    D_HW_GAIN_CORRECTION,
+    X_OFFSET_3,
+    RESERVED_1,
+    RESERVED_2,
+    X_OFFSET_4,
+    X_OFFSET_5,
+    Z_OFFSET_3,
+    RESERVED_3,
+    RESERVED_4,
+    Z_OFFSET_4,
+    Z_OFFSET_5,
+    //- last parameter
+    LAST_PARAMETER
+  };
+
+  /**
+   * BPMOffsets default ctor 
+   */
+  BPMOffsets (void);
+
+  /**
+   * BPMOffsets copy ctor
+   * \param src The source configuration.
+   */
+  BPMOffsets (const BPMOffsets & src);
+
+  /**
+   * BPMOffsets operator=
+   * \param src The source configuration.
+   */
+  BPMOffsets & operator= (const BPMOffsets & src);
+
+  /**
+   * BPMOffsets dtor
+   */
+  virtual ~ BPMOffsets (void);
+
+  /**
+   * BPMOffsets operator==
+   * \param src The source configuration.
+   */
+  bool operator== (const BPMOffsets & src);
+  
+   /**
+   * BPMOffsets operator==
+   * \param src The source configuration.
+   */
+  bool operator!= (const BPMOffsets & src);
+  
+  /**
+   * Read all offsets and parameters from the TANGO database
+   */
+  void read_from_tango_db (BPMLocation location, Tango::DeviceImpl * device) 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the specified offset (use enum)
+   */
+  FpOffsetsType operator[] (int idx) const 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the name of the specified offset (use enum)
+   */
+  const char * parameter_name (int idx) const 
+    throw (Tango::DevFailed);
+
+  /**
+   * Returns the block identifier
+   */
+  const std::string & block_identifier (void) const;
+
+  /**
+   * Returns Libera hardware identifier
+   */
+  const std::string & hw_identifier (void) const;
+
+private:
+  //- The TANGO device
+  Tango::DeviceImpl * device;
+
+  //- Floating point params repository
+  std::vector<FpOffsetsType> bpm_params;
+  
+  //- Block identifier
+  std::string block_id;
+
+  //- Libera hardware identifier
+  std::string hw_id;
+  
+  //- BPM::device parameters names
+  static const char *bpm_params_names[];
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "Offsets.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_OFFSETS_H_
diff --git a/src/Offsets.i b/src/Offsets.i
new file mode 100644
index 0000000000000000000000000000000000000000..45b4a1fe91db223ae4455255a456b15cebd6b397
--- /dev/null
+++ b/src/Offsets.i
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// BPMOffsets::block_id
+// ============================================================================
+INLINE_IMPL const std::string & BPMOffsets::block_identifier (void) const
+{
+  return this->block_id;
+}
+
+// ============================================================================
+// BPMOffsets::hw_id
+// ============================================================================
+INLINE_IMPL const std::string & BPMOffsets::hw_identifier (void) const
+{
+  return this->hw_id;
+}
+
+}                               // namespace bpm
diff --git a/src/PosixConditionImpl.i b/src/PosixConditionImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..d7ad8805938dd0a11c04407171d572d87ad5270d
--- /dev/null
+++ b/src/PosixConditionImpl.i
@@ -0,0 +1,56 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Condition::wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::wait (void)
+{
+  this->timed_wait(0);
+}
+
+// ----------------------------------------------------------------------------
+// Condition::signal
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::signal (void)
+{
+  ::pthread_cond_signal(&m_posix_cond);
+}
+
+// ----------------------------------------------------------------------------
+// Condition::broadcast
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::broadcast (void)
+{
+  ::pthread_cond_broadcast(&m_posix_cond);
+}
+
+} // namespace bpm
diff --git a/src/PosixMutexImpl.i b/src/PosixMutexImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..b69da52438c114c889131475404ce8bde74e7503
--- /dev/null
+++ b/src/PosixMutexImpl.i
@@ -0,0 +1,138 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ****************************************************************************
+// BPM NULL MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// NullMutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::lock (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::acquire (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::unlock (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::release
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::release (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState NullMutex::try_lock (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState NullMutex::try_acquire (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ****************************************************************************
+// BPM MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Mutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::lock (void)
+{
+  ::pthread_mutex_lock(&m_posix_mux);
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::acquire (void)
+{
+  this->lock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState Mutex::try_acquire (void)
+{
+  return this->try_lock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::unlock (void)
+{
+  ::pthread_mutex_unlock(&m_posix_mux);
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::release (void)
+{
+  this->unlock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState Mutex::try_lock (void)
+{
+  MutexState result = MUTEX_LOCKED;
+
+  if (::pthread_mutex_trylock (&m_posix_mux) != 0)
+    result = MUTEX_BUSY;
+
+  return result;
+}
+
+} // namespace bpm
diff --git a/src/PosixSemaphoreImpl.i b/src/PosixSemaphoreImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..2bf16953eb84e15ef1fc082bec54933b272d8761
--- /dev/null
+++ b/src/PosixSemaphoreImpl.i
@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Semaphore::wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Semaphore::wait (void)
+{
+  this->timed_wait(0);
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::timed_wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL bool Semaphore::timed_wait (unsigned long _tmo_msecs)
+{
+  bool r = false;
+  this->m_mux.lock();
+  while (! this->m_value)
+  {
+    r = this->m_cond.timed_wait(_tmo_msecs);
+  }
+  if (r)
+  {
+    this->m_value--;
+  }
+  this->m_mux.unlock();
+  return r;
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::try_wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL SemaphoreState Semaphore::try_wait (void)
+{
+  SemaphoreState s;
+  this->m_mux.lock();
+  if (this->m_value > 0)
+  {
+    this->m_value--;
+    s = SEMAPHORE_DEC;
+ 	}
+	else
+	{
+	  s = SEMAPHORE_NO_RSC;
+	}
+  this->m_mux.unlock();
+  return s;
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::post
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Semaphore::post (void)
+{
+  this->m_mux.lock();
+  this->m_value++;
+  this->m_cond.signal();
+  this->m_mux.unlock();
+}
+
+} // namespace bpm
diff --git a/src/PosixThreadImpl.i b/src/PosixThreadImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..a7a912dd3c34d0db2c8f86ceaf564ed0d38f17b8
--- /dev/null
+++ b/src/PosixThreadImpl.i
@@ -0,0 +1,104 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Thread::priority
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::Priority Thread::priority (void)
+{
+  //- enter critical section
+  bpm::MutexLock guard(this->m_lock);
+
+  return this->m_priority;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::State Thread::state (void)
+{
+  //- enter critical section
+  bpm::MutexLock guard(this->m_lock);
+
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::State Thread::state_i (void) const
+{
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::yield
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::yield (void)
+{
+  ::sched_yield();
+}
+// ----------------------------------------------------------------------------
+// Thread::sleep
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::sleep (unsigned long _msecs)
+{
+#define kNSECS_PER_SEC  1000000000
+#define kNSECS_PER_MSEC 1000000
+
+  unsigned long secs = 0;
+  unsigned long nanosecs = kNSECS_PER_MSEC * _msecs;
+
+	while (nanosecs >= kNSECS_PER_SEC)
+	{
+		secs += 1;
+		nanosecs -= kNSECS_PER_SEC;
+	}
+
+  ThreadingUtilities::sleep(secs, nanosecs);
+
+#undef kNSECS_PER_MSEC
+#undef kNSECS_PER_SEC
+}
+// ----------------------------------------------------------------------------
+// Thread::self
+// ----------------------------------------------------------------------------
+INLINE_IMPL ThreadUID Thread::self (void) const
+{
+  return this->m_uid;
+}
+
+// ----------------------------------------------------------------------------
+// Thread::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL Mutex & Thread::lock (void)
+{
+  return this->m_lock;
+}
+  
+} // namespace bpm
diff --git a/src/PosixThreadingImpl.cpp b/src/PosixThreadingImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9475a7887d83c1799ff6eb2a12c3b314b067accd
--- /dev/null
+++ b/src/PosixThreadingImpl.cpp
@@ -0,0 +1,561 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <errno.h>
+#include <sys/time.h>
+#include "CommonHeader.h"
+#include "threading/Utilities.h"
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+#include "threading/Semaphore.h"
+#include "threading/Thread.h"
+
+#if ! defined (__INLINE_IMPL__)
+# include "threading/impl/PosixMutexImpl.i"
+# include "threading/impl/PosixConditionImpl.i"
+# include "threading/impl/PosixSemaphoreImpl.i"
+# include "threading/impl/PosixThreadImpl.i"
+#endif
+
+// ============================================================================
+// SOME PSEUDO CONSTs
+// ============================================================================
+#define MAX_SLEEP_SECONDS (long)4294966	//- this is (2^32 - 2) / 1000 
+#define NANOSECS_PER_SEC  1000000000L
+#define ONE_SEC_IN_MSECS  1000L
+
+// ============================================================================
+// PLATFORM SPECIFIC THREAD PRIORITIES
+// ============================================================================
+#if defined(HAS_THREAD_PRIORITY)
+ static int lowest_priority;
+ static int normal_priority;
+ static int highest_priority;
+#endif
+
+namespace bpm {
+
+// ****************************************************************************
+// BPM DUMMY_MUTEX IMPL
+// ****************************************************************************
+// ============================================================================
+// NullMutex::NullMutex
+// ============================================================================
+NullMutex::NullMutex (void)
+{
+ //- noop
+}
+// ============================================================================
+// NullMutex::~NullMutex
+// ============================================================================
+NullMutex::~NullMutex (void)
+{
+ //- noop
+}
+
+// ****************************************************************************
+// BPM MUTEX IMPL
+// ****************************************************************************
+// ============================================================================
+// Mutex::Mutex
+// ============================================================================
+Mutex::Mutex (void)
+  : m_posix_mux ()
+{
+  pthread_mutexattr_t ma;
+  ::pthread_mutexattr_init(&ma);
+  ::pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  ::pthread_mutex_init(&m_posix_mux, &ma);
+  ::pthread_mutexattr_destroy(&ma);
+}
+
+// ============================================================================
+// Mutex::~Mutex
+// ============================================================================
+Mutex::~Mutex(void)
+{
+  ::pthread_mutex_destroy(&m_posix_mux);
+}
+
+// ****************************************************************************
+// BPM SEMAPHORE IMPL
+// ****************************************************************************
+#define SEMAPHORE_MAX_COUNT 0x7fffffff
+
+// ============================================================================
+// Semaphore::Semaphore
+// ============================================================================
+Semaphore::Semaphore (unsigned int _initial_value)
+  : m_mux () , m_cond (m_mux), m_value (_initial_value)
+{
+  //- noop
+}
+
+// ============================================================================
+// Semaphore::~Semaphore
+// ============================================================================
+Semaphore::~Semaphore(void)
+{
+  //- noop
+}
+
+// ****************************************************************************
+// BPM CONDITION IMPL
+// ****************************************************************************
+// ============================================================================
+// Condition::Condition
+// ============================================================================
+Condition::Condition (Mutex & external_lock)
+ : m_external_lock (external_lock),
+   m_posix_cond ()
+{
+  ::pthread_cond_init(&m_posix_cond, 0);
+}
+
+// ============================================================================
+// Condition::~Condition
+// ============================================================================
+Condition::~Condition (void)
+{
+  ::pthread_cond_destroy(&m_posix_cond);
+}
+
+// ============================================================================
+// Condition::timed_wait
+// ============================================================================
+bool Condition::timed_wait (unsigned long _tmo_msecs)
+{
+  //- null tmo means infinite wait
+
+  bool signaled = true;
+ 
+	if (_tmo_msecs <= 0) 
+  {
+    ::pthread_cond_wait(&m_posix_cond, &m_external_lock.m_posix_mux);
+  }
+	else 
+  {
+		//- get absoulte time
+		struct timespec ts;
+		ThreadingUtilities::get_time(_tmo_msecs, ts);
+		
+    //- wait for the condition to be signaled or tmo expiration
+		int result = ::pthread_cond_timedwait(&m_posix_cond, 
+                                          &m_external_lock.m_posix_mux, 
+                                          &ts);
+                                          
+    if (result == ETIMEDOUT || result == EINTR)
+      signaled = false;
+      
+    /*
+    switch (result)
+    { 
+      case 0:
+        std::cout << "Condition::pthread_cond_timedwait returned: SUCCESS" << std::endl;
+        break;
+      case ETIMEDOUT:
+        std::cout << "Condition::pthread_cond_timedwait returned: ETIMEDOUT" << std::endl;
+        break;      
+      case EINTR:
+        std::cout << "Condition::pthread_cond_timedwait returned: EINTR" << std::endl;
+        break;
+    }
+    */
+	}
+
+  return signaled;
+}
+
+// ****************************************************************************
+// BPM THREAD IMPL
+// ****************************************************************************
+// ============================================================================
+// BPM common thread entry point (non-OO OS intertace to OO BPM interface)
+// ============================================================================
+Thread::IOArg bpm_thread_common_entry_point (Thread::IOArg _p)
+{
+  //- check input (parano. impl.)
+  if (! _p) return 0;
+
+  //- reinterpret input
+  Thread * me = reinterpret_cast<Thread*>(_p);
+
+  //- store the thread identifier
+  me->m_uid = ThreadingUtilities::self();
+
+  //- select detached or undetached mode
+  if (me->m_detached)
+  {
+    //- just protect bpm impl. against user code using a try/catch statement
+    try
+    {
+	    me->run(me->m_iarg);
+    }
+    catch (...)
+    {
+      //- ignore any exception
+    }
+  }
+  else 
+  {
+    //- just protect bpm impl. against user code using a try/catch statement
+    try
+    {
+	    me->m_oarg = me->run_undetached(me->m_iarg);
+    }
+    catch (...)
+    {
+      //- ignore any exception
+
+    }
+  }
+
+  //- set state to terminated
+  {
+    //- must lock the mutex even in the case of a detached thread. This is because
+    //- a thread may run to completion before the thread that created it has had a
+    //- chance to get out of start().  By locking the mutex we ensure that the
+    //- creating thread must have reached the end of start() before we delete the
+    //- thread object.  Of course, once the call to start() returns, the user can
+    //- still incorrectly refer to the thread object, but that's his problem!
+	  AutoMutex<Mutex> guard(me->m_lock);
+    //- set state to TERMINATED
+    me->m_state = bpm::Thread::STATE_TERMINATED;
+  }
+
+  //- commit suicide in case the thread ran detached
+	if (me->m_detached)
+    delete me;
+
+  return 0;
+}
+
+// ============================================================================
+// Thread::Thread
+// ============================================================================
+Thread::Thread (Tango::DeviceImpl * hd, Thread::IOArg _iarg, Thread::Priority _p)
+ : Tango::LogAdapter (hd),
+   m_state (bpm::Thread::STATE_NEW),
+   m_priority (_p),
+   m_iarg (_iarg),
+   m_oarg (0),
+   m_detached (true),
+   m_uid (BPM_INVALID_THREAD_UID),
+   //- platform specific members
+   m_posix_thread (0)
+{
+#if defined(HAS_THREAD_PRIORITY)
+ static bool init_done = false;
+ if (! init_done)
+ {
+   lowest_priority = ::sched_get_priority_min(SCHED_FIFO);
+   highest_priority = ::sched_get_priority_max(SCHED_FIFO);
+   switch (highest_priority - lowest_priority) 
+   {
+     case 0:
+     case 1:
+       normal_priority = lowest_priority;
+       break;
+     default:
+       normal_priority = lowest_priority + 1;
+       break;
+   }
+   init_done = true;
+ }
+#endif
+}
+
+// ============================================================================
+// Thread::~Thread
+// ============================================================================
+Thread::~Thread (void)
+{
+  //- noop
+}
+
+// ============================================================================
+// Thread::start [detatched thread]
+// ============================================================================
+void Thread::start (void) 
+  throw (Tango::DevFailed)
+{
+  //- mark the thread as detached
+  this->m_detached = true;
+  //- then spawn it
+  this->spawn();
+}
+
+// ============================================================================
+// Thread::start_undetached [undetatched thread]
+// ============================================================================
+void Thread::start_undetached (void)
+  throw (Tango::DevFailed)
+{
+  //- mark the thread as undetached
+  this->m_detached = false;
+  //- then spawn it
+  this->spawn();
+}
+
+// ============================================================================
+// Thread::spawn (common to detatched & undetached threads)
+// ============================================================================
+void Thread::spawn (void) 
+  throw (Tango::DevFailed)
+{
+  //- enter critical section
+  AutoMutex<Mutex> guard(this->m_lock);
+
+  //- be sure the thread is not already running or terminated
+  if (this->m_state != bpm::Thread::STATE_NEW)
+	  return;
+
+  //- intialize thread attributes
+  pthread_attr_t thread_attrs;
+
+  ::pthread_attr_init(&thread_attrs);
+
+  //- set detach attribute
+  int ds = this->m_detached 
+         ? PTHREAD_CREATE_DETACHED 
+         : PTHREAD_CREATE_JOINABLE;
+  ::pthread_attr_setdetachstate(&thread_attrs, ds);
+
+  //- set thread priority
+#if defined(HAS_THREAD_PRIORITY)
+  struct sched_param sp;
+  sp.sched_priority = bpm_to_posix_priority(m_priority);
+  ::pthread_attr_setschedparam(&thread_attrs, &sp));
+#endif
+
+  //- spawn the thread
+  int result = 0;
+  result = ::pthread_create(&m_posix_thread, 
+                            &thread_attrs, 
+                            bpm_thread_common_entry_point, 
+                            static_cast<void*>(this));
+  ::pthread_attr_destroy(&thread_attrs);
+
+  //- check result
+  if (result)
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("system call <pthread_create> failed"),
+                                   _CPTC("Thread::spawn"));
+
+  //- mark the thread as running (before leaving the critical section)
+  this->m_state = bpm::Thread::STATE_RUNNING;
+}
+
+// ============================================================================
+// Thread::join
+// ============================================================================
+void Thread::join (Thread::IOArg * oarg_)
+  throw (Tango::DevFailed)
+{
+  {
+    //- enter critical section
+    AutoMutex<Mutex> guard(this->m_lock);
+
+    //- check thread state
+    if (   
+           (this->m_state != bpm::Thread::STATE_RUNNING) 
+        && 
+           (this->m_state != bpm::Thread::STATE_TERMINATED)
+       )
+      Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("can't join [thread never started or already terminated]"),
+                                     _CPTC("Thread::join"));
+  }
+
+  //- be sure the thread is not detached
+  if (this->m_detached)
+      Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("can't join with a detached thread"),
+                                     _CPTC("Thread::join"));
+
+  if (::pthread_join(m_posix_thread, 0))
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("system call <pthread_join> failed"),
+                                     _CPTC("Thread::join"));
+
+  //- return the "thread result"
+  if (oarg_)
+    *oarg_ = this->m_oarg;
+
+  //- commit suicide
+  delete this;
+}
+
+// ============================================================================
+// Thread::priority
+// ============================================================================
+void Thread::priority (Priority _p)
+  throw (Tango::DevFailed)
+{
+  //- enter critical section
+  AutoMutex<Mutex> guard(this->m_lock);
+  
+  //- check thread state
+  if (this->m_state != bpm::Thread::STATE_RUNNING)
+    return; //- throw exception 
+
+#if defined(HAS_THREAD_PRIORITY)
+    struct sched_param sp;
+    sp.sched_priority = this->bpm_to_posix_priority(_p);
+    if (::pthread_setschedparam(m_posix_thread, SCHED_OTHER, &sp))
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("system call <pthread_setschedparam> failed"),
+                                     _CPTC("Thread::priority"));
+#endif
+
+  //- store new priority
+  this->m_priority = _p;
+}
+
+// ============================================================================
+// Thread::bpm_to_posix_priority
+// ============================================================================
+int Thread::bpm_to_posix_priority (Priority _p)
+{
+#if defined(HAS_THREAD_PRIORITY)
+  switch (_p) 
+  {
+    case bpm::Thread::PRIORITY_LOW:
+	    return lowest_priority;
+      break;
+    case bpm::Thread::PRIORITY_HIGH:
+      return highest_priority;
+      break;
+    case bpm::Thread::PRIORITY_RT:
+      return highest_priority;
+      break;
+    default:
+	    return normal_priority;
+  }
+#else
+  switch (_p) 
+  {
+    default:
+			return 0;
+  } 
+#endif
+}
+
+
+// ============================================================================
+// ThreadingUtilities::self
+// ============================================================================
+ThreadUID ThreadingUtilities::self (void)
+{
+  return static_cast<bpm::ThreadUID>(::pthread_self());
+}
+
+// ============================================================================
+// ThreadingUtilities::sleep
+// ============================================================================
+void ThreadingUtilities::sleep (unsigned long _secs, unsigned long _nano_secs)
+{
+#if defined(HAS_NANO_SLEEP)
+
+  timespec ts2;
+  timespec ts1 = {_secs, _nano_secs};
+
+  while (::nanosleep(&ts1, &ts2)) 
+  {
+    if (errno == EINTR) 
+    {
+	    ts1.tv_sec  = ts2.tv_sec;
+	    ts1.tv_nsec = ts2.tv_nsec;
+	    continue;
+    }
+  }
+
+#else
+
+  if (_secs > 2000) 
+    while ((_secs = ::sleep(_secs))) ;
+  else 
+ 	  ::usleep(_secs * 1000000 + (_nano_secs / 1000));
+
+#endif
+}
+
+// ============================================================================
+// ThreadingUtilities::get_time
+// ============================================================================
+void ThreadingUtilities::get_time (unsigned long & abs_sec_,
+                                   unsigned long & abs_nano_sec_,
+                  		             unsigned long _rel_sec,
+                                   unsigned long _rel_nano_sec)
+{
+  timespec abs;
+
+  struct timeval tv;
+  ::gettimeofday(&tv, NULL); 
+
+  abs.tv_sec = tv.tv_sec;
+  abs.tv_nsec = tv.tv_usec * 1000;
+
+  abs.tv_sec += _rel_sec + abs.tv_nsec / NANOSECS_PER_SEC;
+  abs.tv_nsec += _rel_nano_sec;
+  abs.tv_nsec %= NANOSECS_PER_SEC;
+
+  abs_sec_ = abs.tv_sec;
+  abs_nano_sec_ = abs.tv_nsec;
+}
+
+// ============================================================================
+// ThreadingUtilities::get_time
+// ============================================================================
+void ThreadingUtilities::get_time (unsigned long delay_msecs, Timespec& abs_time)
+{
+  struct timeval now;
+  ::gettimeofday(&now, NULL); 
+  
+  //- std::cout << "delay_msecs........" << delay_msecs << std::endl;
+  
+  abs_time.tv_sec  = now.tv_sec + delay_msecs / 1000;
+  delay_msecs -=  delay_msecs / 1000 * 1000;
+  abs_time.tv_nsec = now.tv_usec * 1000;
+  abs_time.tv_nsec += delay_msecs * 1000000;
+  abs_time.tv_sec  += abs_time.tv_nsec / NANOSECS_PER_SEC;
+  abs_time.tv_nsec %= NANOSECS_PER_SEC;
+  
+  //- std::cout << "now.tv_sec........." << now.tv_sec << std::endl;
+  //- std::cout << "now.tv_nsec........" << now.tv_usec * 1000 << std::endl;
+  //- std::cout << "abs_time.tv_sec...." << abs_time.tv_sec << std::endl;
+  //- std::cout << "abs_time.tv_nsec..." << abs_time.tv_nsec << std::endl;
+  //- std::cout << "dt.sec............." << abs_time.tv_sec - now.tv_sec << std::endl;
+  //- std::cout << "dt.nsec............" << abs_time.tv_nsec - (now.tv_usec * 1000) << std::endl;
+}
+
+} // namespace bpm
diff --git a/src/PosixThreadingImpl.h b/src/PosixThreadingImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b2447ff5cf54524a88164498c828759f955eefc
--- /dev/null
+++ b/src/PosixThreadingImpl.h
@@ -0,0 +1,75 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _POSIX_THREADING_IMPL_
+#define _POSIX_THREADING_IMPL_
+
+//- no nano sleep!
+//- #define HAS_NANO_SLEEP
+
+//- no thread priority!
+//- #define HAS_THREAD_PRIORITY
+
+// ----------------------------------------------------------------------------
+// MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX
+// ----------------------------------------------------------------------------
+#define __MUTEX_IMPLEMENTATION \
+  pthread_mutex_t m_posix_mux; \
+  friend class Condition;
+
+// ----------------------------------------------------------------------------
+// CONDITION - CONDITION - CONDITION - CONDITION - CONDITION - CONDITION
+// ----------------------------------------------------------------------------
+#define __CONDITION_IMPLEMENTATION \
+  pthread_cond_t m_posix_cond;
+
+// ----------------------------------------------------------------------------
+// SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE
+// ----------------------------------------------------------------------------
+#define __SEMAPHORE_IMPLEMENTATION \
+  Mutex m_mux; \
+  Condition m_cond; \
+  int m_value;
+
+// ----------------------------------------------------------------------------
+// THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD
+// ----------------------------------------------------------------------------
+//- common thread entry point (non-OO OS interface to interface)
+#define THREAD_COMMON_ENTRY_POINT \
+  void * bpm_thread_common_entry_point (void *)
+
+extern "C" THREAD_COMMON_ENTRY_POINT;
+
+#define __THREAD_IMPLEMENTATION \
+  pthread_t m_posix_thread; \
+  void spawn (void) throw (Tango::DevFailed); \
+  static int bpm_to_posix_priority (Priority); \
+  friend THREAD_COMMON_ENTRY_POINT;
+
+#endif //- _POSIX_THREADING_IMPL_
diff --git a/src/PosixThreadingImpl.i b/src/PosixThreadingImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..3a46ad6c29d7eb9c44d8240ca4d8c495fc84f228
--- /dev/null
+++ b/src/PosixThreadingImpl.i
@@ -0,0 +1,169 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ****************************************************************************
+// YAT DUMMY_MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// DummyMutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::lock (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::acquire (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::unlock (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::release
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::release (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState DummyMutex::try_lock (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState DummyMutex::try_acquire (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ****************************************************************************
+// YAT MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Mutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::lock (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::acquire (void)
+{
+  this->lock();
+}
+// ----------------------------------------------------------------------------
+// Mutex::try_acquire
+// ----------------------------------------------------------------------------
+MutexState Mutex::try_acquire (void)
+{
+  return this->try_lock();
+}
+// ----------------------------------------------------------------------------
+// Mutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::unlock (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::release (void)
+{
+  this->unlock();
+}
+
+// ****************************************************************************
+// YAT THREAD IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Thread::priority
+// ----------------------------------------------------------------------------
+INLINE_IMPL Priority Thread::priority (void) const
+{
+  //- enter critical section
+  bpm::SmartMutex guard(this->m_lock);
+
+  return this->m_priority;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL State Thread::state (void) const
+{
+  //- enter critical section
+  bpm::SmartMutex guard(this->m_lock);
+
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::yield
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::yield (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Thread::sleep
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::sleep (unsigned long _tmo_msecs)
+{
+  ThreadingUtilities::sleep(0, 1000000 * _tmo_msecs);
+}
+// ----------------------------------------------------------------------------
+// Thread::self
+// ----------------------------------------------------------------------------
+INLINE_IMPL ThreadUID Thread::self (void) const
+{
+  return this->m_uid;
+}
+// ----------------------------------------------------------------------------
+// Thread::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::Mutex & lock (void) const
+{
+  return this->m_lock;
+}
+
+} // namespace bpm
diff --git a/src/README b/src/README
new file mode 100644
index 0000000000000000000000000000000000000000..f13be600868117a42b6e2cb3decf31c8df4cab07
--- /dev/null
+++ b/src/README
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+
+I – COMPILING 
+=============
+
+
+
+
+
+
+  
+  
+      
+
+
+       
+ 
+ 
+
+  
+
+
diff --git a/src/Semaphore.h b/src/Semaphore.h
new file mode 100644
index 0000000000000000000000000000000000000000..32975eed7aca229d90e52922a33183850e103918
--- /dev/null
+++ b/src/Semaphore.h
@@ -0,0 +1,142 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_SEMAPHORE_H_
+#define _BPM_SEMAPHORE_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+
+// ============================================================================
+// Implementation-specific header file.
+// ============================================================================
+#if ! defined(__SEMAPHORE_IMPLEMENTATION)
+# error "implementation header file incomplete [no semaphore implementation]"
+#endif
+
+namespace bpm {
+
+// ============================================================================
+//! <BPM_SEMAPHORE>::try_wait may return one of the following SemaphoreState
+// ============================================================================
+typedef enum
+{
+  //! semaphore is currently "decrementable"
+  SEMAPHORE_DEC,
+  //! no resource available (semaphore value is 0)
+  SEMAPHORE_NO_RSC,
+} SemaphoreState;
+
+// ============================================================================
+//! The BPM Semaphore class
+// ============================================================================
+class Semaphore
+{
+  //! This is the BPM Semaphore class.
+  //!
+  //! This class is not supposed to be derived.
+
+public:
+  //! Constructor (may throw an Exception)
+  Semaphore (unsigned int initial = 1);
+
+  //! Destructor.
+  ~Semaphore (void);
+
+  //! If semaphore value is > 0 then decrement it and carry on. 
+  //! If it's already 0 then block untill the semaphore is either "signaled" 
+  //! or "broascasted" (see post, signal and broadcast members below).
+  void wait (void);
+
+  //! If semaphore value is > 0 then decrements it and returns true. Returns 
+  //! "false" in case the specified timeout expired before the semaphore
+  //! has been "signaled" or "broascasted" by another thread.
+  bool timed_wait (unsigned long tmo_msecs);
+
+  //! If the current semaphore value is > 0, then crements it and returns 
+  //! SEMAPHORE_DEC. In case the semaphore has reached its maximum value,
+  //! this method does not block and "immediately" returns SEMAPHORE_NO_RSC.
+  SemaphoreState try_wait (void);
+
+  //! If any threads are blocked in wait(), wake one of them up. 
+  //! Otherwise increments the value of the semaphore. 
+  void post (void);
+
+private:
+  //! Not implemented private member
+  Semaphore (const Semaphore&);
+  //! Not implemented private member
+  Semaphore & operator= (const Semaphore&);
+  
+  //- platform specific implementation
+  __SEMAPHORE_IMPLEMENTATION;
+};
+
+// ============================================================================
+//! The BPM "auto semaphore" class
+// ============================================================================
+class AutoSemaphore
+{
+  //! An "auto semaphore" providing an auto wait/post mechanism.
+
+public:
+  //! Constructor (wait on the associated Semaphore)
+  AutoSemaphore (Semaphore & _sem)
+    : m_sem (_sem)
+  {
+    m_sem.wait();
+  }
+
+  //! Destructor (post the associated Semaphore)
+  ~AutoSemaphore (void)
+  {
+    m_sem.post();
+  }
+
+private:
+  //! The associated Mutex
+  Semaphore & m_sem;
+
+  //! Not implemented private member
+  AutoSemaphore (const AutoSemaphore&);
+  //! Not implemented private member
+  AutoSemaphore & operator= (const AutoSemaphore&);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/impl/PosixSemaphoreImpl.i"
+#endif
+
+#endif //- _BPM_SEMAPHORE_H_
diff --git a/src/SharedObject.cpp b/src/SharedObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ebee01cc55c13c9a460e573e3322667f3dcd645
--- /dev/null
+++ b/src/SharedObject.cpp
@@ -0,0 +1,101 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/SharedObject.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/SharedObject.i"
+#endif
+
+namespace bpm
+{
+// ============================================================================
+// SharedObject::SharedObject
+// ============================================================================
+SharedObject::SharedObject (void) : reference_count_ (1)
+{
+  //- noop
+}
+
+// ============================================================================
+// SharedObject::~SharedObject
+// ============================================================================
+SharedObject::~SharedObject (void)
+{
+  //- check reference_count_ value
+  DEBUG_ASSERT(this->reference_count_ == 0);
+}
+
+// ============================================================================
+// SharedObject::duplicate
+// ============================================================================
+SharedObject *SharedObject::duplicate (void)
+{
+  AutoMutex<Mutex> guard (this->lock_);
+
+  this->reference_count_++;
+
+  return this;
+}
+
+// ============================================================================
+// SharedObject::release
+// ============================================================================
+void SharedObject::release (void)
+{
+  //- the try/catch block is a trick for embedded version...
+  try
+  {
+    if (this->release_i () == 0)
+      delete this;
+  }
+  catch (...)
+  {
+    //- ignore exception
+  }
+}
+
+// ============================================================================
+// SharedObject::release_i
+// ============================================================================
+SharedObject *SharedObject::release_i (void)
+{
+  AutoMutex<Mutex> guard (this->lock_);
+
+  DEBUG_ASSERT(this->reference_count_ > 0);
+
+  this->reference_count_--;
+
+  return (this->reference_count_ == 0) ? 0 : this;
+}
+
+} //- namespace bpm
diff --git a/src/SharedObject.h b/src/SharedObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..013366a403611e2aa754c405bb3976ba2a098fbf
--- /dev/null
+++ b/src/SharedObject.h
@@ -0,0 +1,100 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _SHARED_OBJECT_H_
+#define _SHARED_OBJECT_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/Mutex.h"
+
+namespace bpm
+{
+
+// ============================================================================
+//! A reference counted object abstraction.
+// ============================================================================
+//!
+//! Base class for any reference counted object (i.e. shared) object.
+//!
+// ============================================================================
+class SharedObject
+{
+public:
+
+  SharedObject (void);
+  // Constructor.
+
+  virtual ~SharedObject (void);
+  // Destructor.
+
+  SharedObject *duplicate (void);
+  // Return a "shallow" copy. Increment the reference count by 1
+  // to avoid deep copies.
+
+  void release (void);
+  // Decrease the shared reference count by 1.  If the reference count
+  // equals 0, then delete <this> and return 0. Behavior is undefined
+  // if reference count < 0.
+
+  int reference_count (void) const;
+  // Returns the current reference count.
+
+  void lock (void);
+  // Gets exclusive access to the data.
+
+  void unlock (void);
+  // Release exclusive access to the data.
+
+protected:
+  // a mutex to protect the data against race conditions
+  bpm::Mutex lock_;
+
+private:
+  // internal release implementation
+  SharedObject * release_i (void);
+
+  //- reference count for (used to avoid deep copies)
+  int reference_count_;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  SharedObject & operator= (const SharedObject &);
+  SharedObject (const SharedObject &);
+};
+
+}  // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/SharedObject.i"
+#endif 
+
+#endif // _SHARED_OBJECT_H_
diff --git a/src/StringTokenizer.cpp b/src/StringTokenizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa4fa7ab2c5f12338740c203b6b1ac4c9bd38823
--- /dev/null
+++ b/src/StringTokenizer.cpp
@@ -0,0 +1,255 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#include "CommonHeader.h"
+#include "StringTokenizer.h"
+
+namespace bpm {
+
+StringTokenizer::StringTokenizer (string str, string delim)
+{
+
+  if ((str.length () == 0) || (delim.length () == 0))
+    return;
+
+  tokenStr = str;
+  this->delim = delim;
+
+  /*
+     Remove sequential delimiter
+   */
+  unsigned int currentPos = 0;
+
+  while (true)
+  {
+
+    if ((currentPos = tokenStr.find (delim, currentPos)) != string::npos)
+    {
+
+      currentPos += delim.length ();
+      while (tokenStr.find (delim, currentPos) == currentPos)
+      {
+
+        tokenStr.erase (currentPos, delim.length ());
+
+      }
+
+    }
+    else
+      break;
+  }
+
+
+  /*
+     Trim leading delimiter
+   */
+  if (tokenStr.find (delim, 0) == 0)
+  {
+    tokenStr.erase (0, delim.length ());
+  }
+
+  /*
+     Trim ending delimiter
+   */
+  currentPos = 0;
+  if ((currentPos = tokenStr.rfind (delim)) != string::npos)
+  {
+    if (currentPos != (tokenStr.length () - delim.length ()))
+      return;
+    tokenStr.erase (tokenStr.length () - delim.length (), delim.length ());
+  }
+
+};
+
+int
+StringTokenizer::countTokens ()
+{
+
+  unsigned int prevPos = 0;
+  int numTokens = 0;
+
+
+  if (tokenStr.length () > 0)
+  {
+
+    numTokens = 0;
+
+    unsigned int currentPos = 0;
+    while (true)
+    {
+
+      if ((currentPos = tokenStr.find (delim, currentPos)) != string::npos)
+      {
+
+        numTokens++;
+        prevPos = currentPos;
+        currentPos += delim.length ();
+
+      }
+      else
+        break;
+
+    }
+
+    return ++numTokens;
+
+  }
+  else
+  {
+
+    return 0;
+
+  }
+
+};
+
+
+bool
+StringTokenizer::hasMoreTokens ()
+{
+
+  return (tokenStr.length () > 0);
+
+};
+
+
+string
+StringTokenizer::nextToken ()
+{
+
+  if (tokenStr.length () == 0)
+    return "";
+
+  string tStr = "";
+  unsigned int pos = tokenStr.find (delim, 0);
+
+  if (pos != string::npos)
+  {
+
+    tStr = tokenStr.substr (0, pos);
+    tokenStr = tokenStr.substr (pos + delim.length (), tokenStr.length () - pos);
+
+  }
+  else
+  {
+
+    tStr = tokenStr.substr (0, tokenStr.length ());
+    tokenStr = "";
+
+  }
+
+  return tStr;
+
+
+};
+
+
+int
+StringTokenizer::nextIntToken ()
+{
+
+  return atoi (nextToken ().c_str ());
+
+};
+
+long
+StringTokenizer::nextLongToken ()
+{
+
+  return atol (nextToken ().c_str ());
+
+};
+
+bpm::FPDataType
+StringTokenizer::nextFPToken ()
+{
+
+  return static_cast< bpm::FPDataType >(atof (nextToken ().c_str ()));
+
+};
+
+
+string
+StringTokenizer::nextToken (string delimiter)
+{
+
+  if (tokenStr.length () == 0)
+    return "";
+
+  string tStr = "";
+  unsigned int pos = tokenStr.find (delimiter, 0);
+
+  if (pos != string::npos)
+  {
+
+    tStr = tokenStr.substr (0, pos);
+    tokenStr = tokenStr.substr (pos + delimiter.length (), tokenStr.length () - pos);
+
+  }
+  else
+  {
+
+    tStr = tokenStr.substr (0, tokenStr.length ());
+    tokenStr = "";
+
+  }
+
+  return tStr;
+
+};
+
+
+string
+StringTokenizer::remainingString ()
+{
+
+  return tokenStr;
+
+};
+
+
+string
+StringTokenizer::filterNextToken (string filterStr)
+{
+
+  string str = nextToken ();
+  unsigned int currentPos = 0;
+
+  while ((currentPos = str.find (filterStr, currentPos)) != string::npos)
+  {
+
+    str.erase (currentPos, filterStr.length ());
+  }
+
+
+  return str;
+
+};
+
+} // namespace bpm
diff --git a/src/StringTokenizer.h b/src/StringTokenizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1997bd2310c6cd7ea7a1467b31d20906d9c8fa7f
--- /dev/null
+++ b/src/StringTokenizer.h
@@ -0,0 +1,91 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+/*
+ ***********************************************************************
+ * Class: StringTokenizer                                              *
+ * By Arash Partow - 2000                                              *
+ * URL: http://www.partow.net/programming/stringtokenizer/index.html   *
+ *                                                                     *
+ * Copyright Notice:                                                   *
+ * Free use of this library is permitted under the guidelines and      *
+ * in accordance with the most current version of the Common Public    *
+ * License.                                                            *
+ * http://www.opensource.org/licenses/cpl.php                          *
+ *                                                                     *
+ ***********************************************************************
+*/
+
+
+
+#ifndef INCLUDE_STRINGTOKENIZER_H
+#define INCLUDE_STRINGTOKENIZER_H
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <string>
+
+
+
+using namespace std;
+
+namespace bpm {
+
+class StringTokenizer
+{
+
+public:
+
+  StringTokenizer (string str, string delim);
+  ~StringTokenizer ()
+  {}
+  ;
+
+  int countTokens ();
+  bool hasMoreTokens ();
+  string nextToken ();
+  int nextIntToken ();
+  long nextLongToken ();
+  bpm::FPDataType nextFPToken ();
+  string nextToken (string delim);
+  string remainingString ();
+  string filterNextToken (string filterStr);
+
+private:
+
+  string tokenStr;
+  string delim;
+
+};
+
+} // namespace
+
+#endif
diff --git a/src/TangoClassID.txt b/src/TangoClassID.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b92dd683c2319668974f8da0f97e137d3bc56126
--- /dev/null
+++ b/src/TangoClassID.txt
@@ -0,0 +1,11 @@
+/**
+ * Device Class Identification:
+ * 
+ * Class Name   :	Libera
+ * Contact      :	nl@soleil.fr
+ * Class Family :	BeamDiag
+ * Platform     :	Unix Like
+ * Bus          :	Ethernet
+ * Manufacturer :	I-Tech
+ * Reference    :	Libera Electron & Brillance
+ */
diff --git a/src/Task.cpp b/src/Task.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4d81fcc59b272e8b0bb24ecf177cbe0c2010545
--- /dev/null
+++ b/src/Task.cpp
@@ -0,0 +1,449 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr 
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/Task.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/Task.i"
+#endif 
+
+namespace bpm
+{
+
+// ======================================================================
+// Task::Config::Config
+// ======================================================================
+ Task::Config::Config ()
+		: enable_timeout_msg (false),
+      timeout_msg_period_ms (0),
+      enable_periodic_msg (false),
+      periodic_msg_period_ms (0),
+      lock_msg_handling (false),
+      lo_wm (kDEFAULT_LO_WATER_MARK),
+      hi_wm (kDEFAULT_HI_WATER_MARK),
+      throw_on_post_tmo (false),
+      msg_handler (0),
+      user_data (0),
+      host_device (0)
+{
+  /* noop ctor */
+}
+
+// ======================================================================
+// Task::Config::Config
+// ======================================================================
+ Task::Config::Config (Tango::DeviceImpl * _hd,
+                       MessageHandler _msg_handler,
+		                   Thread::IOArg _user_data,
+                       bool   _enable_periodic_msg,
+                       size_t _periodic_msg_period_ms,
+		                   bool   _enable_timeout_msg,
+                       size_t _timeout_msg_period_ms,
+                       bool   _lock_msg_handling,
+                       size_t _lo_wm,
+                       size_t _hi_wm,
+                       bool   _throw_on_post_tmo)
+		: enable_timeout_msg (_enable_timeout_msg),
+      timeout_msg_period_ms (_timeout_msg_period_ms),
+      enable_periodic_msg (_enable_periodic_msg),
+      periodic_msg_period_ms (_periodic_msg_period_ms),
+      lock_msg_handling (_lock_msg_handling),
+      lo_wm (_lo_wm),
+      hi_wm (_hi_wm),
+      throw_on_post_tmo (_throw_on_post_tmo),
+      msg_handler (_msg_handler),
+      user_data (_user_data),
+      host_device (_hd)
+{
+  /* noop ctor */
+}
+
+// ======================================================================
+// Task::Task
+// ======================================================================
+Task::Task (const Task::Config& _cfg)
+  : Thread (_cfg.host_device),
+    msg_q_ (_cfg.lo_wm, _cfg.hi_wm, _cfg.throw_on_post_tmo),
+    timeout_msg_period_ms_ (_cfg.timeout_msg_period_ms),
+    periodic_msg_period_ms_ (_cfg.periodic_msg_period_ms),
+    user_data_ (_cfg.user_data),
+    lock_msg_handling_ (_cfg.lock_msg_handling),
+    henv_ (0),
+    hcon_ (0),
+    msg_handler_ (_cfg.msg_handler),
+    connected_ (false)  
+{
+  this->msg_q_.enable_timeout_msg(_cfg.enable_timeout_msg);
+  this->msg_q_.enable_periodic_msg(_cfg.periodic_msg_period_ms);
+}
+
+// ======================================================================
+// Task::~Task
+// ======================================================================
+Task::~Task (void)
+{
+  //- noop
+}
+  
+// ============================================================================
+// Task::go
+// ============================================================================
+void Task::go (size_t _tmo_ms) 
+  throw (Tango::DevFailed)
+{
+  this->start_undetached();
+
+  Message * msg = 0;
+  try
+  {
+    msg = bpm::Message::allocate(TASK_INIT, INIT_MSG_PRIORITY, true);
+  }
+  catch (Tango::DevFailed & ex)
+  {
+    Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                    _CPTC("Message allocation failed"),
+                                    _CPTC("Task::go"));
+  }
+
+  this->wait_msg_handled (msg, _tmo_ms);
+}
+
+// ============================================================================
+// Task::go
+// ============================================================================
+void Task::go (Message * _msg, size_t _tmo_ms) 
+  throw (Tango::DevFailed)
+{
+  this->start_undetached();
+
+  if ( 
+         (_msg == 0)
+      || 
+         (_msg->type() != TASK_INIT)
+      ||
+         (_msg->waitable() == false)
+     )
+     Tango::Except::throw_exception (_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("invalid INIT message [null, wrong type or not waitable]"),
+                                     _CPTC("Task::go"));
+                                      
+  this->wait_msg_handled (_msg, _tmo_ms);
+}
+
+// ============================================================================
+// Task::run_undetached
+// ============================================================================
+void * Task::run_undetached (void *)
+{
+	//- init flag - set to true when TASK_INIT received
+	bool received_init_msg = false;
+
+	//- exit flag - set to true when TASK_EXIT received
+	bool received_exit_msg = false;
+
+	size_t msg_type;
+	Message * msg = 0;
+
+  //- actual tmo on msg waiting
+  size_t tmo = this->actual_timeout(); 
+
+	//- trick: avoid handling TIMEOUT messages before INIT is itself handled
+	//- may be the case for very short Task timeout
+	do
+	{
+		//- release any previously obtained msg
+		if (msg) msg->release();
+
+    //- get/wait next message from the msgQ
+		msg = this->msg_q_.next_message (tmo);
+	}
+	while (! msg || msg->type() != TASK_INIT);
+
+  //- TASK_INIT received
+  received_init_msg = true;
+    
+	//- enter thread's main loop 
+	while (! received_exit_msg)
+	{
+    //- actual tmo on msg waiting
+    tmo = this->actual_timeout();
+
+		//- get/wait next message from the msgQ
+		if (! msg)
+		{ 
+			do
+			{
+        //- get next message
+				msg = this->msg_q_.next_message (tmo);
+        //- do not handle TASK_INIT twice
+        if (msg && msg->type() == TASK_INIT && received_init_msg)
+        {
+          msg->release();
+          msg = 0;
+        }
+      }
+			while (! msg);
+		}
+
+		//- set msg user data
+		msg->user_data(this->user_data_);
+
+		//- we may need msg type after msg release
+		msg_type = msg->type();
+	        
+    //- got a valid message from message Q
+		try
+    {
+      //      std::cout << "Task::handling msg::"
+      //                << std::hex
+      //			  				<< long(msg)
+      //			  				<< std::dec
+      //			  				<< "::"
+      //			  				<< msg->to_string()
+      //			  				<< std::endl;
+			//- call message handler
+      if (this->lock_msg_handling_)
+		  { 
+        //- enter critical section 
+			  MutexLock guard (this->m_lock);
+        (this->msg_handler_)(*msg);
+			}
+      else
+      {
+        this->msg_handler_(*msg);
+      }
+    }
+		catch (const Tango::DevFailed& e)
+		{
+			//- store exception into the message
+      msg->set_error(e);
+		}
+		catch (...)
+		{
+      Tango::DevErrorList errors;
+		  errors.length(1);
+      errors[0].severity = Tango::ERR;
+      errors[0].reason = CORBA::string_dup("UNKNOWN_ERROR");
+      errors[0].origin = CORBA::string_dup("unknown error caught while handling msg");
+      errors[0].desc = CORBA::string_dup("Task::run_undetached");
+      msg->set_error(Tango::DevFailed(errors));
+		}
+    //	  std::cout << "Task::run_undetached::msg [" 
+    //    	        << std::hex 
+    //    	        << (void*)msg 
+    //    	        << std::dec 
+    //    	        << "] handled - notifying waiters"
+    //    	        << std::endl;
+    //- mark message as "processed" (this will signal waiters if any)
+    msg->processed();
+		//- release our msg ref 
+		msg->release();
+    //- abort requested?
+    if (msg_type == TASK_EXIT)
+    {
+	    //- close the msgQ
+	    this->msg_q_.close();
+	    //- mark TASK_EXIT as received (exit thread's main loop)
+	    received_exit_msg = true;
+    }
+		//- reset msg in order to get next msg from msgQ
+		msg = 0;
+  } //- thread's while loop
+
+	return 0;
+}
+
+// ======================================================================
+// Task::exit
+// ======================================================================
+void Task::exit (void)
+  throw (Tango::DevFailed)
+{
+  //- we may have to implicitly delete the thread
+  bool delete_self = false;
+
+  //- enter critical section
+  this->m_lock.lock();
+
+  //- get underlying thread state
+  Thread::State ts = this->state_i();
+
+	//- if the thread is running, then ask it to exit
+  if (ts == bpm::Thread::STATE_RUNNING)
+	{
+    bpm::Message * msg = 0;
+    try
+    {
+      msg = new Message(bpm::TASK_EXIT, EXIT_MSG_PRIORITY, true);
+    }
+    catch (Tango::DevFailed &ex)
+    {
+      this->m_lock.unlock();
+      Tango::Except::re_throw_exception (ex,
+                                         _CPTC("SOFTWARE_ERROR"),
+                                         _CPTC("Could not stop task [bpm::Message allocation failed]"),
+                                         _CPTC("Task::exit"));
+	  }
+    catch (...)
+    {
+      this->m_lock.unlock();
+      Tango::Except::throw_exception (_CPTC("UNKNOWN_ERROR"),
+                                      _CPTC("Could not stop task [bpm::Message allocation failed]"),
+                                      _CPTC("Task::exit"));
+	  }
+    //- unlock the thread lock (avoid deadlock during message handling)
+    this->m_lock.unlock();
+    try
+    {
+		  //- ... then wait for TASK_EXIT msg to be handled
+		  //- TODO: change kINFINITE_WAIT to a more flexible TIMEOUT
+		  // std::cout << "Task::exit - waiting for the TASK_EXIT msg to be handled" << std::endl;
+		  this->wait_msg_handled (msg, kINFINITE_WAIT);
+    }
+    catch (...)
+    {
+      //- ignore any error
+    }
+		//- wait for the thread to actually quit
+		try
+    {
+      Thread::IOArg dummy = 0;
+			// std::cout << "Task::exit - about to join with the underlying thread" << std::endl;
+		  this->join (&dummy);
+    }
+		catch (...)
+    {
+		 //- ignore any error
+    }
+  }
+  else if (ts == bpm::Thread::STATE_NEW) 
+  {
+    //- delete the thread (instanciated but never been started)
+	  // std::cout << "Task::exit - about to delete the thread [has never been started]" << std::endl;
+		delete_self = true;
+    //- leave critical section
+    this->m_lock.unlock();
+  }
+	else
+  {
+    //- nothing to do...
+	  // std::cout << "Task::exit - do nothing" << std::endl;
+    //- leave critical section
+    this->m_lock.unlock();
+  }
+
+  //- delete (if required)
+  if (delete_self)
+  {
+    // std::cout << "Task::exit - deleting <this> Task instance" << std::endl;
+    delete this;
+  }
+}
+
+// ======================================================================
+// Task::wait_msg_handled
+// ======================================================================
+void Task::wait_msg_handled (Message * _msg, size_t _tmo_ms)
+		 throw (Tango::DevFailed)
+{
+	//- check input
+	if (! _msg || ! _msg->waitable())	
+  {
+    Tango::Except::throw_exception (_CPTC("INVALID_ARGUMENT"),
+                                    _CPTC("invalid message [either null or not waitable]"),
+                                    _CPTC("Task::wait_msg_handled"));
+	}
+
+	try
+	{
+		//- post a shallow copy of the msg 
+		this->msg_q_.post(_msg->duplicate());
+	}
+	catch (...)
+	{
+		_msg->release();
+    Tango::Except::throw_exception (_CPTC("INTERNAL_ERROR"),
+                                    _CPTC("message could not be posted"),
+                                    _CPTC("Task::wait_msg_handled"));
+	}
+	
+  //	std::cout << "Task::wait_msg_handled::waiting for msg [" 
+  //	        << std::hex 
+  //	        << (void*)_msg 
+  //	        << std::dec 
+  //	        << "] to be handled"
+  //	        << std::endl;
+	
+	//- wait for the msg to be handled or tmo expiration
+	if (_msg->wait_processed(_tmo_ms))
+	{
+    //	  std::cout << "Task::wait_msg_handled::msg [" 
+    //	          << std::hex 
+    //	          << (void*)_msg 
+    //	          << std::dec 
+    //	          << "] handled [gave error::" 
+    //	          << (_msg->has_error() ? "yes" : "no")
+    //	          << "]"
+    //	          << std::endl;
+    Tango::DevFailed msg_exception;
+    bool msg_gave_error = _msg->has_error();
+    //- to store error localy before releasing msg
+	  if (msg_gave_error)
+      msg_exception = _msg->get_error();
+	  //- release msg
+		_msg->release();
+		//- throw an exception if msg gave error
+		if (msg_gave_error)
+	    throw msg_exception;
+		//- msg did not gave error, just return
+		return;
+	}
+
+	//- too bad, timeout expired...
+  //  std::cout << "Task::wait_msg_handled::timeout expired while waiting for msg [" 
+  //	        << std::hex 
+  //	        << (void*)_msg 
+  //	        << std::dec 
+  //	        << "] to be handled"
+  //	        << std::endl;
+	          
+	//- release msg
+	_msg->release();
+
+	//- throw timeout exception
+  Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"),
+                                  _CPTC ("timeout expired while waiting for message to be handled"),
+                                  _CPTC ("Task::wait_msg_handled"));
+}
+
+} // namespace
diff --git a/src/Task.h b/src/Task.h
new file mode 100644
index 0000000000000000000000000000000000000000..4eafde9992efbe59f13a235fb90574c38ce8c81e
--- /dev/null
+++ b/src/Task.h
@@ -0,0 +1,205 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_TASK_H_
+#define _BPM_TASK_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Thread.h"
+#include "threading/MessageQ.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_TASK_TMO_MSECS         5000
+#define kDEFAULT_THD_PERIODIC_TMO_MSECS 1000
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// class: Task
+// ============================================================================
+class Task : public bpm::Thread
+{
+  friend class BPM;
+  
+public:
+
+  //-define what a msg handler is
+  typedef void (*MessageHandler) (const bpm::Message&);
+  
+  //! yat::Task configuration class
+	class Config
+	{
+	public:
+    //- enable TIMEOUT messages
+		bool enable_timeout_msg;
+		//- timeout msg period in msec
+		size_t timeout_msg_period_ms;
+    //- enable PERIODIC messages
+		bool enable_periodic_msg;
+		//- periodic msg period in msec
+		size_t periodic_msg_period_ms;
+		//- should we process msg under critical section?
+		bool lock_msg_handling;
+    //- msgQ low water mark
+    size_t lo_wm;
+    //- msgQ high water mark
+    size_t hi_wm;
+    //- throw exception on post message timeout
+    bool throw_on_post_tmo;
+    //- msg handler
+    MessageHandler msg_handler;
+		//- user data (passed back in all msg)
+    Thread::IOArg user_data;
+    //- host TANGO device
+    Tango::DeviceImpl * host_device;
+    
+    //- default ctor
+		Config ();
+		
+    //- ctor
+		Config (Tango::DeviceImpl * hd, 
+		        MessageHandler msg_handler,
+		        Thread::IOArg user_data = 0,
+            bool   enable_periodic_msg = false,
+            size_t periodic_msg_period_ms = 0,
+		        bool   enable_timeout_msg = false,
+            size_t timeout_msg_period_ms = 0,
+            bool   lock_msg_handling = false,
+            size_t lo_wm = kDEFAULT_LO_WATER_MARK,
+            size_t hi_wm = kDEFAULT_HI_WATER_MARK,
+            bool   throw_on_post_tmo = true);
+	};
+
+  //- ctor
+	Task (const Config& cfg);
+
+	//- dtor
+	virtual ~Task (void);
+
+	//- starts the task
+  void go (size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+    throw (Tango::DevFailed);
+
+ 	//- starts the task 
+  //- an exception is thrown otherwise in case the specified message:
+  //-   * is not of type TASK_INIT
+  //-   * is not "waitable"
+  void go (Message * msg, size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+    throw (Tango::DevFailed);
+
+	//! Abort the task (join with the underlying thread before returning).
+  //! Provides an implementation to the Thread::exit pure virtual method.
+  virtual void exit (void)
+    throw (Tango::DevFailed);
+
+  //- posts a message to the task
+	void post (Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO)
+		throw (Tango::DevFailed);
+
+  //- post a CSPI event to the task
+  void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO)
+    throw (Tango::DevFailed);
+    
+	//- wait for a msg to be handled
+	void wait_msg_handled (Message * msg, size_t tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+		throw (Tango::DevFailed);
+
+	//- timeout msg period mutator
+	void set_timeout_msg_period (size_t p_msecs);
+	
+	//- periodic msg period accessor
+	size_t get_timeout_msg_period (void) const;
+	
+	//- enable/disable timeout messages
+	void enable_timeout_msg (bool enable);
+
+	//- returns timeout messages handling status
+	bool timeout_msg_enabled (void) const;
+
+	//- periodic msg period mutator
+	void set_periodic_msg_period (size_t p_msecs);
+	
+	//- periodic msg period accessor
+	size_t get_periodic_msg_period (void) const;
+
+  //- enable/disable periodic messages
+	void enable_periodic_msg (bool enable);
+
+	//- returns period messages handling status
+	bool periodic_msg_enabled (void) const;
+
+protected:
+	//- run_undetached
+  virtual Thread::IOArg run_undetached (Thread::IOArg);
+
+private:
+	//- actual_timeout
+  size_t actual_timeout (void) const;
+
+	//- the associated messageQ
+	MessageQ msg_q_;
+
+	//- timeout msg period
+	size_t timeout_msg_period_ms_;
+
+	//- periodic msg period 
+  size_t periodic_msg_period_ms_;
+
+	//- user data 
+	Thread::IOArg user_data_;
+
+  //- should we process msg under critical section?
+  bool lock_msg_handling_;
+
+  //- the CSPI env. handle
+  CSPIHENV henv_;
+
+  //- the CSPI con. handle
+  CSPIHCON hcon_;
+  
+  //- the message handler entry point
+  MessageHandler msg_handler_;
+  
+  //- connection flag: true if connected to the Libera, false ortherwise 
+  bool connected_;
+};
+
+} // namespace 
+
+#if defined (__INLINE_IMPL__)
+# include <threading/Task.i>
+#endif
+
+#endif // _BPM_TASK_H_
diff --git a/src/Thread.h b/src/Thread.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d9287c627cec0ea62ca1daecac774d6104c12c9
--- /dev/null
+++ b/src/Thread.h
@@ -0,0 +1,207 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_THREAD_H_
+#define _BPM_THREAD_H_
+
+// ----------------------------------------------------------------------------
+// DEPENDENCIES
+// ----------------------------------------------------------------------------
+#include "threading/Mutex.h"
+
+// ----------------------------------------------------------------------------
+// Implementation-specific header file.
+// ----------------------------------------------------------------------------
+#if ! defined(__THREAD_IMPLEMENTATION)
+# error "implementation header file incomplete [no thread implementation]"
+#endif
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+//! The bpm Thread abstract class
+// ----------------------------------------------------------------------------
+class Thread : public Tango::LogAdapter
+{
+  //! This abstract class can't be used as this and must be derived.
+  //! Provides both "detached" and "undetached" (i.e. joinable) behaviour.
+
+public:
+  //! A dedicated type for thread entry point argument (user specified data).
+  typedef void * IOArg;
+
+  //! The possible thread priorities (default is NORMAL).
+  //! Be aware that setting the thread priority to HIGH or RT may 
+  //! prevent other threads from running (CPU starvation).
+  enum Priority
+  {
+	  PRIORITY_LOW,
+	  PRIORITY_NORMAL,
+	  PRIORITY_HIGH,
+    PRIORITY_RT
+  };
+
+  //! The possible thread states
+  enum State
+  {
+  	//! Thread object exists but thread hasn't started yet.
+  	//! In this state, the thread UID (identifier) is undefined.
+	  STATE_NEW,
+    //! Thread is running.
+	  STATE_RUNNING,
+    //! Thread has terminated but storage has not been reclaimed (i.e. waiting to be joined).
+    STATE_TERMINATED
+  };
+
+	//! Returns the the thread unique indentifier.
+	//! In case the thread is not yet running (THREAD_STATE_NEW), self will returns
+	//! YAT_INVALID_THREAD_UID (since the thread UID is not defined in this state).
+  ThreadUID self (void) const;
+
+	//! Set the priority of the thread.
+	//! In case the thread is running, the priority is immediately applied.
+	void priority (Priority p)
+    throw (Tango::DevFailed);
+
+	//! Returns the current priority of the thread.
+  Thread::Priority priority (void);
+
+ 	//! Returns the current state of the thread.
+  //! \remarks Locks the associated Mutex (\c m_lock)
+  Thread::State state (void);
+
+ 	//! This pure virtual member _must_ cause the "run" (for detached threads)
+  //! or "run_undetached" (for undetached threads) to return. In other words,
+  //! exit _must_ make the thread quit its "infinite loop" and quit. Its
+  //! content in purely application dependent - that's why the actual
+  //! implementation is delegated to the derived class.
+  virtual void exit (void) = 0;
+
+	//! Returns the associated mutex
+  Mutex & lock (void);
+  
+	//! Allows another thread to run.
+  static void yield (void);
+
+	//! Causes the thread to sleep for the given time.
+  static void sleep (unsigned long msecs);
+  
+protected:
+	//! This constructor is used in a derived class.  The thread will
+	//! execute the run() or run_undetached() member functions depending on
+	//! whether start() or start_undetached() is called respectively.
+  Thread (Tango::DeviceImpl * hd, 
+          IOArg a = 0, 
+          Priority p = bpm::Thread::PRIORITY_NORMAL);
+
+ 	//! Causes the thread to be detached.  
+  //! In this case the thread executes the run member function.
+  void start (void)
+    throw (Tango::DevFailed);
+
+ 	//! Causes the thread to be undetached.
+  //! In this case the thread executes the run_undetached member function.
+  void start_undetached (void)
+    throw (Tango::DevFailed);
+
+	//! Join causes the calling thread to wait for another's completion,
+	//! putting the return value in the variable of type IOArg whose address
+	//! is given (unless passed a null pointer). Only undetached threads
+	//! may be joined. Storage for the thread will be reclaimed. May throw an 
+  //! exception in case the thread is either "not running" or "terminated".
+  //! An exception will also be thrown in case the thread is "detached" or
+  //! in case the underlying OS "wait for the thread to terminate" call fails.
+  void join (Thread::IOArg *)
+    throw (Tango::DevFailed);
+
+	//! The Thread destructor cannot be called by user (except via a derived class).
+	//! Use exit() instead. This also means a thread object must be allocated with
+  //! new - it cannot be statically or automatically allocated. The destructor of
+  //! a class that inherits from omni_thread shouldn't be public either (otherwise 
+  //! the thread object can be destroyed while the underlying thread is still running).
+  virtual ~Thread (void);
+
+	//! Default implementation of the run method (detached thread).
+	//! Should be overridden in a derived class. Called by start()
+  virtual void run (Thread::IOArg)
+  {
+    //- noop
+    DEBUG_ASSERT(true);
+  }
+
+	//! Default implementation of the run_undetached method (undetached thread).
+	//! Should be overridden in a derived class. Called by start_undetached()
+  virtual IOArg run_undetached (Thread::IOArg)
+  {
+    DEBUG_ASSERT(true);
+    return 0;
+  }
+
+  //! The following mutex is used to protect any members which can change
+  //! after construction (such as m_state, m_priority, ...)
+  bpm::Mutex m_lock;
+
+ 	//! Returns the current state of the thread.
+  //! \remarks Does not lock the associated Mutex (\c m_lock)
+  Thread::State state_i (void) const;
+
+private:
+  //! The current TState of the thread.
+  State m_state;
+
+  //! The current TPriority of the thread.
+  Priority m_priority;
+
+  //! The thread input argument
+  Thread::IOArg  m_iarg;
+
+  //! The thread returned value
+  Thread::IOArg  m_oarg;
+
+  //! Detached/undetached flag
+  bool m_detached;
+
+  //! The thread identifier
+  ThreadUID m_uid;
+
+  //! Not implemented private members
+  Thread (const Thread&);
+  Thread & operator= (const Thread&);
+
+  //- platform specific implementation
+  __THREAD_IMPLEMENTATION;
+};
+
+} // namespace bpm 
+
+#if defined (__INLINE_IMPL__)
+#  include "threading/impl/PosixThreadImpl.i"
+#endif
+
+#endif //- _BPM_THREAD_H_
diff --git a/src/TimeUtils.h b/src/TimeUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..4df08c2c621b9ca785b8f3f1185c0c3fee0ca908
--- /dev/null
+++ b/src/TimeUtils.h
@@ -0,0 +1,167 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_TIME_UTILS_H_
+#define _BPM_TIME_UTILS_H_
+
+// ============================================================================
+// TIME MACROS
+// ============================================================================
+#include <ctime>
+#include <sys/time.h>
+#include <math.h>
+
+namespace bpm {
+
+typedef struct _timeval
+{
+  int tv_sec;
+  int tv_usec;
+  time_t tv_utc;
+  _timeval ()
+    : tv_sec(0), tv_usec(0), tv_utc(0) {}
+} _timeval;
+
+} // namespace
+
+#define _TIMESTAMP _timeval
+
+#define _TIMESPEC timespec
+
+#define _GET_TIME(T) \
+  do \
+  { \
+    struct timeval _now; \
+    ::gettimeofday(&_now, 0); \
+    T.tv_sec = _now.tv_sec; \
+    T.tv_usec = _now.tv_usec; \
+    ::time(&T.tv_utc); \
+  } while (0)
+
+#define _MAX_DATE_LEN 256
+
+#define _TIMESTAMP_TO_DATE(T,S) \
+  do \
+  { \
+    struct tm * tmv = ::localtime(&T.tv_utc); \
+    char b[_MAX_DATE_LEN]; \
+    ::memset(b, 0, _MAX_DATE_LEN); \
+    ::strftime(b, _MAX_DATE_LEN, "%a, %d %b %Y %H:%M:%S", tmv); \
+    S = std::string(b); \
+  } while (0)
+  
+#define	_RESET_TIMESTAMP(T) \
+  do \
+  { \
+    T.tv_sec = 0; \
+    T.tv_usec = 0; \
+    T.tv_utc = 0; \
+  } while (0)
+  
+#define	_COPY_TIMESTAMP(S, D) \
+  do \
+  { \
+    D.tv_sec = S.tv_sec; \
+    D.tv_usec = S.tv_usec; \
+    D.tv_utc = S.tv_utc; \
+  } while (0)
+  
+  
+#define	_ELAPSED_SEC(B, A) \
+  static_cast<double>((A.tv_sec - B.tv_sec) + (1.E-6 * (A.tv_usec - B.tv_usec)))
+
+#define	_ELAPSED_MSEC(B, A) _ELAPSED_SEC(B, A) * 1.E3
+
+#define	_ELAPSED_USEC(B, A) _ELAPSED_SEC(B, A) * 1.E6
+
+#define _IS_VALID_TIMESTAMP(T) T.tv_sec != 0 || T.tv_usec != 0
+
+#define	_TMO_EXPIRED(B, A, TMO) _ELAPSED_SEC (B, A) > TMO
+
+
+namespace bpm
+{
+
+typedef _TIMESTAMP Timestamp;
+typedef _TIMESPEC  Timespec;
+
+// ============================================================================
+//  A timer object measures elapsed time.
+//  It is recommended that implementations measure wall clock rather than CPU
+//  time since the intended use is performance measurement on systems where
+//  total elapsed time is more important than just process or CPU time.
+//  Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
+//  due to implementation limitations.  The accuracy of timings depends on the
+//  accuracy of timing information provided by the underlying platform, and
+//  this varies a great deal from platform to platform.
+// ============================================================================
+class Timer
+{
+public:
+  Timer () 
+  { 
+    this->restart();
+  } 
+  
+  void restart() 
+  {
+    ::gettimeofday(&m_start_time, NULL); 
+  }
+
+  //- return elapsed time in seconds
+  double elapsed_sec () const             
+  { 
+    struct timeval now;
+    ::gettimeofday(&now, NULL);
+    return (now.tv_sec - m_start_time.tv_sec) + 1e-6 * (now.tv_usec - m_start_time.tv_usec);
+  }
+
+  //- return elapsed time in milliseconds
+  double elapsed_msec () const             
+  { 
+    struct timeval now;
+    ::gettimeofday(&now, NULL);
+    return 1e3 * (now.tv_sec - m_start_time.tv_sec) + 1e-3 * (now.tv_usec - m_start_time.tv_usec);
+  }
+
+  //- return elapsed time in microseconds
+  double elapsed_usec () const             
+  { 
+    struct timeval now;
+    ::gettimeofday(&now, NULL);
+    return 1e6 * (now.tv_sec - m_start_time.tv_sec) + (now.tv_usec - m_start_time.tv_usec);
+  }
+
+private:
+  struct timeval m_start_time;
+};
+
+} // bpm
+
+#endif // -_BPM_TIME_UTILS_H_
diff --git a/src/Utilities.h b/src/Utilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..8624e49694e2bb9f622b4518aeea7ebca72e3ac3
--- /dev/null
+++ b/src/Utilities.h
@@ -0,0 +1,79 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+
+#ifndef _BPM_THREADING_UTILS_H_
+#define _BPM_THREADING_UTILS_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define BPM_INVALID_THREAD_UID 0xffffffff
+
+namespace bpm {
+
+// ============================================================================
+//! A dedicated type for thread identifier
+// ============================================================================
+typedef unsigned long ThreadUID;
+
+// ============================================================================
+//! The BPM threading utilities
+// ============================================================================
+class ThreadingUtilities
+{
+public:
+ 	//! Returns the calling thread identifier.
+  static ThreadUID self (void);
+
+	//! Causes the caller to sleep for the given time.
+  static void sleep (unsigned long secs, unsigned long nanosecs = 0);
+
+	//! Calculates an absolute time in seconds and nanoseconds, suitable for
+	//! use in timed_waits, which is the current time plus the given relative 
+  //! offset.
+  static void get_time (unsigned long & abs_sec,
+                        unsigned long & abs_nsec,
+			                  unsigned long offset_sec = 0,
+                        unsigned long offset_nsec = 0);
+  
+	//! Calculates an absolute time in seconds and nanoseconds, suitable for
+	//! use in timed_waits, which is the current time plus the given relative 
+  //! offset. WORKS ONLY FOR <delay_msecs> < 1 SECS. 
+  static void get_time (unsigned long delay_msecs, Timespec& abs_time);
+};
+
+} // namespace bpm 
+
+#endif //- _BPM_THREADING_UTILS_H_
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63bd8ac3b66462acd25215cbddc6cfe8aa596406
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,72 @@
+//+=============================================================================
+//
+// file :        main.cpp
+//
+// description : C++ source for a TANGO device server main.
+//               The main rule is to initialise (and create) the Tango
+//               system and to create the DServerClass singleton.
+//               The main should be the same for every Tango device server.
+//
+// project :     TANGO Device Server
+//
+// $Author: nleclercq $
+//
+// copyleft :    European Synchrotron Radiation Facility
+//               BP 220, Grenoble 38043
+//               FRANCE
+//
+//-=============================================================================
+//
+//  		This file is generated by POGO
+//	(Program Obviously used to Generate tango Object)
+//
+//         (c) - Software Engineering Group - ESRF
+//=============================================================================
+
+#include <tango.h>
+
+#if defined(ENABLE_CRASH_REPORT)
+# include <crashreporting/crash_report.h>
+#else
+# define DECLARE_CRASH_HANDLER
+# define INSTALL_CRASH_HANDLER
+#endif
+
+DECLARE_CRASH_HANDLER;
+
+int main(int argc, char *argv[])
+{
+  INSTALL_CRASH_HANDLER;
+
+	Tango::Util * tg = 0;
+	try
+	{
+		// Initialise the device server
+		//----------------------------------------
+		tg = Tango::Util::init(argc,argv);
+
+		// Create the device server singleton 
+		//	which will create everything
+		//----------------------------------------
+		tg->server_init(false);
+
+		// Run the endless loop
+		//----------------------------------------
+		cout << "Ready to accept request" << endl;
+		tg->server_run();
+	}
+	catch (bad_alloc)
+	{
+		cout << "Can't allocate memory to store device object !!!" << endl;
+		cout << "Exiting" << endl;
+	}
+	catch (CORBA::Exception &e)
+	{
+		Tango::Except::print_exception(e);
+		
+		cout << "Received a CORBA_Exception" << endl;
+		cout << "Exiting" << endl;
+	}
+	tg->server_cleanup();
+	return(0);
+}
diff --git a/src/threading/Condition.h b/src/threading/Condition.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b39232b57bef1a0ac79d3f91305128fa9eec2f2
--- /dev/null
+++ b/src/threading/Condition.h
@@ -0,0 +1,130 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_CONDITION_H_
+#define _BPM_CONDITION_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+
+// ----------------------------------------------------------------------------
+// Implementation-specific header file.
+// ----------------------------------------------------------------------------
+#if ! defined(__CONDITION_IMPLEMENTATION)
+# error "implementation header file incomplete [no condition implementation]"
+#endif
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// FORWARD DECL
+// ----------------------------------------------------------------------------
+class Mutex;
+
+// ----------------------------------------------------------------------------
+//! \class Condition
+//! \brief The BPM Condition variable class
+//!
+//! The Windows implementation is based on D.C.Schmidt & Al solution describes
+//! in the following article: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+//!
+//! Under Linux (and any other \c POSIX platforms), the code relies on the local
+//! \c pthread implementation.
+//!
+//! \remarks
+//! While its destructor is virtual, this class is not supposed to be derived.\n
+//! Be sure to clearly understand the internal behaviour before trying to do so.
+// ----------------------------------------------------------------------------
+class Condition
+{
+public:
+  //! Constructor.
+  //!
+  //! Each condition must be associated to a mutex that must be hold while
+  //! evaluating the condition. It means that \a external_mutex must be locked
+  //! prior to any to call to the Condition interface. See \link
+  //! http://www.cs.wustl.edu/~schmidt/win32-cv-1.html D.C.Schmidt and I.Pyarali
+  //! \endlink article for details.
+  Condition (bpm::Mutex& external_mutex);
+
+  //! Destructor.
+  //!
+  //! While this destructor is virtual, this class is not supposed to be derived.
+  //! Be sure to understand the internal behaviour before trying to do so.
+  virtual ~Condition (void);
+
+  //! Wait until the condition is either \link Condition::signal signaled\endlink
+  //! or \link Condition::broadcast broadcasted\endlink by another thread.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void wait (void);
+
+  //! Wait for the condition to be \link Condition::signal signaled\endlink
+  //! or \link Condition::broadcast broadcasted\endlink by another thread.
+  //! Returns \c false in case the specified timeout expired before the condition 
+  //! was notified. Returns \c true otherwise.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  //!
+  //! \param tmo_msecs The timeout in milliseconds
+  //! \return \c false [timeout expired] or \c true [condition notified]
+  bool timed_wait (unsigned long tmo_msecs);
+
+  //! Signals the condition by notifying \b one of the waiting threads.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void signal (void);
+
+  //! Broadcasts the condition by notifying \b all waiting threads.
+  //!
+  //! The associated \a external_mutex <b>must be locked</b> by the calling thread.
+  void broadcast (void);
+
+private:
+  //! The so called "external mutex" (see D.Schmidt's article)
+  Mutex & m_external_lock;
+  
+  //! Not implemented private member
+  Condition (const Condition&);
+  //! Not implemented private member
+  Condition & operator= (const Condition&);
+  
+  //! hidden/abstract platform specific implementation
+  __CONDITION_IMPLEMENTATION;
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+#  include <threading/impl/PosixConditionImpl.i>
+#endif
+
+#endif //- _BPM_CONDITION_H_
diff --git a/src/threading/GenericContainer.h b/src/threading/GenericContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..35288f4e20db5bfc9feab96a3e89d4aa1040c5ea
--- /dev/null
+++ b/src/threading/GenericContainer.h
@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _GENERIC_CONTAINER_H_
+#define _GENERIC_CONTAINER_H_
+
+#include "CommonHeader.h"
+
+namespace bpm 
+{
+
+// ============================================================================
+//	class: Container
+// ============================================================================
+class Container
+{
+public:
+  Container ()
+  {
+    //- noop
+  };
+
+  virtual ~Container () 
+  {
+    //- noop
+  };
+};
+
+// ============================================================================
+//	template class: GenericContainer - class T must have a copy ctor
+// ============================================================================
+template <typename T> 
+class GenericContainer : public Container
+{
+public:
+
+  //- ctor
+  GenericContainer (T* _msg_data, bool _ownership = true) 
+    : ptr_(_msg_data), own_(_ownership) 
+  {
+    //- noop
+  }
+
+  //- ctor
+  GenericContainer (const T& _data) 
+    : ptr_(0), own_(true)
+  {
+    try
+    {
+      this->ptr_ = new T(_data);
+      if (this->ptr_ == 0)
+        throw std::bad_alloc();
+    }
+    catch (const std::bad_alloc&)
+    {
+      this->ptr_ = 0;
+      Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                      _CPTC("memory allocation failed"),
+                                      _CPTC("GenericContainer:GenericContainer"));
+    }
+  }
+
+  //- dtor
+  virtual ~GenericContainer ()
+  {
+    if (own_)
+      delete this->ptr_;
+  }
+
+  //- returns content and optionaly transfers ownership to caller
+  T * content (bool transfer_ownership)
+  {
+    T * tmp = this->ptr_;
+    if (transfer_ownership)
+    {
+      this->own_ = false;
+      this->ptr_ = 0;
+    }
+    return tmp;
+  }
+
+  //- returns content
+  T & content ()
+  {
+    return  *(this->ptr_);
+  }
+  
+private:
+  //- actual container content
+  T * ptr_;
+  bool own_;
+};
+
+
+// ============================================================================
+//	template function
+// ============================================================================
+template <typename T> T * extract_data (Container * _c, 
+                                        bool _transfer_ownership = true)
+    throw (Tango::DevFailed)
+{
+  GenericContainer<T> * gc = 0;
+
+  try
+  {
+    gc = dynamic_cast<GenericContainer<T>*>(_c);
+    if (gc == 0)
+  	{
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from Container [unexpected content]"),
+                                      _CPTC("dettach_data"));
+  	}
+  }
+  catch (const std::bad_cast&)
+  {
+    Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                    _CPTC("could not extract data from Container [unexpected content]"),
+                                    _CPTC("dettach_data"));
+  }
+
+  return gc->content(_transfer_ownership);
+}
+
+} // namespace bpm
+
+#endif // _GENERIC_CONTAINER_H_
+
+
+
diff --git a/src/threading/Implementation.h b/src/threading/Implementation.h
new file mode 100644
index 0000000000000000000000000000000000000000..af050779e83da00c4778069083d4f4eda7c0a58c
--- /dev/null
+++ b/src/threading/Implementation.h
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_THREADING_IMPL_H_
+#define _BPM_THREADING_IMPL_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/impl/PosixThreadingImpl.h"
+
+// ============================================================================
+// MISC DEFINEs
+// ============================================================================
+#define kINFINITE_WAIT  0
+#define DUMP_THREAD_UID std::hex << yat::ThreadingUtilities::self() << std::dec 
+
+#endif //- _BPM_THREADING_IMPL_H_
diff --git a/src/threading/Message.cpp b/src/threading/Message.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cdc365dd3123f5bfb2c9793ab7c5211290bf539e
--- /dev/null
+++ b/src/threading/Message.cpp
@@ -0,0 +1,210 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <math.h>
+#include "CommonHeader.h"
+#include "threading/Message.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/Message.i"
+#endif // __INLINE_IMPL__
+
+namespace bpm
+{
+
+// ============================================================================
+// Message::allocate 
+// ============================================================================
+Message * Message::allocate (size_t _msg_type, size_t _msg_priority, bool _waitable)
+  throw (Tango::DevFailed)
+{
+  bpm::Message * msg = 0;
+     
+  try
+  {
+    msg = new bpm::Message (_msg_type, _msg_priority, _waitable);
+  	if (msg == 0)
+      throw std::bad_alloc();
+  }
+  catch (const std::bad_alloc&)
+  {
+    Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"),
+                                   _CPTC("Message allocation failed"),
+                                   _CPTC("Message::allocate"));
+	}
+  catch (...)
+  {
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("Message allocation failed [unknown exception caught]"),
+                                   _CPTC("Message::allocate"));
+	}
+
+  return msg;
+}
+
+// ============================================================================
+// Message::Message
+// ============================================================================
+Message::Message (CSPI_EVENT * e, size_t p, bool w)
+  : SharedObject (),
+    type_ (CSPI_USER),
+    priority_ (p),
+    user_data_ (e->user_data),
+    msg_data_ (0),
+    cspi_data_ (e->hdr.param),
+    cond_ (0),
+    has_waiter_ (false),
+    has_error_ (false)
+{
+  switch (e->hdr.id)
+  {
+    case CSPI_EVENT_USER:
+      this->type_ = CSPI_USER;
+      break;
+    case CSPI_EVENT_OVERFLOW:
+      switch (e->hdr.param)
+      {
+      case CSPI_OVERFLOW_DD_FPGA:
+        this->type_ = CSPI_DD_FPGA_OVERFLOW;
+        break;
+      case CSPI_OVERFLOW_SA_FPGA:
+        this->type_ = CSPI_SA_FPGA_OVERFLOW;
+        break;
+      case CSPI_OVERFLOW_SA_DRV:
+        this->type_ = CSPI_SA_DRVR_OVERFLOW;
+        break;
+      }
+      break;
+    case CSPI_EVENT_CFG:
+      this->type_ = CSPI_CONFIG_CHANGE;
+      break;
+    case CSPI_EVENT_SA:
+      this->type_ = CSPI_SA;
+      break;
+    case CSPI_EVENT_INTERLOCK:
+      this->type_ = CSPI_INTERLOCK;
+      break;
+    case CSPI_EVENT_PM:
+      this->type_ = CSPI_PM;
+      break;
+    case CSPI_EVENT_FA:
+      this->type_ = CSPI_FA;
+      break;
+    case CSPI_EVENT_TRIGGET:
+      this->type_ = CSPI_TRIGGET;
+      break;
+    case CSPI_EVENT_TRIGSET:
+      this->type_ = CSPI_TRIGSET;
+      break;
+  }
+  
+  if (w)
+    this->make_waitable();
+}
+
+// ============================================================================
+// Message::Message
+// ============================================================================
+Message::Message (size_t t, size_t p, bool _w)
+  : SharedObject (),
+    type_ (t),
+    priority_ (p),
+    user_data_ (0), 
+    msg_data_ (0),
+    cspi_data_ (0),
+    cond_ (0),
+    has_waiter_ (false),
+    has_error_ (false),
+    processed_ (false)
+{
+  if (_w)
+    this->make_waitable();
+}
+
+// ============================================================================
+// Message::~Message
+// ============================================================================
+Message::~Message ()
+{
+  //-note: exception_ contains some Tango::DevError which itself 
+  //-note: contains CORBA::string_member which releases the 
+  //-note: associated memory (i.e. char*)
+
+	if (this->msg_data_)
+  {
+		delete this->msg_data_;
+    this->msg_data_ = 0;
+  }
+  
+  DEBUG_ASSERT(this->processed_ ? true : (this->has_waiter_ ? false : true));
+  
+	if (this->cond_)
+  {
+    if (! this->processed_)
+    {
+      AutoMutex<Mutex> guard(this->lock_);
+      this->cond_->broadcast();
+    }
+		delete this->cond_;
+  }
+}
+
+// ============================================================================
+// Message::make_waitable 
+// ============================================================================
+void Message::make_waitable (void)
+  throw (Tango::DevFailed)
+{ 
+  if (this->cond_)
+    return;
+
+  try
+  {
+    this->cond_ = new Condition(this->lock_);
+    if (this->cond_ == 0)
+      throw std::bad_alloc();
+  }
+  catch (const std::bad_alloc&)
+  {
+    Tango::Except::throw_exception(_CPTC("MEMORY_ERROR"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("Message::make_waitable"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"),
+                                   _CPTC("memory allocation failed"),
+                                   _CPTC("Message::make_waitable"));
+  }
+}
+
+} // namespace bpm
diff --git a/src/threading/Message.h b/src/threading/Message.h
new file mode 100644
index 0000000000000000000000000000000000000000..793a3f43b5d84507a3aff74d6b0a62a5b49520e5
--- /dev/null
+++ b/src/threading/Message.h
@@ -0,0 +1,332 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MSG_H_
+#define _BPM_MSG_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+#include "threading/Semaphore.h"
+#include "threading/SharedObject.h"
+#include "threading/GenericContainer.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define HIGHEST_MSG_PRIORITY  0xFFFF
+#define LOWEST_MSG_PRIORITY   0
+#define INIT_MSG_PRIORITY     HIGHEST_MSG_PRIORITY
+#define EXIT_MSG_PRIORITY     HIGHEST_MSG_PRIORITY
+#define MAX_USER_PRIORITY     (HIGHEST_MSG_PRIORITY - 20)
+#define DEFAULT_MSG_PRIORITY  LOWEST_MSG_PRIORITY
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// enum: MessageType
+// ============================================================================
+typedef enum
+{
+  //--------------------
+  CSPI_USER = 0,
+  CSPI_DD_FPGA_OVERFLOW,
+  CSPI_SA_FPGA_OVERFLOW,
+  CSPI_SA_DRVR_OVERFLOW,
+  CSPI_CONFIG_CHANGE,
+  CSPI_SA,
+  CSPI_INTERLOCK,
+  CSPI_PM,
+  CSPI_FA,
+  CSPI_TRIGGET,
+  CSPI_TRIGSET,
+  //--------------------
+  TASK_INIT,
+  TASK_TIMEOUT,
+  TASK_PERIODIC,
+  TASK_EXIT,
+  //--------------------
+  FIRST_USER_MSG = 1000
+} MessageType;
+
+// ============================================================================
+//  struct: Message
+// ============================================================================
+class Message : private SharedObject
+{
+  friend class Task;
+  friend class Thread;
+  
+public:
+
+	//---------------------------------------------
+	// Message::factory
+	//---------------------------------------------
+  static Message * allocate (size_t msg_type, 
+                             size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                             bool waitable = false)
+    throw (Tango::DevFailed);
+
+
+  //---------------------------------------------
+  // Message::ctor
+  //---------------------------------------------
+  explicit Message (CSPI_EVENT * evt, 
+                    size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                    bool waitable = false);
+
+  //---------------------------------------------
+  // Message::ctor
+  //---------------------------------------------
+  explicit Message (size_t msg_type, 
+                    size_t msg_priority = DEFAULT_MSG_PRIORITY,
+                    bool waitable = false);
+
+  //---------------------------------------------
+  // Message::dtor
+  //---------------------------------------------
+  virtual ~Message ();
+
+  //---------------------------------------------
+  // Message::to_string
+  //---------------------------------------------
+  const char * to_string (void) const;
+
+  //---------------------------------------------
+  // Message::is_ctrl_message
+  //---------------------------------------------
+  bool is_ctrl_message (void);
+  
+  //---------------------------------------------
+  // Message::duplicate
+  //---------------------------------------------
+  Message * duplicate (void);
+  
+  //---------------------------------------------
+  // Message::release
+  //---------------------------------------------
+  void release (void);
+  
+	//---------------------------------------------
+	// Message::type
+	//---------------------------------------------
+	size_t type (void) const;
+
+	//---------------------------------------------
+	// Message::type
+	//---------------------------------------------
+  size_t priority (void) const;
+  
+	//---------------------------------------------
+	// Message::user_data
+	//---------------------------------------------
+  void * user_data (void) const;
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  void user_data (void * user_data);
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  int cspi_data (void) const;
+  
+	//---------------------------------------------
+	// Message::cspi_data
+	//---------------------------------------------
+  void cspi_data (int _cspi_data);
+
+  //---------------------------------------------
+	// Message::attach_data - gets ownership
+	//---------------------------------------------
+  template <typename T> void attach_data (T * _data, bool _ownership = true)
+    throw (Tango::DevFailed)
+  {
+    Container * md = new GenericContainer<T>(_data, _ownership);
+    if (md == 0)
+    {
+     Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                     _CPTC("MessageData allocation failed"),
+                                     _CPTC("Message::attach_data"));
+    }
+    this->msg_data_ = md;
+  }
+
+  //---------------------------------------------
+	// Message::attach_data - makes a copy
+	//---------------------------------------------
+  template <typename T> void attach_data (const T & _data)
+    throw (Tango::DevFailed)
+  {
+    Container * md = new GenericContainer<T>(_data);
+    if (md == 0)
+    {
+     Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                     _CPTC("MessageData allocation failed"),
+                                     _CPTC("Message::attach_data"));
+    }
+    this->msg_data_ = md;
+  }
+  
+  //---------------------------------------------
+  // Message::get_data
+  //---------------------------------------------
+  template <typename T> T& get_data () const
+    throw (Tango::DevFailed)
+  {
+    GenericContainer<T> * c = 0;
+    try
+    {
+      c = dynamic_cast<GenericContainer<T>*>(this->msg_data_);
+      if (c == 0)
+      {
+        Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                        _CPTC("could not extract data from message [unexpected content]"),
+                                        _CPTC("Message::msg_data"));
+      }
+    }
+    catch(const std::bad_cast&)
+    {
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from message [unexpected content]"),
+                                      _CPTC("Message::msg_data"));
+    }
+    return c->content();
+  }
+  
+	//---------------------------------------------
+	// Message::detach_data
+	//---------------------------------------------
+  template <typename T> void detach_data (T*& _data) const
+    throw (Tango::DevFailed)
+  {
+    try
+    {
+    	GenericContainer<T> * c = dynamic_cast<GenericContainer<T>*>(this->msg_data_);
+      if (c == 0)
+  	  {
+        Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                        _CPTC("could not extract data from message [unexpected content]"),
+                                        _CPTC("Message::msg_data"));
+  	  }
+  	  _data = c->content(true);
+    }
+    catch(const std::bad_cast&)
+    {
+      Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"),
+                                      _CPTC("could not extract data from message [unexpected content]"),
+                                      _CPTC("Message::msg_data"));
+    }
+  }
+
+	//---------------------------------------------
+	// Message::make_waitable
+	//--------------------------------------------
+  void make_waitable (void)
+    throw (Tango::DevFailed);
+    
+	//---------------------------------------------
+	// Message::waitable
+	//--------------------------------------------
+  bool waitable (void) const;
+  
+  //---------------------------------------------
+  // Message::wait_processed
+  //---------------------------------------------
+  bool wait_processed (unsigned long tmo_ms);
+    
+ 	//---------------------------------------------
+	// Message::processed
+	//---------------------------------------------
+  void processed (void); 
+  
+	//---------------------------------------------
+	// Message::has_error
+	//---------------------------------------------
+  bool has_error (void) const;
+
+	//---------------------------------------------
+	// Message::set_error
+	//---------------------------------------------
+  void set_error (const Tango::DevFailed & e);
+
+	//---------------------------------------------
+	// Message::get_error
+	//---------------------------------------------
+  const Tango::DevFailed & get_error (void) const;
+  
+private:
+  //- the notification type
+  int type_;
+  
+	//- the msg priority
+	size_t priority_;
+	
+  //- the associated user data (common to all messages)
+  void * user_data_;
+  
+	//- the msg data (specific to a given message)
+	Container * msg_data_;
+	
+	//- the cspi data (from cspi evt)
+  int cspi_data_;
+  
+  //- condition variable (for waitable msgs)
+	Condition * cond_;
+	
+  //- true if a thread is "waiting" for the message to be handled
+  bool has_waiter_;
+  
+  //- true if an error occured during message handling
+  bool has_error_;
+  
+  //- true if msg has been processed
+  bool processed_;
+  
+  //- TANGO exception local storage
+  Tango::DevFailed exception_;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  Message & operator= (const Message &);
+  Message (const Message &);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/Message.i"
+#endif 
+
+#endif // _BPM_MSG_H_
diff --git a/src/threading/Message.i b/src/threading/Message.i
new file mode 100644
index 0000000000000000000000000000000000000000..4642cbc4dcde1425b5774c7e02b47d44aa933003
--- /dev/null
+++ b/src/threading/Message.i
@@ -0,0 +1,224 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// Message::duplicate
+// ============================================================================
+INLINE_IMPL Message * Message::duplicate (void)
+{
+  return reinterpret_cast<Message*>(this->SharedObject::duplicate ());
+}
+
+// ============================================================================
+// Message::release
+// ============================================================================
+INLINE_IMPL void Message::release (void)
+{
+  this->SharedObject::release ();
+}
+  
+// ============================================================================
+// Message::is_ctrl_message
+// ============================================================================
+INLINE_IMPL bool Message::is_ctrl_message (void)
+{
+  return this->type_ == TASK_INIT || this->type_ == TASK_EXIT;
+}
+
+// ============================================================================
+// Message::to_string
+// ============================================================================
+INLINE_IMPL const char * Message::to_string (void) const
+{
+  switch (this->type_)
+  {
+    case CSPI_USER:
+      return "CSPI_USER";
+      break;
+    case CSPI_DD_FPGA_OVERFLOW:
+      return "CSPI_DD_FPGA_OVERFLOW";
+      break;
+    case CSPI_SA_FPGA_OVERFLOW:
+      return "CSPI_SA_FPGA_OVERFLOW";
+      break;
+    case CSPI_SA_DRVR_OVERFLOW:
+      return "CSPI_SA_DRVR_OVERFLOW";
+      break;
+    case CSPI_CONFIG_CHANGE:
+      return "CSPI_CONFIG_CHANGE";
+      break;
+    case CSPI_SA:
+      return "CSPI_SA";
+      break;
+    case CSPI_INTERLOCK:
+      return "CSPI_INTERLOCK";
+      break;
+    case CSPI_PM:
+      return "CSPI_PM";
+      break;
+    case CSPI_FA:
+      return "CSPI_FA";
+      break;
+    case CSPI_TRIGGET:
+      return "CSPI_TRIGGET";
+      break;
+    case CSPI_TRIGSET:
+      return "CSPI_TRIGSET";
+      break;
+    case TASK_INIT:
+      return "TASK_INIT";
+      break;
+    case TASK_TIMEOUT:
+      return "TASK_TIMEOUT";
+      break;
+    case TASK_EXIT:
+      return "TASK_EXIT";
+      break;
+  }
+  return "UNKNOWN OR USER DEFINED MSG";
+}
+    
+// ============================================================================
+// Message::type
+// ============================================================================
+INLINE_IMPL size_t Message::type (void) const
+{
+  return this->type_;
+}
+
+// ============================================================================
+// Message::priority
+// ============================================================================
+INLINE_IMPL size_t Message::priority (void) const
+{
+  return this->priority_;
+}
+
+// ============================================================================
+// Message::user_data
+// ============================================================================
+INLINE_IMPL void * Message::user_data (void) const
+{
+  return this->user_data_;
+}
+
+// ============================================================================
+// Message::user_data
+// ============================================================================
+INLINE_IMPL void Message::user_data (void* _ud)
+{
+  this->user_data_ = _ud;
+}
+
+// ============================================================================
+// Message::cspi_data
+// ============================================================================
+INLINE_IMPL int Message::cspi_data (void) const
+{
+  return this->cspi_data_;
+}
+
+// ============================================================================
+// Message::cspi_data
+// ============================================================================
+INLINE_IMPL void Message::cspi_data (int _cspi_data)
+{
+  this->cspi_data_ = _cspi_data;
+}
+
+// ============================================================================
+// Message::waitable
+// ============================================================================
+INLINE_IMPL bool Message::waitable (void) const
+{
+  return this->cond_  ? true : false;
+}
+
+// ============================================================================
+// Message::wait_processed
+// ============================================================================
+INLINE_IMPL bool Message::wait_processed (unsigned long _tmo_ms)
+{
+  bpm::AutoMutex<bpm::Mutex> guard (this->lock_);
+  
+  if (! this->waitable())
+  {
+	  Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"),
+                                   _CPTC("Message::wait_processed called on a none waitable message [check code]"),
+                                   _CPTC("Message::wait_processed"));
+  }
+  
+  if (this->processed_)
+    return true;
+ 
+  return this->cond_->timed_wait(_tmo_ms);
+}
+
+// ============================================================================
+// Message::processed
+// ============================================================================
+INLINE_IMPL void Message::processed (void)
+{
+  bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+
+  this->processed_ = true;
+
+  if (this->waitable())
+    this->cond_->broadcast();
+}
+
+// ============================================================================
+// Message::has_error
+// ============================================================================
+INLINE_IMPL bool Message::has_error (void) const
+{
+  return this->has_error_;
+}
+
+// ============================================================================
+// Message::set_error
+// ============================================================================
+INLINE_IMPL void Message::set_error (const Tango::DevFailed & e)
+{
+  this->has_error_ = true;
+  this->exception_ = e;
+}
+
+// ============================================================================
+// Message::get_error
+// ============================================================================
+INLINE_IMPL const Tango::DevFailed & Message::get_error (void) const
+{
+  return this->exception_;
+}
+
+} //- namespace bpm
diff --git a/src/threading/MessageQ.cpp b/src/threading/MessageQ.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38f0c837fb758c5cf77d9634dda44a8ebe31139d
--- /dev/null
+++ b/src/threading/MessageQ.cpp
@@ -0,0 +1,425 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/MessageQ.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/MessageQ.i"
+#endif // __INLINE_IMPL__
+
+namespace bpm
+{
+
+// ============================================================================
+// MessageQ::MessageQ
+// ============================================================================
+MessageQ::MessageQ (size_t _lo_wm, size_t _hi_wm, bool _throw_on_post_tmo)
+  : msg_q_ (0),
+    msg_producer_sync_ (lock_),
+    msg_consumer_sync_ (lock_),
+		state_(MessageQ::OPEN),
+		enable_timeout_msg_ (false),
+    enable_periodic_msg_ (false),
+    lo_wm_ (_lo_wm),
+    hi_wm_ (_hi_wm),
+    saturated_ (false),
+    throw_on_post_msg_timeout_ (_throw_on_post_tmo),
+    last_returned_msg_periodic_ (true)
+{
+  this->last_periodic_msg_ts_.tv_sec = 0;
+  this->last_periodic_msg_ts_.tv_usec = 0;
+}
+
+// ============================================================================
+// MessageQ::~MessageQ
+// ============================================================================
+MessageQ::~MessageQ (void)
+{
+  bpm::AutoMutex<bpm::Mutex> (this->lock_);
+
+  this->state_ = MessageQ::CLOSED;
+
+  this->clear_i();
+}
+
+// ============================================================================
+// MessageQ::clear_i
+// ============================================================================
+size_t MessageQ::clear_i (void)
+{
+  size_t num_msg_in_q = this->msg_q_.size();
+
+  while (! this->msg_q_.empty())
+  {
+	  Message * m = this->msg_q_.front ();
+    if (m) m->release();
+	  this->msg_q_.pop_front();
+  }
+
+  return num_msg_in_q;
+}
+
+// ============================================================================
+// MessageQ::close
+// ============================================================================
+void MessageQ::close (void)
+{
+  bpm::AutoMutex<bpm::Mutex> (this->lock_);
+  
+	this->state_ = MessageQ::CLOSED;
+}
+
+// ============================================================================
+// MessageQ::post
+// ============================================================================
+void MessageQ::post (bpm::Message * msg, size_t _tmo_msecs)
+  throw (Tango::DevFailed)
+{
+  //- check input
+  if (! msg) return;
+  
+  //- caller can't post any TIMEOUT or PERIODIC msg
+  if (msg->type() == TASK_TIMEOUT || msg->type() == TASK_PERIODIC)
+  {
+	  //- silently trash the message
+	  msg->release();
+	  return;
+  }
+  
+  //- enter critical section (required for cond.var. to work properly)
+  bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+
+  //- can only post a msg on an opened MsgQ
+  if (this->state_ != MessageQ::OPEN)
+  {
+	  //- silently trash the message (should we throw an exception instead?)
+	  msg->release();
+	  return;
+  }
+
+  //- we force post of ctrl message even if the msQ is saturated
+  if (msg->is_ctrl_message()) 
+  {
+    //- insert msg according to its priority
+    try
+    {
+      this->insert_i(msg);
+    }
+    catch (...)
+    {
+      //- insert_i released the message (no memory leak)
+      Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                      _CPTC ("could not post ctrl message [msgQ insertion error]"),
+                                      _CPTC ("MessageQ::post"));
+    }
+    //- wakeup msg consumers (tell them there is a message to handle)
+    //- this will work since we are under critical section 
+    msg_consumer_sync_.signal();
+    //- done (skip remaining code)
+    return;
+  }
+
+  //- is the messageQ saturated?
+  if (! this->saturated_ && (this->msg_q_.size() == this->hi_wm_))
+  {
+    //- mark msgQ as saturated
+    this->saturated_ = true;
+  }
+
+  //- msg is not a ctrl message...
+  //- wait for the messageQ to have room for new messages
+  if (! this->wait_not_full_i(_tmo_msecs))
+  {
+    //- can't post msg, destroy it in order to avoid memory leak
+    msg->release(); 
+    //- throw exception if the messageQ is configured to do so
+    if (this->throw_on_post_msg_timeout_)
+    {
+      Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"),
+                                      _CPTC ("could not post message [timeout expired]"),
+                                      _CPTC ("MessageQ::post"));
+    }
+    //- return if we didn't throw an exception
+    return;
+  }
+  
+  DEBUG_ASSERT(this->msg_q_.size() <= this->hi_wm_);
+
+  //- insert the message according to its priority
+  try
+  {
+    this->insert_i(msg);
+  }
+  catch (...)
+  {
+    //- insert_i released the message (no memory leak)
+    Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                    _CPTC ("could not post message [msgQ insertion error]"),
+                                    _CPTC ("MessageQ::post"));
+  }
+
+  //- wakeup msg consumers (tell them there is a new message to handle)
+  //- this will work since we are still under critical section
+  //--------------------------------------------------
+  //-TODO: avoid using this under sys signal callback!
+  //--------------------------------------------------
+  msg_consumer_sync_.signal ();
+}
+
+// ============================================================================
+// MessageQ::post
+// ============================================================================
+void MessageQ::post (CSPI_EVENT * _evt, size_t _tmo_msecs)
+  throw (Tango::DevFailed)
+{
+  //- check input
+  if (! _evt) return;
+
+  bpm::Message * msg = 0;
+
+  try
+  {
+    msg = new bpm::Message (_evt);
+    if (msg == 0)
+      throw std::bad_alloc ();
+  }
+  catch (const std::bad_alloc &)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                    _CPTC ("memory allocation failed"),
+                                    _CPTC ("MessageQ::post"));
+  }
+  catch (...)
+  {
+    Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"),
+                                    _CPTC ("memory allocation failed"),
+                                    _CPTC ("MessageQ::post"));
+  }
+  
+  this->post(msg, _tmo_msecs);
+}
+
+// ============================================================================
+// MessageQ::next_message
+// ============================================================================ 
+bpm::Message * MessageQ::next_message (size_t _tmo_msecs)
+{
+  //- enter critical section (required for cond.var. to work properly)
+	bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+
+  //- the msg
+  bpm::Message * msg = 0;
+  
+  //- wait for the messageQ to contain at least one message
+  //- bpm::Timer t;
+  //- std:cout << "[this:" << (long)this << "]" << " - wait_not_empty_i waiting for msg [tmo is " << _tmo_msecs << "]" << std::endl;
+  if (! this->wait_not_empty_i(_tmo_msecs))
+  {
+    //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned false after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl;
+    //- <wait_not_empty_i> returned <false> : means no msg in msg queue after <_tmo_msecs>
+    //- it may be time to return a periodic message
+    if (this->enable_periodic_msg_ && this->periodic_tmo_expired(_tmo_msecs))
+    {
+      this->last_returned_msg_periodic_ = true; 
+      GET_TIME(this->last_periodic_msg_ts_);
+      //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC" << std::endl; 
+      return new Message(TASK_PERIODIC); 
+    }
+    //- else return a timeout msg 
+    if (this->enable_timeout_msg_)  
+    {
+      this->last_returned_msg_periodic_ = false;
+      //- std::cout << "MessageQ::next_message::returning TASK_TIMEOUT" << std::endl; 
+      return new Message(TASK_TIMEOUT);
+    }
+    //- no msg 
+    //- std::cout << "MessageQ::next_message::returning NULL msg" << std::endl; 
+    this->last_returned_msg_periodic_ = false; 
+    return 0;
+  }
+    
+  //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned true after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl;
+  
+  //- ok, there should be at least one message in the messageQ
+  DEBUG_ASSERT(this->msg_q_.empty() == false);
+
+  //- we are still under critical section since the "Condition::timed_wait" 
+  //- located in "wait_not_empty_i" garantee that the associated mutex (i.e. 
+  //- this->lock_ in the present case) is acquired when the function returns
+
+	//- get msg from Q
+  msg = this->msg_q_.front();
+
+  //- parano. debugging
+  DEBUG_ASSERT(msg != 0);
+
+  //- if the msg is a ctrl msg...
+  if (msg->is_ctrl_message())
+  {
+    //... then extract it from the Q and return it
+	  this->msg_q_.pop_front();
+    //- if we reach the low water mark, then wakeup msg producer(s) 
+    if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_)
+    {
+      //- no longer saturated
+      this->saturated_ = false;
+      //- this will work since we are still under critical section
+      this->msg_producer_sync_.broadcast();
+    }
+    //- we are about to return a ctrl msg so...
+    this->last_returned_msg_periodic_ = false;
+    //- return ctrl message
+    //- std::cout << "MessageQ::next_message::returning a CTRL msg" << std::endl; 
+	  return msg;
+  }
+
+  //- avoid PERIODIC msg starvation (see note above)
+  if (
+       this->enable_periodic_msg_ 
+         &&
+       this->periodic_tmo_expired(_tmo_msecs) 
+         && 
+       this->last_returned_msg_periodic_ == false
+     )
+  {
+      //- we didn't actually extract the <msg> from the Q.
+      //- we just "accessed it using "pop_front" so no need to reinject it into the Q
+      this->last_returned_msg_periodic_ = true;
+      GET_TIME(this->last_periodic_msg_ts_);
+      //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC msg" << std::endl; 
+      return new Message(TASK_PERIODIC); 
+  }
+  
+  //- we are about to return a msg from the Q so...
+  this->last_returned_msg_periodic_ = false;
+  
+  //- then extract it from the Q and return it
+  this->msg_q_.pop_front();
+  
+  //- if we reach the low water mark, then wakeup msg producer(s) 
+  if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_)
+  {
+    //- no longer saturated
+    this->saturated_ = false;
+    //- this will work since we are still under critical section
+    this->msg_producer_sync_.broadcast(); 
+  }
+	
+	//- std::cout << "MessageQ::next_message::returning USER msg" << std::endl; 
+	
+	return msg;
+}
+
+// ============================================================================
+// MessageQ::wait_not_empty_i
+// ============================================================================
+bool MessageQ::wait_not_empty_i (size_t _tmo_msecs)
+{
+	//- <this->lock_> MUST be locked by the calling thread
+  //----------------------------------------------------
+
+  //- while the messageQ is empty...
+  while (this->msg_q_.empty())
+  {
+ 	  //- wait for a msg or tmo expiration 
+    if (! this->msg_consumer_sync_.timed_wait(_tmo_msecs))
+      return false; 
+  }
+
+  //- at least one message available in the MsgQ
+  return true;
+} 
+
+// ============================================================================
+// MessageQ::wait_not_full_i
+// ============================================================================
+bool MessageQ::wait_not_full_i (size_t _tmo_msecs)
+{
+	//- <this->lock_> MUST be locked by the calling thread
+  //----------------------------------------------------
+
+  //- while the messageQ is full...
+  while (this->saturated_)
+  {
+ 	  //- wait for some msgs to be consumed or tmo expiration 
+    if (! this->msg_producer_sync_.timed_wait(_tmo_msecs))
+      return false; 
+  }
+
+  //- at least one message available in the MsgQ
+  return true;
+}
+
+// ============================================================================
+// Binary predicate
+// ============================================================================
+static bool insert_msg_criterion (Message * const m1, Message * const m2)
+{
+  return m2->priority() < m1->priority();  
+}
+ 
+// ============================================================================
+// MessageQ::insert_i
+// ============================================================================
+void MessageQ::insert_i (Message * _msg)
+  throw (Tango::DevFailed)
+{
+  try
+  {
+    if (this->msg_q_.empty())
+    {
+      //- optimization: no need to take count of the msg priority
+      this->msg_q_.push_front (_msg);
+    }
+    else
+    { 
+      //- insert msg according to its priority
+      MessageQImpl::iterator pos = std::upper_bound(this->msg_q_.begin(),
+                                                    this->msg_q_.end(),
+                                                    _msg,
+                                                    insert_msg_criterion);
+      this->msg_q_.insert(pos, _msg);
+    }
+  }
+  catch (...)
+  {
+    _msg->processed();
+    _msg->release();
+    Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"),
+                                    _CPTC ("could insert message into the message queue"),
+                                    _CPTC ("MessageQ::insert_i"));
+ 
+  }
+}
+
+} // namespace bpm
diff --git a/src/threading/MessageQ.h b/src/threading/MessageQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee8af1d8f7aab0b6bd4fa49d2267158a0834823f
--- /dev/null
+++ b/src/threading/MessageQ.h
@@ -0,0 +1,200 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MSGQ_H_
+#define _BPM_MSGQ_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <list>
+#include "CommonHeader.h"
+#include "threading/Message.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_THD_TMO_MSECS 1000
+#if defined(kDEFAULT_MSG_TMO_MSECS)
+# undef kDEFAULT_MSG_TMO_MSECS
+#endif
+#define kDEFAULT_MSG_TMO_MSECS 2500
+//-----------------------------------------------------------------------------
+#define kDEFAULT_POST_MSG_TMO   1000
+#define kDEFAULT_LO_WATER_MARK  256
+#define kDEFAULT_HI_WATER_MARK  512
+#define kMIN_LO_WATER_MARK      kDEFAULT_LO_WATER_MARK
+#define kMIN_WATER_MARKS_DIFF   kDEFAULT_LO_WATER_MARK
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// class: MessageQ
+// ============================================================================
+class MessageQ
+{
+  friend class Task;
+
+  typedef std::list<bpm::Message *> MessageQImpl;
+
+public:
+
+  //- MessageQ has a state
+  typedef enum
+  {
+    OPEN,
+    CLOSED
+  } State;
+
+  //- post a bpm::Message into the msgQ
+  void post (bpm::Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) 
+    throw (Tango::DevFailed);
+
+  //- post a cspi event into the msgQ
+  void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) 
+    throw (Tango::DevFailed);
+
+  //- extract next message from the msgQ
+  bpm::Message * next_message (size_t tmo_msecs);
+  
+  //- low water mark mutator
+  void lo_wm (size_t _lo_wm);
+
+  //- low water mark accessor
+  size_t lo_wm () const;
+
+  //- high water mark mutator
+  void hi_wm (size_t _hi_wm);
+
+  //- high water mark accessor
+  size_t hi_wm () const;
+
+  //- should the msgQ throw an exception on post msg tmo expiration?
+  void throw_on_post_msg_timeout (bool _strategy);
+  
+  //- clear msgQ content 
+	void clear();
+	
+  //- close the msqQ
+  void close (void);
+
+  //- enable/disable timeout msg 
+  void enable_timeout_msg (bool b);
+  bool timeout_msg_enabled () const;
+  
+  //- enable/disable handling flag
+  void enable_periodic_msg (bool b);
+  bool periodic_msg_enabled () const;
+  
+private:
+  //- private ctor
+  MessageQ (size_t lo_wm = kDEFAULT_LO_WATER_MARK,
+            size_t hi_wm = kDEFAULT_HI_WATER_MARK,
+            bool throw_on_post_tmo = false);
+            
+  //- private ctor
+  virtual ~MessageQ ();
+            
+  //- check the periodic msg timeout
+  bool periodic_tmo_expired (double tmo_msecs) const;
+
+  //- clears msgQ content (returns num of trashed messages)
+	size_t clear_i();
+
+  //- waits for the msQ to contain at least one msg
+  //- returns false if tmo expired, true otherwise.
+  bool wait_not_empty_i (size_t tmo_msecs);
+
+  //- waits for the msQ to have room for new messages
+  //- returns false if tmo expired, true otherwise.
+  bool wait_not_full_i (size_t tmo_msecs);
+
+  //- insert a msg according to its priority
+  void insert_i (Message * msg)
+    throw (Tango::DevFailed);
+
+	//- use a std::deque to implement msgQ
+	MessageQImpl msg_q_;
+
+	//- sync. object in order to make the msgQ thread safe
+	bpm::Mutex lock_;
+
+	//- Producer(s) synch object
+	bpm::Condition msg_producer_sync_;
+
+	//- Consumer synch object
+	bpm::Condition msg_consumer_sync_;
+	
+	//- state
+	MessageQ::State state_;
+
+  //- timeout msg handling flag
+  bool enable_timeout_msg_;
+
+  //- periodic msg handling flag
+  bool enable_periodic_msg_;
+
+  //- last returned PERIODIC msg timestamp
+  TIME_VAL last_periodic_msg_ts_;
+
+  //- low water marks
+  size_t lo_wm_;
+
+  //- high water marks
+  size_t hi_wm_;
+
+  //- msqQ saturation flag
+  bool saturated_;
+
+  //- expection activation flag
+  bool throw_on_post_msg_timeout_;
+  
+  //- flag indicating whether or not the last returned msg was a periodoc msg
+  //- we use this flag in order to avoid PERIODIC event flooding in case
+  //- the PERIODIC event frequency is really high - which could prevent other
+  //- messages from being handled. reciprocally, a very high msg posting freq.
+  //- could prevent the PERIODIC msg from being handled. the following tries
+  //- to ensure that any msg is "finally" handled.
+  bool last_returned_msg_periodic_;
+  
+  // = Disallow these operations.
+  //--------------------------------------------
+  MessageQ & operator= (const MessageQ &);
+  MessageQ (const MessageQ &);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/MessageQ.i"
+#endif // __INLINE_IMPL__
+
+#endif // _BPM_MSGQ_H_
diff --git a/src/threading/MessageQ.i b/src/threading/MessageQ.i
new file mode 100644
index 0000000000000000000000000000000000000000..be6935fc3383ab9e0b67f44f2a878b796615f6ee
--- /dev/null
+++ b/src/threading/MessageQ.i
@@ -0,0 +1,133 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// MessageQ::periodic_tmo_expired
+// ============================================================================
+INLINE_IMPL bool MessageQ::periodic_tmo_expired (double _tmo_msecs) const
+{
+  TIME_VAL now; 
+  GET_TIME(now);
+  return ELAPSED_MSEC(this->last_periodic_msg_ts_, now) >= (0.95 * _tmo_msecs);
+}
+
+// ============================================================================
+// MessageQ::lo_wm
+// ============================================================================
+INLINE_IMPL void MessageQ::lo_wm (size_t _lo_wm)
+{
+  this->lo_wm_ = _lo_wm;  
+
+  if (this->lo_wm_ < kMIN_LO_WATER_MARK)
+    this->lo_wm_ = kMIN_LO_WATER_MARK;
+
+  if ((this->hi_wm_ - this->lo_wm_) < kMIN_WATER_MARKS_DIFF)
+    this->hi_wm_ = this->lo_wm_ + kMIN_WATER_MARKS_DIFF;
+}
+
+// ============================================================================
+// MessageQ::lo_wm
+// ============================================================================
+INLINE_IMPL size_t MessageQ::lo_wm ()  const
+{
+  return this->lo_wm_;
+}
+
+// ============================================================================
+// MessageQ::hi_wm
+// ============================================================================
+INLINE_IMPL void MessageQ::hi_wm (size_t _hi_wm)
+{
+  this->hi_wm_ = _hi_wm;
+
+  if ((this->hi_wm_ - this->lo_wm_) < kMIN_WATER_MARKS_DIFF)
+    this->hi_wm_ = this->lo_wm_ + kMIN_WATER_MARKS_DIFF;
+}
+
+// ============================================================================
+// MessageQ::hi_wm
+// ============================================================================
+INLINE_IMPL size_t MessageQ::hi_wm ()  const
+{
+  return this->hi_wm_;
+}
+
+// ============================================================================
+// MessageQ::throw_on_post_msg_timeout
+// ============================================================================
+INLINE_IMPL void MessageQ::throw_on_post_msg_timeout (bool _strategy)
+{
+  this->throw_on_post_msg_timeout_ = _strategy;
+}
+
+// ============================================================================
+// MessageQ::clear
+// ============================================================================
+INLINE_IMPL void MessageQ::clear (void)
+{
+  bpm::AutoMutex<bpm::Mutex> guard(this->lock_);
+  this->clear_i();
+}
+
+// ============================================================================
+// MessageQ::enable_timeout_msg
+// ============================================================================
+INLINE_IMPL void MessageQ::enable_timeout_msg (bool b)
+{
+  this->enable_timeout_msg_ = b;
+}
+
+// ============================================================================
+// MessageQ::timeout_msg_enabled
+// ============================================================================
+INLINE_IMPL bool MessageQ::timeout_msg_enabled (void) const
+{
+  return this->enable_timeout_msg_;
+}
+
+// ============================================================================
+// MessageQ::enable_periodic_msg
+// ============================================================================
+INLINE_IMPL void MessageQ::enable_periodic_msg (bool b)
+{
+  this->enable_periodic_msg_ = b;
+}
+
+// ============================================================================
+// MessageQ::periodic_msg_enabled
+// ============================================================================
+INLINE_IMPL bool MessageQ::periodic_msg_enabled (void) const
+{
+  return this->enable_periodic_msg_;
+}
+
+} //- namespace bpm
diff --git a/src/threading/Mutex.h b/src/threading/Mutex.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1fd465d4e30697e324d930a67f92d183f4225d0
--- /dev/null
+++ b/src/threading/Mutex.h
@@ -0,0 +1,237 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_MUTEX_H_
+#define _BPM_MUTEX_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Utilities.h"
+#include "threading/Implementation.h"
+
+// ============================================================================
+// Implementation-specific header file.
+// ============================================================================
+#if ! defined(__MUTEX_IMPLEMENTATION)
+# error "implementation header file incomplete [no mutex implementation]"
+#endif
+
+namespace bpm {
+
+// ============================================================================
+//! <BPM_MUTEX>::try_lock may return one of the following MutexState
+// ============================================================================
+typedef enum
+{
+  MUTEX_LOCKED,
+  MUTEX_BUSY,
+} MutexState;
+
+// ============================================================================
+//! The BPM NullMutex class
+// ============================================================================
+class NullMutex
+{
+  //! This is the yat NullMutex class.
+  //!
+  //! Provides a "do nothing" Mutex impl. May be used as template argument
+  //! in order to control the template instanciation and avoiding locking
+  //! overhead where thread safety is not required.
+  //!
+  //! template <typename LOCK> class OptionalThreadSafetyImpl
+  //! {
+  //! public:
+  //!   inline void do_something (void)
+  //!   {
+  //!      yat::AutoMutex<LOCK>(this->m_mutex);
+  //!      ...
+  //!   }
+  //! private:
+  //    LOCK m_mutex;
+  //! }
+  //!
+  //! OptionalThreadSafetyImpl<yat::Mutex> will be thread safe while...
+  //! OptionalThreadSafetyImpl<yat::NullMutex> will not be!
+  //!
+  //! This class is not supposed to be derived.
+
+public:
+  //! Constructor.
+  NullMutex (void);
+
+  //! Destructor.
+  ~NullMutex (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void lock (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void acquire (void);
+
+  //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED.
+  MutexState try_lock (void);
+
+  //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED.
+  MutexState try_acquire (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void unlock (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void release (void);
+
+private:
+  //! Not implemented private member
+  NullMutex (const NullMutex&);
+  //! Not implemented private member
+  NullMutex & operator= (const NullMutex&);
+};
+
+// ============================================================================
+//! The BPM Mutex class
+// ============================================================================
+class Mutex
+{
+  //! This is the yat Mutex implementation.
+  //!
+  //! This class is not supposed to be derived (no virtual destructor).
+
+public:
+  //! Constructor.
+  Mutex (void);
+
+  //! Destructor.
+  ~Mutex (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void lock (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  void acquire (void);
+
+  //! Locks (i.e. acquires) the mutex.
+  //! Returns MUTEX_LOCKED in case the mutex was successfully locked.
+  //! Returns MUTEX_BUSY if it is already owned by another thread.
+  MutexState try_lock (void);
+  
+  //! Locks (i.e. acquires) the mutex.
+  //! Returns MUTEX_LOCKED in case the mutex was successfully locked.
+  //! Returns MUTEX_BUSY if it is already owned by another thread.
+  MutexState try_acquire (void);
+
+  //! Unlocks (i.e. releases) the mutex.
+  void unlock (void);
+  
+  //! Unlocks (i.e. releases) the mutex.
+  void release (void);
+
+private:
+  //! Not implemented private member
+  Mutex (const Mutex&);
+  //! Not implemented private member
+  Mutex & operator= (const Mutex&);
+
+  //- platform specific implementation
+  __MUTEX_IMPLEMENTATION;
+};
+
+// ============================================================================
+//! The BPM "auto mutex" class
+// ============================================================================
+template <typename LOCK_TYPE = bpm::Mutex> class AutoMutex
+{
+  //! An "auto mutex" providing an auto lock/unlock mechanism.
+  //!
+  //! The AutoMutex is ideal in context where some exceptions may be thrown.
+  //! Whatever is the exit path of your code, the <AutoMutex> will garantee
+  //! that the associated <Mutex> is properly unlock.
+  //!
+  //! This class is template since it may be used in contexts in which the
+  //! thread safety is optionnal (see yat::NullMutex for an example).
+  //!
+  //! AutoMutex provides an efficient and safe alternative to:
+  //!
+  //! { //- enter critical section
+  //!   my_mutex.lock();
+  //!   ...your critical section code goes here (may throw an exception)...
+  //!   my_mutex.unlock();
+  //! } //- leave critical section
+  //!
+  //! In such a context, you can use a instance AutoMutex as follows:
+  //!
+  //! { //- enter critical section
+  //!   yat::AutoMutex<> guard(my_mutex);
+  //!   ...your critical section code goes here (may throw an exception)...
+  //! } //- leave critical section
+  //!
+  //! This has the advantage that my_mutex.unlock() will be called automatically
+  //! even if an exception is thrown. Since the AutoMutex is created on the stack
+  //! its destructor will be called whatever is the exit path of critical section.
+  //!
+  //! Note that AutoMutex can be used with any "LOCK_TYPE" which interface contains
+  //! both a lock(void) and a unlock(void) method. The yat::SharedObject class of
+  //! such a compatible "LOCK_TYPE". 
+  //!
+public:
+  //! Constructor (locks the associated Mutex)
+  AutoMutex (LOCK_TYPE & _lock)
+    : m_lock (_lock)
+  {
+    m_lock.lock();
+  }
+
+  //! Destructor (unlocks the associated Mutex)
+  ~AutoMutex (void)
+  {
+    m_lock.unlock();
+  }
+
+private:
+  //! The associated Mutex
+  LOCK_TYPE & m_lock;
+
+  //! Not implemented private member
+  AutoMutex (const AutoMutex&);
+  //! Not implemented private member
+  AutoMutex & operator= (const AutoMutex&);
+};
+
+// ============================================================================
+//! MutexLock: an AutoMutex specialisation (for backforward compatibility)
+// ============================================================================
+typedef AutoMutex<Mutex> MutexLock;
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+#  include "threading/impl/PosixMutexImpl.i"
+#endif
+
+#endif //- _BPM_MUTEX_H_
diff --git a/src/threading/Semaphore.h b/src/threading/Semaphore.h
new file mode 100644
index 0000000000000000000000000000000000000000..32975eed7aca229d90e52922a33183850e103918
--- /dev/null
+++ b/src/threading/Semaphore.h
@@ -0,0 +1,142 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_SEMAPHORE_H_
+#define _BPM_SEMAPHORE_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+
+// ============================================================================
+// Implementation-specific header file.
+// ============================================================================
+#if ! defined(__SEMAPHORE_IMPLEMENTATION)
+# error "implementation header file incomplete [no semaphore implementation]"
+#endif
+
+namespace bpm {
+
+// ============================================================================
+//! <BPM_SEMAPHORE>::try_wait may return one of the following SemaphoreState
+// ============================================================================
+typedef enum
+{
+  //! semaphore is currently "decrementable"
+  SEMAPHORE_DEC,
+  //! no resource available (semaphore value is 0)
+  SEMAPHORE_NO_RSC,
+} SemaphoreState;
+
+// ============================================================================
+//! The BPM Semaphore class
+// ============================================================================
+class Semaphore
+{
+  //! This is the BPM Semaphore class.
+  //!
+  //! This class is not supposed to be derived.
+
+public:
+  //! Constructor (may throw an Exception)
+  Semaphore (unsigned int initial = 1);
+
+  //! Destructor.
+  ~Semaphore (void);
+
+  //! If semaphore value is > 0 then decrement it and carry on. 
+  //! If it's already 0 then block untill the semaphore is either "signaled" 
+  //! or "broascasted" (see post, signal and broadcast members below).
+  void wait (void);
+
+  //! If semaphore value is > 0 then decrements it and returns true. Returns 
+  //! "false" in case the specified timeout expired before the semaphore
+  //! has been "signaled" or "broascasted" by another thread.
+  bool timed_wait (unsigned long tmo_msecs);
+
+  //! If the current semaphore value is > 0, then crements it and returns 
+  //! SEMAPHORE_DEC. In case the semaphore has reached its maximum value,
+  //! this method does not block and "immediately" returns SEMAPHORE_NO_RSC.
+  SemaphoreState try_wait (void);
+
+  //! If any threads are blocked in wait(), wake one of them up. 
+  //! Otherwise increments the value of the semaphore. 
+  void post (void);
+
+private:
+  //! Not implemented private member
+  Semaphore (const Semaphore&);
+  //! Not implemented private member
+  Semaphore & operator= (const Semaphore&);
+  
+  //- platform specific implementation
+  __SEMAPHORE_IMPLEMENTATION;
+};
+
+// ============================================================================
+//! The BPM "auto semaphore" class
+// ============================================================================
+class AutoSemaphore
+{
+  //! An "auto semaphore" providing an auto wait/post mechanism.
+
+public:
+  //! Constructor (wait on the associated Semaphore)
+  AutoSemaphore (Semaphore & _sem)
+    : m_sem (_sem)
+  {
+    m_sem.wait();
+  }
+
+  //! Destructor (post the associated Semaphore)
+  ~AutoSemaphore (void)
+  {
+    m_sem.post();
+  }
+
+private:
+  //! The associated Mutex
+  Semaphore & m_sem;
+
+  //! Not implemented private member
+  AutoSemaphore (const AutoSemaphore&);
+  //! Not implemented private member
+  AutoSemaphore & operator= (const AutoSemaphore&);
+};
+
+} // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/impl/PosixSemaphoreImpl.i"
+#endif
+
+#endif //- _BPM_SEMAPHORE_H_
diff --git a/src/threading/SharedObject.cpp b/src/threading/SharedObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ebee01cc55c13c9a460e573e3322667f3dcd645
--- /dev/null
+++ b/src/threading/SharedObject.cpp
@@ -0,0 +1,101 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/SharedObject.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/SharedObject.i"
+#endif
+
+namespace bpm
+{
+// ============================================================================
+// SharedObject::SharedObject
+// ============================================================================
+SharedObject::SharedObject (void) : reference_count_ (1)
+{
+  //- noop
+}
+
+// ============================================================================
+// SharedObject::~SharedObject
+// ============================================================================
+SharedObject::~SharedObject (void)
+{
+  //- check reference_count_ value
+  DEBUG_ASSERT(this->reference_count_ == 0);
+}
+
+// ============================================================================
+// SharedObject::duplicate
+// ============================================================================
+SharedObject *SharedObject::duplicate (void)
+{
+  AutoMutex<Mutex> guard (this->lock_);
+
+  this->reference_count_++;
+
+  return this;
+}
+
+// ============================================================================
+// SharedObject::release
+// ============================================================================
+void SharedObject::release (void)
+{
+  //- the try/catch block is a trick for embedded version...
+  try
+  {
+    if (this->release_i () == 0)
+      delete this;
+  }
+  catch (...)
+  {
+    //- ignore exception
+  }
+}
+
+// ============================================================================
+// SharedObject::release_i
+// ============================================================================
+SharedObject *SharedObject::release_i (void)
+{
+  AutoMutex<Mutex> guard (this->lock_);
+
+  DEBUG_ASSERT(this->reference_count_ > 0);
+
+  this->reference_count_--;
+
+  return (this->reference_count_ == 0) ? 0 : this;
+}
+
+} //- namespace bpm
diff --git a/src/threading/SharedObject.h b/src/threading/SharedObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..013366a403611e2aa754c405bb3976ba2a098fbf
--- /dev/null
+++ b/src/threading/SharedObject.h
@@ -0,0 +1,100 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _SHARED_OBJECT_H_
+#define _SHARED_OBJECT_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/Mutex.h"
+
+namespace bpm
+{
+
+// ============================================================================
+//! A reference counted object abstraction.
+// ============================================================================
+//!
+//! Base class for any reference counted object (i.e. shared) object.
+//!
+// ============================================================================
+class SharedObject
+{
+public:
+
+  SharedObject (void);
+  // Constructor.
+
+  virtual ~SharedObject (void);
+  // Destructor.
+
+  SharedObject *duplicate (void);
+  // Return a "shallow" copy. Increment the reference count by 1
+  // to avoid deep copies.
+
+  void release (void);
+  // Decrease the shared reference count by 1.  If the reference count
+  // equals 0, then delete <this> and return 0. Behavior is undefined
+  // if reference count < 0.
+
+  int reference_count (void) const;
+  // Returns the current reference count.
+
+  void lock (void);
+  // Gets exclusive access to the data.
+
+  void unlock (void);
+  // Release exclusive access to the data.
+
+protected:
+  // a mutex to protect the data against race conditions
+  bpm::Mutex lock_;
+
+private:
+  // internal release implementation
+  SharedObject * release_i (void);
+
+  //- reference count for (used to avoid deep copies)
+  int reference_count_;
+
+  // = Disallow these operations.
+  //--------------------------------------------
+  SharedObject & operator= (const SharedObject &);
+  SharedObject (const SharedObject &);
+};
+
+}  // namespace bpm
+
+#if defined (__INLINE_IMPL__)
+# include "threading/SharedObject.i"
+#endif 
+
+#endif // _SHARED_OBJECT_H_
diff --git a/src/threading/SharedObject.i b/src/threading/SharedObject.i
new file mode 100644
index 0000000000000000000000000000000000000000..7bcfed70b98c2bde2a934b8d30f670e516a66f55
--- /dev/null
+++ b/src/threading/SharedObject.i
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// SharedObject::lock
+// ============================================================================
+INLINE_IMPL void SharedObject::lock (void)
+{
+  this->lock_.acquire ();
+}
+
+// ============================================================================
+// SharedObject::unlock
+// ============================================================================
+INLINE_IMPL void SharedObject::unlock (void)
+{
+  this->lock_.release ();
+}
+
+}  // namespace bpm
diff --git a/src/threading/Task.cpp b/src/threading/Task.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4d81fcc59b272e8b0bb24ecf177cbe0c2010545
--- /dev/null
+++ b/src/threading/Task.cpp
@@ -0,0 +1,449 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr 
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "CommonHeader.h"
+#include "threading/Task.h"
+
+#if !defined (__INLINE_IMPL__)
+# include "threading/Task.i"
+#endif 
+
+namespace bpm
+{
+
+// ======================================================================
+// Task::Config::Config
+// ======================================================================
+ Task::Config::Config ()
+		: enable_timeout_msg (false),
+      timeout_msg_period_ms (0),
+      enable_periodic_msg (false),
+      periodic_msg_period_ms (0),
+      lock_msg_handling (false),
+      lo_wm (kDEFAULT_LO_WATER_MARK),
+      hi_wm (kDEFAULT_HI_WATER_MARK),
+      throw_on_post_tmo (false),
+      msg_handler (0),
+      user_data (0),
+      host_device (0)
+{
+  /* noop ctor */
+}
+
+// ======================================================================
+// Task::Config::Config
+// ======================================================================
+ Task::Config::Config (Tango::DeviceImpl * _hd,
+                       MessageHandler _msg_handler,
+		                   Thread::IOArg _user_data,
+                       bool   _enable_periodic_msg,
+                       size_t _periodic_msg_period_ms,
+		                   bool   _enable_timeout_msg,
+                       size_t _timeout_msg_period_ms,
+                       bool   _lock_msg_handling,
+                       size_t _lo_wm,
+                       size_t _hi_wm,
+                       bool   _throw_on_post_tmo)
+		: enable_timeout_msg (_enable_timeout_msg),
+      timeout_msg_period_ms (_timeout_msg_period_ms),
+      enable_periodic_msg (_enable_periodic_msg),
+      periodic_msg_period_ms (_periodic_msg_period_ms),
+      lock_msg_handling (_lock_msg_handling),
+      lo_wm (_lo_wm),
+      hi_wm (_hi_wm),
+      throw_on_post_tmo (_throw_on_post_tmo),
+      msg_handler (_msg_handler),
+      user_data (_user_data),
+      host_device (_hd)
+{
+  /* noop ctor */
+}
+
+// ======================================================================
+// Task::Task
+// ======================================================================
+Task::Task (const Task::Config& _cfg)
+  : Thread (_cfg.host_device),
+    msg_q_ (_cfg.lo_wm, _cfg.hi_wm, _cfg.throw_on_post_tmo),
+    timeout_msg_period_ms_ (_cfg.timeout_msg_period_ms),
+    periodic_msg_period_ms_ (_cfg.periodic_msg_period_ms),
+    user_data_ (_cfg.user_data),
+    lock_msg_handling_ (_cfg.lock_msg_handling),
+    henv_ (0),
+    hcon_ (0),
+    msg_handler_ (_cfg.msg_handler),
+    connected_ (false)  
+{
+  this->msg_q_.enable_timeout_msg(_cfg.enable_timeout_msg);
+  this->msg_q_.enable_periodic_msg(_cfg.periodic_msg_period_ms);
+}
+
+// ======================================================================
+// Task::~Task
+// ======================================================================
+Task::~Task (void)
+{
+  //- noop
+}
+  
+// ============================================================================
+// Task::go
+// ============================================================================
+void Task::go (size_t _tmo_ms) 
+  throw (Tango::DevFailed)
+{
+  this->start_undetached();
+
+  Message * msg = 0;
+  try
+  {
+    msg = bpm::Message::allocate(TASK_INIT, INIT_MSG_PRIORITY, true);
+  }
+  catch (Tango::DevFailed & ex)
+  {
+    Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"),
+                                    _CPTC("Message allocation failed"),
+                                    _CPTC("Task::go"));
+  }
+
+  this->wait_msg_handled (msg, _tmo_ms);
+}
+
+// ============================================================================
+// Task::go
+// ============================================================================
+void Task::go (Message * _msg, size_t _tmo_ms) 
+  throw (Tango::DevFailed)
+{
+  this->start_undetached();
+
+  if ( 
+         (_msg == 0)
+      || 
+         (_msg->type() != TASK_INIT)
+      ||
+         (_msg->waitable() == false)
+     )
+     Tango::Except::throw_exception (_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("invalid INIT message [null, wrong type or not waitable]"),
+                                     _CPTC("Task::go"));
+                                      
+  this->wait_msg_handled (_msg, _tmo_ms);
+}
+
+// ============================================================================
+// Task::run_undetached
+// ============================================================================
+void * Task::run_undetached (void *)
+{
+	//- init flag - set to true when TASK_INIT received
+	bool received_init_msg = false;
+
+	//- exit flag - set to true when TASK_EXIT received
+	bool received_exit_msg = false;
+
+	size_t msg_type;
+	Message * msg = 0;
+
+  //- actual tmo on msg waiting
+  size_t tmo = this->actual_timeout(); 
+
+	//- trick: avoid handling TIMEOUT messages before INIT is itself handled
+	//- may be the case for very short Task timeout
+	do
+	{
+		//- release any previously obtained msg
+		if (msg) msg->release();
+
+    //- get/wait next message from the msgQ
+		msg = this->msg_q_.next_message (tmo);
+	}
+	while (! msg || msg->type() != TASK_INIT);
+
+  //- TASK_INIT received
+  received_init_msg = true;
+    
+	//- enter thread's main loop 
+	while (! received_exit_msg)
+	{
+    //- actual tmo on msg waiting
+    tmo = this->actual_timeout();
+
+		//- get/wait next message from the msgQ
+		if (! msg)
+		{ 
+			do
+			{
+        //- get next message
+				msg = this->msg_q_.next_message (tmo);
+        //- do not handle TASK_INIT twice
+        if (msg && msg->type() == TASK_INIT && received_init_msg)
+        {
+          msg->release();
+          msg = 0;
+        }
+      }
+			while (! msg);
+		}
+
+		//- set msg user data
+		msg->user_data(this->user_data_);
+
+		//- we may need msg type after msg release
+		msg_type = msg->type();
+	        
+    //- got a valid message from message Q
+		try
+    {
+      //      std::cout << "Task::handling msg::"
+      //                << std::hex
+      //			  				<< long(msg)
+      //			  				<< std::dec
+      //			  				<< "::"
+      //			  				<< msg->to_string()
+      //			  				<< std::endl;
+			//- call message handler
+      if (this->lock_msg_handling_)
+		  { 
+        //- enter critical section 
+			  MutexLock guard (this->m_lock);
+        (this->msg_handler_)(*msg);
+			}
+      else
+      {
+        this->msg_handler_(*msg);
+      }
+    }
+		catch (const Tango::DevFailed& e)
+		{
+			//- store exception into the message
+      msg->set_error(e);
+		}
+		catch (...)
+		{
+      Tango::DevErrorList errors;
+		  errors.length(1);
+      errors[0].severity = Tango::ERR;
+      errors[0].reason = CORBA::string_dup("UNKNOWN_ERROR");
+      errors[0].origin = CORBA::string_dup("unknown error caught while handling msg");
+      errors[0].desc = CORBA::string_dup("Task::run_undetached");
+      msg->set_error(Tango::DevFailed(errors));
+		}
+    //	  std::cout << "Task::run_undetached::msg [" 
+    //    	        << std::hex 
+    //    	        << (void*)msg 
+    //    	        << std::dec 
+    //    	        << "] handled - notifying waiters"
+    //    	        << std::endl;
+    //- mark message as "processed" (this will signal waiters if any)
+    msg->processed();
+		//- release our msg ref 
+		msg->release();
+    //- abort requested?
+    if (msg_type == TASK_EXIT)
+    {
+	    //- close the msgQ
+	    this->msg_q_.close();
+	    //- mark TASK_EXIT as received (exit thread's main loop)
+	    received_exit_msg = true;
+    }
+		//- reset msg in order to get next msg from msgQ
+		msg = 0;
+  } //- thread's while loop
+
+	return 0;
+}
+
+// ======================================================================
+// Task::exit
+// ======================================================================
+void Task::exit (void)
+  throw (Tango::DevFailed)
+{
+  //- we may have to implicitly delete the thread
+  bool delete_self = false;
+
+  //- enter critical section
+  this->m_lock.lock();
+
+  //- get underlying thread state
+  Thread::State ts = this->state_i();
+
+	//- if the thread is running, then ask it to exit
+  if (ts == bpm::Thread::STATE_RUNNING)
+	{
+    bpm::Message * msg = 0;
+    try
+    {
+      msg = new Message(bpm::TASK_EXIT, EXIT_MSG_PRIORITY, true);
+    }
+    catch (Tango::DevFailed &ex)
+    {
+      this->m_lock.unlock();
+      Tango::Except::re_throw_exception (ex,
+                                         _CPTC("SOFTWARE_ERROR"),
+                                         _CPTC("Could not stop task [bpm::Message allocation failed]"),
+                                         _CPTC("Task::exit"));
+	  }
+    catch (...)
+    {
+      this->m_lock.unlock();
+      Tango::Except::throw_exception (_CPTC("UNKNOWN_ERROR"),
+                                      _CPTC("Could not stop task [bpm::Message allocation failed]"),
+                                      _CPTC("Task::exit"));
+	  }
+    //- unlock the thread lock (avoid deadlock during message handling)
+    this->m_lock.unlock();
+    try
+    {
+		  //- ... then wait for TASK_EXIT msg to be handled
+		  //- TODO: change kINFINITE_WAIT to a more flexible TIMEOUT
+		  // std::cout << "Task::exit - waiting for the TASK_EXIT msg to be handled" << std::endl;
+		  this->wait_msg_handled (msg, kINFINITE_WAIT);
+    }
+    catch (...)
+    {
+      //- ignore any error
+    }
+		//- wait for the thread to actually quit
+		try
+    {
+      Thread::IOArg dummy = 0;
+			// std::cout << "Task::exit - about to join with the underlying thread" << std::endl;
+		  this->join (&dummy);
+    }
+		catch (...)
+    {
+		 //- ignore any error
+    }
+  }
+  else if (ts == bpm::Thread::STATE_NEW) 
+  {
+    //- delete the thread (instanciated but never been started)
+	  // std::cout << "Task::exit - about to delete the thread [has never been started]" << std::endl;
+		delete_self = true;
+    //- leave critical section
+    this->m_lock.unlock();
+  }
+	else
+  {
+    //- nothing to do...
+	  // std::cout << "Task::exit - do nothing" << std::endl;
+    //- leave critical section
+    this->m_lock.unlock();
+  }
+
+  //- delete (if required)
+  if (delete_self)
+  {
+    // std::cout << "Task::exit - deleting <this> Task instance" << std::endl;
+    delete this;
+  }
+}
+
+// ======================================================================
+// Task::wait_msg_handled
+// ======================================================================
+void Task::wait_msg_handled (Message * _msg, size_t _tmo_ms)
+		 throw (Tango::DevFailed)
+{
+	//- check input
+	if (! _msg || ! _msg->waitable())	
+  {
+    Tango::Except::throw_exception (_CPTC("INVALID_ARGUMENT"),
+                                    _CPTC("invalid message [either null or not waitable]"),
+                                    _CPTC("Task::wait_msg_handled"));
+	}
+
+	try
+	{
+		//- post a shallow copy of the msg 
+		this->msg_q_.post(_msg->duplicate());
+	}
+	catch (...)
+	{
+		_msg->release();
+    Tango::Except::throw_exception (_CPTC("INTERNAL_ERROR"),
+                                    _CPTC("message could not be posted"),
+                                    _CPTC("Task::wait_msg_handled"));
+	}
+	
+  //	std::cout << "Task::wait_msg_handled::waiting for msg [" 
+  //	        << std::hex 
+  //	        << (void*)_msg 
+  //	        << std::dec 
+  //	        << "] to be handled"
+  //	        << std::endl;
+	
+	//- wait for the msg to be handled or tmo expiration
+	if (_msg->wait_processed(_tmo_ms))
+	{
+    //	  std::cout << "Task::wait_msg_handled::msg [" 
+    //	          << std::hex 
+    //	          << (void*)_msg 
+    //	          << std::dec 
+    //	          << "] handled [gave error::" 
+    //	          << (_msg->has_error() ? "yes" : "no")
+    //	          << "]"
+    //	          << std::endl;
+    Tango::DevFailed msg_exception;
+    bool msg_gave_error = _msg->has_error();
+    //- to store error localy before releasing msg
+	  if (msg_gave_error)
+      msg_exception = _msg->get_error();
+	  //- release msg
+		_msg->release();
+		//- throw an exception if msg gave error
+		if (msg_gave_error)
+	    throw msg_exception;
+		//- msg did not gave error, just return
+		return;
+	}
+
+	//- too bad, timeout expired...
+  //  std::cout << "Task::wait_msg_handled::timeout expired while waiting for msg [" 
+  //	        << std::hex 
+  //	        << (void*)_msg 
+  //	        << std::dec 
+  //	        << "] to be handled"
+  //	        << std::endl;
+	          
+	//- release msg
+	_msg->release();
+
+	//- throw timeout exception
+  Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"),
+                                  _CPTC ("timeout expired while waiting for message to be handled"),
+                                  _CPTC ("Task::wait_msg_handled"));
+}
+
+} // namespace
diff --git a/src/threading/Task.h b/src/threading/Task.h
new file mode 100644
index 0000000000000000000000000000000000000000..4eafde9992efbe59f13a235fb90574c38ce8c81e
--- /dev/null
+++ b/src/threading/Task.h
@@ -0,0 +1,205 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_TASK_H_
+#define _BPM_TASK_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Thread.h"
+#include "threading/MessageQ.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define kDEFAULT_TASK_TMO_MSECS         5000
+#define kDEFAULT_THD_PERIODIC_TMO_MSECS 1000
+//-----------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// class: Task
+// ============================================================================
+class Task : public bpm::Thread
+{
+  friend class BPM;
+  
+public:
+
+  //-define what a msg handler is
+  typedef void (*MessageHandler) (const bpm::Message&);
+  
+  //! yat::Task configuration class
+	class Config
+	{
+	public:
+    //- enable TIMEOUT messages
+		bool enable_timeout_msg;
+		//- timeout msg period in msec
+		size_t timeout_msg_period_ms;
+    //- enable PERIODIC messages
+		bool enable_periodic_msg;
+		//- periodic msg period in msec
+		size_t periodic_msg_period_ms;
+		//- should we process msg under critical section?
+		bool lock_msg_handling;
+    //- msgQ low water mark
+    size_t lo_wm;
+    //- msgQ high water mark
+    size_t hi_wm;
+    //- throw exception on post message timeout
+    bool throw_on_post_tmo;
+    //- msg handler
+    MessageHandler msg_handler;
+		//- user data (passed back in all msg)
+    Thread::IOArg user_data;
+    //- host TANGO device
+    Tango::DeviceImpl * host_device;
+    
+    //- default ctor
+		Config ();
+		
+    //- ctor
+		Config (Tango::DeviceImpl * hd, 
+		        MessageHandler msg_handler,
+		        Thread::IOArg user_data = 0,
+            bool   enable_periodic_msg = false,
+            size_t periodic_msg_period_ms = 0,
+		        bool   enable_timeout_msg = false,
+            size_t timeout_msg_period_ms = 0,
+            bool   lock_msg_handling = false,
+            size_t lo_wm = kDEFAULT_LO_WATER_MARK,
+            size_t hi_wm = kDEFAULT_HI_WATER_MARK,
+            bool   throw_on_post_tmo = true);
+	};
+
+  //- ctor
+	Task (const Config& cfg);
+
+	//- dtor
+	virtual ~Task (void);
+
+	//- starts the task
+  void go (size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+    throw (Tango::DevFailed);
+
+ 	//- starts the task 
+  //- an exception is thrown otherwise in case the specified message:
+  //-   * is not of type TASK_INIT
+  //-   * is not "waitable"
+  void go (Message * msg, size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+    throw (Tango::DevFailed);
+
+	//! Abort the task (join with the underlying thread before returning).
+  //! Provides an implementation to the Thread::exit pure virtual method.
+  virtual void exit (void)
+    throw (Tango::DevFailed);
+
+  //- posts a message to the task
+	void post (Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO)
+		throw (Tango::DevFailed);
+
+  //- post a CSPI event to the task
+  void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO)
+    throw (Tango::DevFailed);
+    
+	//- wait for a msg to be handled
+	void wait_msg_handled (Message * msg, size_t tmo_ms = kDEFAULT_MSG_TMO_MSECS)
+		throw (Tango::DevFailed);
+
+	//- timeout msg period mutator
+	void set_timeout_msg_period (size_t p_msecs);
+	
+	//- periodic msg period accessor
+	size_t get_timeout_msg_period (void) const;
+	
+	//- enable/disable timeout messages
+	void enable_timeout_msg (bool enable);
+
+	//- returns timeout messages handling status
+	bool timeout_msg_enabled (void) const;
+
+	//- periodic msg period mutator
+	void set_periodic_msg_period (size_t p_msecs);
+	
+	//- periodic msg period accessor
+	size_t get_periodic_msg_period (void) const;
+
+  //- enable/disable periodic messages
+	void enable_periodic_msg (bool enable);
+
+	//- returns period messages handling status
+	bool periodic_msg_enabled (void) const;
+
+protected:
+	//- run_undetached
+  virtual Thread::IOArg run_undetached (Thread::IOArg);
+
+private:
+	//- actual_timeout
+  size_t actual_timeout (void) const;
+
+	//- the associated messageQ
+	MessageQ msg_q_;
+
+	//- timeout msg period
+	size_t timeout_msg_period_ms_;
+
+	//- periodic msg period 
+  size_t periodic_msg_period_ms_;
+
+	//- user data 
+	Thread::IOArg user_data_;
+
+  //- should we process msg under critical section?
+  bool lock_msg_handling_;
+
+  //- the CSPI env. handle
+  CSPIHENV henv_;
+
+  //- the CSPI con. handle
+  CSPIHCON hcon_;
+  
+  //- the message handler entry point
+  MessageHandler msg_handler_;
+  
+  //- connection flag: true if connected to the Libera, false ortherwise 
+  bool connected_;
+};
+
+} // namespace 
+
+#if defined (__INLINE_IMPL__)
+# include <threading/Task.i>
+#endif
+
+#endif // _BPM_TASK_H_
diff --git a/src/threading/Task.i b/src/threading/Task.i
new file mode 100644
index 0000000000000000000000000000000000000000..9420c4777e72f0991364932193fae805c0ea294a
--- /dev/null
+++ b/src/threading/Task.i
@@ -0,0 +1,127 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm
+{
+
+// ============================================================================
+// Task::enable_timeout_msg
+// ============================================================================
+INLINE_IMPL void Task::enable_timeout_msg (bool b)
+{
+  this->msg_q_.enable_timeout_msg(b);
+}
+
+// ============================================================================
+// Task::timeout_msg_enabled
+// ============================================================================
+INLINE_IMPL bool Task::timeout_msg_enabled (void) const
+{
+  return this->msg_q_.timeout_msg_enabled();
+}
+
+// ============================================================================
+// Task::set_timeout_msg_period
+// ============================================================================
+INLINE_IMPL void Task::set_timeout_msg_period (size_t _tmo)
+{
+  this->timeout_msg_period_ms_ = _tmo;
+}
+
+// ============================================================================
+// Task::get_timeout_msg_period
+// ============================================================================
+INLINE_IMPL size_t Task::get_timeout_msg_period (void) const
+{
+  return this->timeout_msg_period_ms_;
+}
+
+// ============================================================================
+// Task::enable_periodic_msg
+// ============================================================================
+INLINE_IMPL void Task::enable_periodic_msg (bool b)
+{
+  this->msg_q_.enable_periodic_msg(b);
+}
+
+// ============================================================================
+// Task::periodic_msg_enabled
+// ============================================================================
+INLINE_IMPL bool Task::periodic_msg_enabled (void) const
+{
+  return this->msg_q_.periodic_msg_enabled();
+}
+
+// ============================================================================
+// Task::set_periodic_timeout
+// ============================================================================
+INLINE_IMPL void Task::set_periodic_msg_period (size_t _tmo)
+{
+  this->periodic_msg_period_ms_ = _tmo;
+}
+
+// ============================================================================
+// Task::get_timeout_msg_period
+// ============================================================================
+INLINE_IMPL size_t Task::get_periodic_msg_period (void) const
+{
+  return this->periodic_msg_period_ms_;
+}
+
+// ============================================================================
+// Task::actual_timeout_msg_period
+// ============================================================================
+INLINE_IMPL size_t Task::actual_timeout (void) const
+{
+  if (this->msg_q_.enable_periodic_msg_ && this->periodic_msg_period_ms_)
+    return this->periodic_msg_period_ms_;
+  if (this->msg_q_.enable_timeout_msg_ && this->timeout_msg_period_ms_)
+    return this->timeout_msg_period_ms_;
+  return kDEFAULT_TASK_TMO_MSECS;
+}
+
+// ============================================================================
+// Task::post
+// ============================================================================
+INLINE_IMPL void Task::post (bpm::Message * _msg, size_t _tmo_msecs) 
+	throw (Tango::DevFailed)
+{
+  this->msg_q_.post (_msg, _tmo_msecs);
+}
+
+// ============================================================================
+// Thread::post
+// ============================================================================
+INLINE_IMPL void Task::post (CSPI_EVENT * evt, size_t _tmo_msecs)  
+  throw (Tango::DevFailed)
+{
+  this->msg_q_.post(evt, _tmo_msecs);
+}
+
+} //- namespace bpm
diff --git a/src/threading/Thread.h b/src/threading/Thread.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d9287c627cec0ea62ca1daecac774d6104c12c9
--- /dev/null
+++ b/src/threading/Thread.h
@@ -0,0 +1,207 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _BPM_THREAD_H_
+#define _BPM_THREAD_H_
+
+// ----------------------------------------------------------------------------
+// DEPENDENCIES
+// ----------------------------------------------------------------------------
+#include "threading/Mutex.h"
+
+// ----------------------------------------------------------------------------
+// Implementation-specific header file.
+// ----------------------------------------------------------------------------
+#if ! defined(__THREAD_IMPLEMENTATION)
+# error "implementation header file incomplete [no thread implementation]"
+#endif
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+//! The bpm Thread abstract class
+// ----------------------------------------------------------------------------
+class Thread : public Tango::LogAdapter
+{
+  //! This abstract class can't be used as this and must be derived.
+  //! Provides both "detached" and "undetached" (i.e. joinable) behaviour.
+
+public:
+  //! A dedicated type for thread entry point argument (user specified data).
+  typedef void * IOArg;
+
+  //! The possible thread priorities (default is NORMAL).
+  //! Be aware that setting the thread priority to HIGH or RT may 
+  //! prevent other threads from running (CPU starvation).
+  enum Priority
+  {
+	  PRIORITY_LOW,
+	  PRIORITY_NORMAL,
+	  PRIORITY_HIGH,
+    PRIORITY_RT
+  };
+
+  //! The possible thread states
+  enum State
+  {
+  	//! Thread object exists but thread hasn't started yet.
+  	//! In this state, the thread UID (identifier) is undefined.
+	  STATE_NEW,
+    //! Thread is running.
+	  STATE_RUNNING,
+    //! Thread has terminated but storage has not been reclaimed (i.e. waiting to be joined).
+    STATE_TERMINATED
+  };
+
+	//! Returns the the thread unique indentifier.
+	//! In case the thread is not yet running (THREAD_STATE_NEW), self will returns
+	//! YAT_INVALID_THREAD_UID (since the thread UID is not defined in this state).
+  ThreadUID self (void) const;
+
+	//! Set the priority of the thread.
+	//! In case the thread is running, the priority is immediately applied.
+	void priority (Priority p)
+    throw (Tango::DevFailed);
+
+	//! Returns the current priority of the thread.
+  Thread::Priority priority (void);
+
+ 	//! Returns the current state of the thread.
+  //! \remarks Locks the associated Mutex (\c m_lock)
+  Thread::State state (void);
+
+ 	//! This pure virtual member _must_ cause the "run" (for detached threads)
+  //! or "run_undetached" (for undetached threads) to return. In other words,
+  //! exit _must_ make the thread quit its "infinite loop" and quit. Its
+  //! content in purely application dependent - that's why the actual
+  //! implementation is delegated to the derived class.
+  virtual void exit (void) = 0;
+
+	//! Returns the associated mutex
+  Mutex & lock (void);
+  
+	//! Allows another thread to run.
+  static void yield (void);
+
+	//! Causes the thread to sleep for the given time.
+  static void sleep (unsigned long msecs);
+  
+protected:
+	//! This constructor is used in a derived class.  The thread will
+	//! execute the run() or run_undetached() member functions depending on
+	//! whether start() or start_undetached() is called respectively.
+  Thread (Tango::DeviceImpl * hd, 
+          IOArg a = 0, 
+          Priority p = bpm::Thread::PRIORITY_NORMAL);
+
+ 	//! Causes the thread to be detached.  
+  //! In this case the thread executes the run member function.
+  void start (void)
+    throw (Tango::DevFailed);
+
+ 	//! Causes the thread to be undetached.
+  //! In this case the thread executes the run_undetached member function.
+  void start_undetached (void)
+    throw (Tango::DevFailed);
+
+	//! Join causes the calling thread to wait for another's completion,
+	//! putting the return value in the variable of type IOArg whose address
+	//! is given (unless passed a null pointer). Only undetached threads
+	//! may be joined. Storage for the thread will be reclaimed. May throw an 
+  //! exception in case the thread is either "not running" or "terminated".
+  //! An exception will also be thrown in case the thread is "detached" or
+  //! in case the underlying OS "wait for the thread to terminate" call fails.
+  void join (Thread::IOArg *)
+    throw (Tango::DevFailed);
+
+	//! The Thread destructor cannot be called by user (except via a derived class).
+	//! Use exit() instead. This also means a thread object must be allocated with
+  //! new - it cannot be statically or automatically allocated. The destructor of
+  //! a class that inherits from omni_thread shouldn't be public either (otherwise 
+  //! the thread object can be destroyed while the underlying thread is still running).
+  virtual ~Thread (void);
+
+	//! Default implementation of the run method (detached thread).
+	//! Should be overridden in a derived class. Called by start()
+  virtual void run (Thread::IOArg)
+  {
+    //- noop
+    DEBUG_ASSERT(true);
+  }
+
+	//! Default implementation of the run_undetached method (undetached thread).
+	//! Should be overridden in a derived class. Called by start_undetached()
+  virtual IOArg run_undetached (Thread::IOArg)
+  {
+    DEBUG_ASSERT(true);
+    return 0;
+  }
+
+  //! The following mutex is used to protect any members which can change
+  //! after construction (such as m_state, m_priority, ...)
+  bpm::Mutex m_lock;
+
+ 	//! Returns the current state of the thread.
+  //! \remarks Does not lock the associated Mutex (\c m_lock)
+  Thread::State state_i (void) const;
+
+private:
+  //! The current TState of the thread.
+  State m_state;
+
+  //! The current TPriority of the thread.
+  Priority m_priority;
+
+  //! The thread input argument
+  Thread::IOArg  m_iarg;
+
+  //! The thread returned value
+  Thread::IOArg  m_oarg;
+
+  //! Detached/undetached flag
+  bool m_detached;
+
+  //! The thread identifier
+  ThreadUID m_uid;
+
+  //! Not implemented private members
+  Thread (const Thread&);
+  Thread & operator= (const Thread&);
+
+  //- platform specific implementation
+  __THREAD_IMPLEMENTATION;
+};
+
+} // namespace bpm 
+
+#if defined (__INLINE_IMPL__)
+#  include "threading/impl/PosixThreadImpl.i"
+#endif
+
+#endif //- _BPM_THREAD_H_
diff --git a/src/threading/Utilities.h b/src/threading/Utilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..8624e49694e2bb9f622b4518aeea7ebca72e3ac3
--- /dev/null
+++ b/src/threading/Utilities.h
@@ -0,0 +1,79 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+
+#ifndef _BPM_THREADING_UTILS_H_
+#define _BPM_THREADING_UTILS_H_
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include "threading/Implementation.h"
+
+// ============================================================================
+// CONSTs
+// ============================================================================
+#define BPM_INVALID_THREAD_UID 0xffffffff
+
+namespace bpm {
+
+// ============================================================================
+//! A dedicated type for thread identifier
+// ============================================================================
+typedef unsigned long ThreadUID;
+
+// ============================================================================
+//! The BPM threading utilities
+// ============================================================================
+class ThreadingUtilities
+{
+public:
+ 	//! Returns the calling thread identifier.
+  static ThreadUID self (void);
+
+	//! Causes the caller to sleep for the given time.
+  static void sleep (unsigned long secs, unsigned long nanosecs = 0);
+
+	//! Calculates an absolute time in seconds and nanoseconds, suitable for
+	//! use in timed_waits, which is the current time plus the given relative 
+  //! offset.
+  static void get_time (unsigned long & abs_sec,
+                        unsigned long & abs_nsec,
+			                  unsigned long offset_sec = 0,
+                        unsigned long offset_nsec = 0);
+  
+	//! Calculates an absolute time in seconds and nanoseconds, suitable for
+	//! use in timed_waits, which is the current time plus the given relative 
+  //! offset. WORKS ONLY FOR <delay_msecs> < 1 SECS. 
+  static void get_time (unsigned long delay_msecs, Timespec& abs_time);
+};
+
+} // namespace bpm 
+
+#endif //- _BPM_THREADING_UTILS_H_
diff --git a/src/threading/impl/PosixConditionImpl.i b/src/threading/impl/PosixConditionImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..d7ad8805938dd0a11c04407171d572d87ad5270d
--- /dev/null
+++ b/src/threading/impl/PosixConditionImpl.i
@@ -0,0 +1,56 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Condition::wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::wait (void)
+{
+  this->timed_wait(0);
+}
+
+// ----------------------------------------------------------------------------
+// Condition::signal
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::signal (void)
+{
+  ::pthread_cond_signal(&m_posix_cond);
+}
+
+// ----------------------------------------------------------------------------
+// Condition::broadcast
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Condition::broadcast (void)
+{
+  ::pthread_cond_broadcast(&m_posix_cond);
+}
+
+} // namespace bpm
diff --git a/src/threading/impl/PosixMutexImpl.i b/src/threading/impl/PosixMutexImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..b69da52438c114c889131475404ce8bde74e7503
--- /dev/null
+++ b/src/threading/impl/PosixMutexImpl.i
@@ -0,0 +1,138 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ****************************************************************************
+// BPM NULL MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// NullMutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::lock (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::acquire (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::unlock (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::release
+// ----------------------------------------------------------------------------
+INLINE_IMPL void NullMutex::release (void)
+{
+ //- noop
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState NullMutex::try_lock (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ----------------------------------------------------------------------------
+// NullMutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState NullMutex::try_acquire (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ****************************************************************************
+// BPM MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Mutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::lock (void)
+{
+  ::pthread_mutex_lock(&m_posix_mux);
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::acquire (void)
+{
+  this->lock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState Mutex::try_acquire (void)
+{
+  return this->try_lock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::unlock (void)
+{
+  ::pthread_mutex_unlock(&m_posix_mux);
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::release (void)
+{
+  this->unlock();
+}
+
+// ----------------------------------------------------------------------------
+// Mutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState Mutex::try_lock (void)
+{
+  MutexState result = MUTEX_LOCKED;
+
+  if (::pthread_mutex_trylock (&m_posix_mux) != 0)
+    result = MUTEX_BUSY;
+
+  return result;
+}
+
+} // namespace bpm
diff --git a/src/threading/impl/PosixSemaphoreImpl.i b/src/threading/impl/PosixSemaphoreImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..2bf16953eb84e15ef1fc082bec54933b272d8761
--- /dev/null
+++ b/src/threading/impl/PosixSemaphoreImpl.i
@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Semaphore::wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Semaphore::wait (void)
+{
+  this->timed_wait(0);
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::timed_wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL bool Semaphore::timed_wait (unsigned long _tmo_msecs)
+{
+  bool r = false;
+  this->m_mux.lock();
+  while (! this->m_value)
+  {
+    r = this->m_cond.timed_wait(_tmo_msecs);
+  }
+  if (r)
+  {
+    this->m_value--;
+  }
+  this->m_mux.unlock();
+  return r;
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::try_wait
+// ----------------------------------------------------------------------------
+INLINE_IMPL SemaphoreState Semaphore::try_wait (void)
+{
+  SemaphoreState s;
+  this->m_mux.lock();
+  if (this->m_value > 0)
+  {
+    this->m_value--;
+    s = SEMAPHORE_DEC;
+ 	}
+	else
+	{
+	  s = SEMAPHORE_NO_RSC;
+	}
+  this->m_mux.unlock();
+  return s;
+}
+
+// ----------------------------------------------------------------------------
+// Semaphore::post
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Semaphore::post (void)
+{
+  this->m_mux.lock();
+  this->m_value++;
+  this->m_cond.signal();
+  this->m_mux.unlock();
+}
+
+} // namespace bpm
diff --git a/src/threading/impl/PosixThreadImpl.i b/src/threading/impl/PosixThreadImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..a7a912dd3c34d0db2c8f86ceaf564ed0d38f17b8
--- /dev/null
+++ b/src/threading/impl/PosixThreadImpl.i
@@ -0,0 +1,104 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ----------------------------------------------------------------------------
+// Thread::priority
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::Priority Thread::priority (void)
+{
+  //- enter critical section
+  bpm::MutexLock guard(this->m_lock);
+
+  return this->m_priority;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::State Thread::state (void)
+{
+  //- enter critical section
+  bpm::MutexLock guard(this->m_lock);
+
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::State Thread::state_i (void) const
+{
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::yield
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::yield (void)
+{
+  ::sched_yield();
+}
+// ----------------------------------------------------------------------------
+// Thread::sleep
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::sleep (unsigned long _msecs)
+{
+#define kNSECS_PER_SEC  1000000000
+#define kNSECS_PER_MSEC 1000000
+
+  unsigned long secs = 0;
+  unsigned long nanosecs = kNSECS_PER_MSEC * _msecs;
+
+	while (nanosecs >= kNSECS_PER_SEC)
+	{
+		secs += 1;
+		nanosecs -= kNSECS_PER_SEC;
+	}
+
+  ThreadingUtilities::sleep(secs, nanosecs);
+
+#undef kNSECS_PER_MSEC
+#undef kNSECS_PER_SEC
+}
+// ----------------------------------------------------------------------------
+// Thread::self
+// ----------------------------------------------------------------------------
+INLINE_IMPL ThreadUID Thread::self (void) const
+{
+  return this->m_uid;
+}
+
+// ----------------------------------------------------------------------------
+// Thread::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL Mutex & Thread::lock (void)
+{
+  return this->m_lock;
+}
+  
+} // namespace bpm
diff --git a/src/threading/impl/PosixThreadingImpl.cpp b/src/threading/impl/PosixThreadingImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9475a7887d83c1799ff6eb2a12c3b314b067accd
--- /dev/null
+++ b/src/threading/impl/PosixThreadingImpl.cpp
@@ -0,0 +1,561 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <errno.h>
+#include <sys/time.h>
+#include "CommonHeader.h"
+#include "threading/Utilities.h"
+#include "threading/Mutex.h"
+#include "threading/Condition.h"
+#include "threading/Semaphore.h"
+#include "threading/Thread.h"
+
+#if ! defined (__INLINE_IMPL__)
+# include "threading/impl/PosixMutexImpl.i"
+# include "threading/impl/PosixConditionImpl.i"
+# include "threading/impl/PosixSemaphoreImpl.i"
+# include "threading/impl/PosixThreadImpl.i"
+#endif
+
+// ============================================================================
+// SOME PSEUDO CONSTs
+// ============================================================================
+#define MAX_SLEEP_SECONDS (long)4294966	//- this is (2^32 - 2) / 1000 
+#define NANOSECS_PER_SEC  1000000000L
+#define ONE_SEC_IN_MSECS  1000L
+
+// ============================================================================
+// PLATFORM SPECIFIC THREAD PRIORITIES
+// ============================================================================
+#if defined(HAS_THREAD_PRIORITY)
+ static int lowest_priority;
+ static int normal_priority;
+ static int highest_priority;
+#endif
+
+namespace bpm {
+
+// ****************************************************************************
+// BPM DUMMY_MUTEX IMPL
+// ****************************************************************************
+// ============================================================================
+// NullMutex::NullMutex
+// ============================================================================
+NullMutex::NullMutex (void)
+{
+ //- noop
+}
+// ============================================================================
+// NullMutex::~NullMutex
+// ============================================================================
+NullMutex::~NullMutex (void)
+{
+ //- noop
+}
+
+// ****************************************************************************
+// BPM MUTEX IMPL
+// ****************************************************************************
+// ============================================================================
+// Mutex::Mutex
+// ============================================================================
+Mutex::Mutex (void)
+  : m_posix_mux ()
+{
+  pthread_mutexattr_t ma;
+  ::pthread_mutexattr_init(&ma);
+  ::pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  ::pthread_mutex_init(&m_posix_mux, &ma);
+  ::pthread_mutexattr_destroy(&ma);
+}
+
+// ============================================================================
+// Mutex::~Mutex
+// ============================================================================
+Mutex::~Mutex(void)
+{
+  ::pthread_mutex_destroy(&m_posix_mux);
+}
+
+// ****************************************************************************
+// BPM SEMAPHORE IMPL
+// ****************************************************************************
+#define SEMAPHORE_MAX_COUNT 0x7fffffff
+
+// ============================================================================
+// Semaphore::Semaphore
+// ============================================================================
+Semaphore::Semaphore (unsigned int _initial_value)
+  : m_mux () , m_cond (m_mux), m_value (_initial_value)
+{
+  //- noop
+}
+
+// ============================================================================
+// Semaphore::~Semaphore
+// ============================================================================
+Semaphore::~Semaphore(void)
+{
+  //- noop
+}
+
+// ****************************************************************************
+// BPM CONDITION IMPL
+// ****************************************************************************
+// ============================================================================
+// Condition::Condition
+// ============================================================================
+Condition::Condition (Mutex & external_lock)
+ : m_external_lock (external_lock),
+   m_posix_cond ()
+{
+  ::pthread_cond_init(&m_posix_cond, 0);
+}
+
+// ============================================================================
+// Condition::~Condition
+// ============================================================================
+Condition::~Condition (void)
+{
+  ::pthread_cond_destroy(&m_posix_cond);
+}
+
+// ============================================================================
+// Condition::timed_wait
+// ============================================================================
+bool Condition::timed_wait (unsigned long _tmo_msecs)
+{
+  //- null tmo means infinite wait
+
+  bool signaled = true;
+ 
+	if (_tmo_msecs <= 0) 
+  {
+    ::pthread_cond_wait(&m_posix_cond, &m_external_lock.m_posix_mux);
+  }
+	else 
+  {
+		//- get absoulte time
+		struct timespec ts;
+		ThreadingUtilities::get_time(_tmo_msecs, ts);
+		
+    //- wait for the condition to be signaled or tmo expiration
+		int result = ::pthread_cond_timedwait(&m_posix_cond, 
+                                          &m_external_lock.m_posix_mux, 
+                                          &ts);
+                                          
+    if (result == ETIMEDOUT || result == EINTR)
+      signaled = false;
+      
+    /*
+    switch (result)
+    { 
+      case 0:
+        std::cout << "Condition::pthread_cond_timedwait returned: SUCCESS" << std::endl;
+        break;
+      case ETIMEDOUT:
+        std::cout << "Condition::pthread_cond_timedwait returned: ETIMEDOUT" << std::endl;
+        break;      
+      case EINTR:
+        std::cout << "Condition::pthread_cond_timedwait returned: EINTR" << std::endl;
+        break;
+    }
+    */
+	}
+
+  return signaled;
+}
+
+// ****************************************************************************
+// BPM THREAD IMPL
+// ****************************************************************************
+// ============================================================================
+// BPM common thread entry point (non-OO OS intertace to OO BPM interface)
+// ============================================================================
+Thread::IOArg bpm_thread_common_entry_point (Thread::IOArg _p)
+{
+  //- check input (parano. impl.)
+  if (! _p) return 0;
+
+  //- reinterpret input
+  Thread * me = reinterpret_cast<Thread*>(_p);
+
+  //- store the thread identifier
+  me->m_uid = ThreadingUtilities::self();
+
+  //- select detached or undetached mode
+  if (me->m_detached)
+  {
+    //- just protect bpm impl. against user code using a try/catch statement
+    try
+    {
+	    me->run(me->m_iarg);
+    }
+    catch (...)
+    {
+      //- ignore any exception
+    }
+  }
+  else 
+  {
+    //- just protect bpm impl. against user code using a try/catch statement
+    try
+    {
+	    me->m_oarg = me->run_undetached(me->m_iarg);
+    }
+    catch (...)
+    {
+      //- ignore any exception
+
+    }
+  }
+
+  //- set state to terminated
+  {
+    //- must lock the mutex even in the case of a detached thread. This is because
+    //- a thread may run to completion before the thread that created it has had a
+    //- chance to get out of start().  By locking the mutex we ensure that the
+    //- creating thread must have reached the end of start() before we delete the
+    //- thread object.  Of course, once the call to start() returns, the user can
+    //- still incorrectly refer to the thread object, but that's his problem!
+	  AutoMutex<Mutex> guard(me->m_lock);
+    //- set state to TERMINATED
+    me->m_state = bpm::Thread::STATE_TERMINATED;
+  }
+
+  //- commit suicide in case the thread ran detached
+	if (me->m_detached)
+    delete me;
+
+  return 0;
+}
+
+// ============================================================================
+// Thread::Thread
+// ============================================================================
+Thread::Thread (Tango::DeviceImpl * hd, Thread::IOArg _iarg, Thread::Priority _p)
+ : Tango::LogAdapter (hd),
+   m_state (bpm::Thread::STATE_NEW),
+   m_priority (_p),
+   m_iarg (_iarg),
+   m_oarg (0),
+   m_detached (true),
+   m_uid (BPM_INVALID_THREAD_UID),
+   //- platform specific members
+   m_posix_thread (0)
+{
+#if defined(HAS_THREAD_PRIORITY)
+ static bool init_done = false;
+ if (! init_done)
+ {
+   lowest_priority = ::sched_get_priority_min(SCHED_FIFO);
+   highest_priority = ::sched_get_priority_max(SCHED_FIFO);
+   switch (highest_priority - lowest_priority) 
+   {
+     case 0:
+     case 1:
+       normal_priority = lowest_priority;
+       break;
+     default:
+       normal_priority = lowest_priority + 1;
+       break;
+   }
+   init_done = true;
+ }
+#endif
+}
+
+// ============================================================================
+// Thread::~Thread
+// ============================================================================
+Thread::~Thread (void)
+{
+  //- noop
+}
+
+// ============================================================================
+// Thread::start [detatched thread]
+// ============================================================================
+void Thread::start (void) 
+  throw (Tango::DevFailed)
+{
+  //- mark the thread as detached
+  this->m_detached = true;
+  //- then spawn it
+  this->spawn();
+}
+
+// ============================================================================
+// Thread::start_undetached [undetatched thread]
+// ============================================================================
+void Thread::start_undetached (void)
+  throw (Tango::DevFailed)
+{
+  //- mark the thread as undetached
+  this->m_detached = false;
+  //- then spawn it
+  this->spawn();
+}
+
+// ============================================================================
+// Thread::spawn (common to detatched & undetached threads)
+// ============================================================================
+void Thread::spawn (void) 
+  throw (Tango::DevFailed)
+{
+  //- enter critical section
+  AutoMutex<Mutex> guard(this->m_lock);
+
+  //- be sure the thread is not already running or terminated
+  if (this->m_state != bpm::Thread::STATE_NEW)
+	  return;
+
+  //- intialize thread attributes
+  pthread_attr_t thread_attrs;
+
+  ::pthread_attr_init(&thread_attrs);
+
+  //- set detach attribute
+  int ds = this->m_detached 
+         ? PTHREAD_CREATE_DETACHED 
+         : PTHREAD_CREATE_JOINABLE;
+  ::pthread_attr_setdetachstate(&thread_attrs, ds);
+
+  //- set thread priority
+#if defined(HAS_THREAD_PRIORITY)
+  struct sched_param sp;
+  sp.sched_priority = bpm_to_posix_priority(m_priority);
+  ::pthread_attr_setschedparam(&thread_attrs, &sp));
+#endif
+
+  //- spawn the thread
+  int result = 0;
+  result = ::pthread_create(&m_posix_thread, 
+                            &thread_attrs, 
+                            bpm_thread_common_entry_point, 
+                            static_cast<void*>(this));
+  ::pthread_attr_destroy(&thread_attrs);
+
+  //- check result
+  if (result)
+    Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                   _CPTC("system call <pthread_create> failed"),
+                                   _CPTC("Thread::spawn"));
+
+  //- mark the thread as running (before leaving the critical section)
+  this->m_state = bpm::Thread::STATE_RUNNING;
+}
+
+// ============================================================================
+// Thread::join
+// ============================================================================
+void Thread::join (Thread::IOArg * oarg_)
+  throw (Tango::DevFailed)
+{
+  {
+    //- enter critical section
+    AutoMutex<Mutex> guard(this->m_lock);
+
+    //- check thread state
+    if (   
+           (this->m_state != bpm::Thread::STATE_RUNNING) 
+        && 
+           (this->m_state != bpm::Thread::STATE_TERMINATED)
+       )
+      Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("can't join [thread never started or already terminated]"),
+                                     _CPTC("Thread::join"));
+  }
+
+  //- be sure the thread is not detached
+  if (this->m_detached)
+      Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"),
+                                     _CPTC("can't join with a detached thread"),
+                                     _CPTC("Thread::join"));
+
+  if (::pthread_join(m_posix_thread, 0))
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("system call <pthread_join> failed"),
+                                     _CPTC("Thread::join"));
+
+  //- return the "thread result"
+  if (oarg_)
+    *oarg_ = this->m_oarg;
+
+  //- commit suicide
+  delete this;
+}
+
+// ============================================================================
+// Thread::priority
+// ============================================================================
+void Thread::priority (Priority _p)
+  throw (Tango::DevFailed)
+{
+  //- enter critical section
+  AutoMutex<Mutex> guard(this->m_lock);
+  
+  //- check thread state
+  if (this->m_state != bpm::Thread::STATE_RUNNING)
+    return; //- throw exception 
+
+#if defined(HAS_THREAD_PRIORITY)
+    struct sched_param sp;
+    sp.sched_priority = this->bpm_to_posix_priority(_p);
+    if (::pthread_setschedparam(m_posix_thread, SCHED_OTHER, &sp))
+      Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"),
+                                     _CPTC("system call <pthread_setschedparam> failed"),
+                                     _CPTC("Thread::priority"));
+#endif
+
+  //- store new priority
+  this->m_priority = _p;
+}
+
+// ============================================================================
+// Thread::bpm_to_posix_priority
+// ============================================================================
+int Thread::bpm_to_posix_priority (Priority _p)
+{
+#if defined(HAS_THREAD_PRIORITY)
+  switch (_p) 
+  {
+    case bpm::Thread::PRIORITY_LOW:
+	    return lowest_priority;
+      break;
+    case bpm::Thread::PRIORITY_HIGH:
+      return highest_priority;
+      break;
+    case bpm::Thread::PRIORITY_RT:
+      return highest_priority;
+      break;
+    default:
+	    return normal_priority;
+  }
+#else
+  switch (_p) 
+  {
+    default:
+			return 0;
+  } 
+#endif
+}
+
+
+// ============================================================================
+// ThreadingUtilities::self
+// ============================================================================
+ThreadUID ThreadingUtilities::self (void)
+{
+  return static_cast<bpm::ThreadUID>(::pthread_self());
+}
+
+// ============================================================================
+// ThreadingUtilities::sleep
+// ============================================================================
+void ThreadingUtilities::sleep (unsigned long _secs, unsigned long _nano_secs)
+{
+#if defined(HAS_NANO_SLEEP)
+
+  timespec ts2;
+  timespec ts1 = {_secs, _nano_secs};
+
+  while (::nanosleep(&ts1, &ts2)) 
+  {
+    if (errno == EINTR) 
+    {
+	    ts1.tv_sec  = ts2.tv_sec;
+	    ts1.tv_nsec = ts2.tv_nsec;
+	    continue;
+    }
+  }
+
+#else
+
+  if (_secs > 2000) 
+    while ((_secs = ::sleep(_secs))) ;
+  else 
+ 	  ::usleep(_secs * 1000000 + (_nano_secs / 1000));
+
+#endif
+}
+
+// ============================================================================
+// ThreadingUtilities::get_time
+// ============================================================================
+void ThreadingUtilities::get_time (unsigned long & abs_sec_,
+                                   unsigned long & abs_nano_sec_,
+                  		             unsigned long _rel_sec,
+                                   unsigned long _rel_nano_sec)
+{
+  timespec abs;
+
+  struct timeval tv;
+  ::gettimeofday(&tv, NULL); 
+
+  abs.tv_sec = tv.tv_sec;
+  abs.tv_nsec = tv.tv_usec * 1000;
+
+  abs.tv_sec += _rel_sec + abs.tv_nsec / NANOSECS_PER_SEC;
+  abs.tv_nsec += _rel_nano_sec;
+  abs.tv_nsec %= NANOSECS_PER_SEC;
+
+  abs_sec_ = abs.tv_sec;
+  abs_nano_sec_ = abs.tv_nsec;
+}
+
+// ============================================================================
+// ThreadingUtilities::get_time
+// ============================================================================
+void ThreadingUtilities::get_time (unsigned long delay_msecs, Timespec& abs_time)
+{
+  struct timeval now;
+  ::gettimeofday(&now, NULL); 
+  
+  //- std::cout << "delay_msecs........" << delay_msecs << std::endl;
+  
+  abs_time.tv_sec  = now.tv_sec + delay_msecs / 1000;
+  delay_msecs -=  delay_msecs / 1000 * 1000;
+  abs_time.tv_nsec = now.tv_usec * 1000;
+  abs_time.tv_nsec += delay_msecs * 1000000;
+  abs_time.tv_sec  += abs_time.tv_nsec / NANOSECS_PER_SEC;
+  abs_time.tv_nsec %= NANOSECS_PER_SEC;
+  
+  //- std::cout << "now.tv_sec........." << now.tv_sec << std::endl;
+  //- std::cout << "now.tv_nsec........" << now.tv_usec * 1000 << std::endl;
+  //- std::cout << "abs_time.tv_sec...." << abs_time.tv_sec << std::endl;
+  //- std::cout << "abs_time.tv_nsec..." << abs_time.tv_nsec << std::endl;
+  //- std::cout << "dt.sec............." << abs_time.tv_sec - now.tv_sec << std::endl;
+  //- std::cout << "dt.nsec............" << abs_time.tv_nsec - (now.tv_usec * 1000) << std::endl;
+}
+
+} // namespace bpm
diff --git a/src/threading/impl/PosixThreadingImpl.h b/src/threading/impl/PosixThreadingImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b2447ff5cf54524a88164498c828759f955eefc
--- /dev/null
+++ b/src/threading/impl/PosixThreadingImpl.h
@@ -0,0 +1,75 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+#ifndef _POSIX_THREADING_IMPL_
+#define _POSIX_THREADING_IMPL_
+
+//- no nano sleep!
+//- #define HAS_NANO_SLEEP
+
+//- no thread priority!
+//- #define HAS_THREAD_PRIORITY
+
+// ----------------------------------------------------------------------------
+// MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX
+// ----------------------------------------------------------------------------
+#define __MUTEX_IMPLEMENTATION \
+  pthread_mutex_t m_posix_mux; \
+  friend class Condition;
+
+// ----------------------------------------------------------------------------
+// CONDITION - CONDITION - CONDITION - CONDITION - CONDITION - CONDITION
+// ----------------------------------------------------------------------------
+#define __CONDITION_IMPLEMENTATION \
+  pthread_cond_t m_posix_cond;
+
+// ----------------------------------------------------------------------------
+// SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE
+// ----------------------------------------------------------------------------
+#define __SEMAPHORE_IMPLEMENTATION \
+  Mutex m_mux; \
+  Condition m_cond; \
+  int m_value;
+
+// ----------------------------------------------------------------------------
+// THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD
+// ----------------------------------------------------------------------------
+//- common thread entry point (non-OO OS interface to interface)
+#define THREAD_COMMON_ENTRY_POINT \
+  void * bpm_thread_common_entry_point (void *)
+
+extern "C" THREAD_COMMON_ENTRY_POINT;
+
+#define __THREAD_IMPLEMENTATION \
+  pthread_t m_posix_thread; \
+  void spawn (void) throw (Tango::DevFailed); \
+  static int bpm_to_posix_priority (Priority); \
+  friend THREAD_COMMON_ENTRY_POINT;
+
+#endif //- _POSIX_THREADING_IMPL_
diff --git a/src/threading/impl/PosixThreadingImpl.i b/src/threading/impl/PosixThreadingImpl.i
new file mode 100644
index 0000000000000000000000000000000000000000..3a46ad6c29d7eb9c44d8240ca4d8c495fc84f228
--- /dev/null
+++ b/src/threading/impl/PosixThreadingImpl.i
@@ -0,0 +1,169 @@
+//------------------------------------------------------------------------------
+// This file is part of the Libera Tango Device
+//------------------------------------------------------------------------------
+//
+// Copyright (C) 2005-2008  Nicolas Leclercq, Synchrotron SOLEIL.
+//
+// Part of the code is copyright (C) 2005-2008 Michael Abbott, 
+// Diamond Light Source Ltd. See ./ma/README for details. 
+//
+// The Libera Tango Device 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.
+//
+// The Libera Tango Device 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., 51
+// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// Contact:
+//      Nicolas Leclercq
+//      Synchrotron SOLEIL
+//      libera-sofware<AT>esrf<DOT>fr
+//------------------------------------------------------------------------------
+
+namespace bpm {
+
+// ****************************************************************************
+// YAT DUMMY_MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// DummyMutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::lock (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::acquire (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::unlock (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::release
+// ----------------------------------------------------------------------------
+INLINE_IMPL void DummyMutex::release (void)
+{
+ //- noop
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::try_lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState DummyMutex::try_lock (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+// ----------------------------------------------------------------------------
+// DummyMutex::try_acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL MutexState DummyMutex::try_acquire (void)
+{
+  return bpm::MUTEX_LOCKED;
+}
+
+// ****************************************************************************
+// YAT MUTEX IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Mutex::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::lock (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::acquire (void)
+{
+  this->lock();
+}
+// ----------------------------------------------------------------------------
+// Mutex::try_acquire
+// ----------------------------------------------------------------------------
+MutexState Mutex::try_acquire (void)
+{
+  return this->try_lock();
+}
+// ----------------------------------------------------------------------------
+// Mutex::unlock
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::unlock (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Mutex::acquire
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Mutex::release (void)
+{
+  this->unlock();
+}
+
+// ****************************************************************************
+// YAT THREAD IMPL
+// ****************************************************************************
+// ----------------------------------------------------------------------------
+// Thread::priority
+// ----------------------------------------------------------------------------
+INLINE_IMPL Priority Thread::priority (void) const
+{
+  //- enter critical section
+  bpm::SmartMutex guard(this->m_lock);
+
+  return this->m_priority;
+}
+// ----------------------------------------------------------------------------
+// Thread::state
+// ----------------------------------------------------------------------------
+INLINE_IMPL State Thread::state (void) const
+{
+  //- enter critical section
+  bpm::SmartMutex guard(this->m_lock);
+
+  return this->m_state;
+}
+// ----------------------------------------------------------------------------
+// Thread::yield
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::yield (void)
+{
+#error no impl
+}
+// ----------------------------------------------------------------------------
+// Thread::sleep
+// ----------------------------------------------------------------------------
+INLINE_IMPL void Thread::sleep (unsigned long _tmo_msecs)
+{
+  ThreadingUtilities::sleep(0, 1000000 * _tmo_msecs);
+}
+// ----------------------------------------------------------------------------
+// Thread::self
+// ----------------------------------------------------------------------------
+INLINE_IMPL ThreadUID Thread::self (void) const
+{
+  return this->m_uid;
+}
+// ----------------------------------------------------------------------------
+// Thread::lock
+// ----------------------------------------------------------------------------
+INLINE_IMPL Thread::Mutex & lock (void) const
+{
+  return this->m_lock;
+}
+
+} // namespace bpm