//-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceST360CounterSimulation(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceST360CounterSimulation";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Simulation settings
                 */
                XmlNode node = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Simulation);
                this.simDistance = XmlUtilities.GetChildValueAsDouble(node, Consts.STRXML_SimDistance);
                this.simDuration = XmlUtilities.GetChildValueAsInt(node, Consts.STRXML_SimDuration);
                this.simMean = XmlUtilities.GetChildValueAsInt(node, Consts.STRXML_SimMean);
                this.simPower = XmlUtilities.GetChildValueAsDouble(node, Consts.STRXML_SimPower);
                this.simDeviation = XmlUtilities.GetChildValueAsDouble(node, Consts.STRXML_SimDeviation);

                /*
                 * Initialise properties
                 */
                this.delaysSimulated = true;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceSerialLcdSerial(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceSerialLcdSerial";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Serial port settings
                 */
                XmlNode xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Serial);
                this.serialport = XmlUtilities.GetChildValue(xmlNode, Consts.STRXML_Port);
                this.baudrate = XmlUtilities.GetChildValueAsInt(xmlNode, Consts.STRXML_Baud);

                Logfile.Write(Logfile.Level.Config, String.Format(STRLOG_SerialPort_arg2, serialport, baudrate));

                /*
                 * Create the receive and report objects
                 */
                this.receiveDataInfo = new ReceiveDataInfo();
                this.reportQueue = new Queue<LCDPacket>();
                this.reportSignal = new Object();
                this.responseSignal = new Object();
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="configProperties"></param>
        public LabEquipmentManager(ConfigProperties configProperties)
        {
            const string methodName = "LabEquipmentManager";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Check that parameters are valid
                 */
                if (configProperties == null)
                {
                    throw new ArgumentNullException(ConfigProperties.ClassName);
                }

                /*
                 * Create class instances and objects that are used by the LabEquipmentEngine
                 */
                this.labEquipmentConfiguration = new LabEquipmentConfiguration(configProperties);
                if (labEquipmentConfiguration == null)
                {
                    throw new ArgumentNullException(LabEquipmentConfiguration.ClassName);
                }
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceSerialLcdNetwork(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceSerialLcdNetwork";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Network settings
                 */
                XmlNode xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Network);
                String ipAddr = XmlUtilities.GetChildValue(xmlNode, Consts.STRXML_IPaddr);
                this.port = XmlUtilities.GetChildValueAsInt(xmlNode, Consts.STRXML_Port);
                this.ipAddress = IPAddress.Parse(ipAddr);

                Logfile.Write(String.Format(STRLOG_IPaddrPort_arg2, this.ipAddress.ToString(), this.port));
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DriverSimAbsorbers(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DriverSimAbsorbers";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            /*
             * Nothing to do here
             */

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //-----------------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceRedLion(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration, STR_ClassName)
        {
            const string methodName = "DeviceRedLion";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                string logMessage = Logfile.STRLOG_Newline;

                /*
                 * Get the IP address and port number to use
                 */
                XmlNode xmlNodeNetwork = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Network);
                string ipaddr = XmlUtilities.GetChildValue(xmlNodeNetwork, Consts.STRXML_IPaddr, false);
                this.ipAddress = IPAddress.Parse(ipaddr);
                this.port = XmlUtilities.GetChildValueAsInt(xmlNodeNetwork, Consts.STRXML_Port);
                logMessage += String.Format(STRLOG_IPaddrPort_arg2, this.ipAddress.ToString(), this.port) + Logfile.STRLOG_Newline;

                /*
                 * Get the network timeouts
                 */
                XmlNode xmlNodeTimeouts = XmlUtilities.GetChildNode(xmlNodeNetwork, Consts.STRXML_Timeouts);
                this.receiveTimeout = XmlUtilities.GetChildValueAsInt(xmlNodeTimeouts, Consts.STRXML_Receive);
                logMessage += String.Format(STRLOG_ReceiveTimout_arg, this.receiveTimeout) + Logfile.STRLOG_Newline;

                /*
                 * Get Modbus slave identity
                 */
                XmlNode xmlNodeModbus = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Modbus, false);
                this.slaveId = XmlUtilities.GetChildValueAsInt(xmlNodeModbus, Consts.STRXML_SlaveId);
                logMessage += String.Format(STRLOG_ModbusSlaveId_arg, this.slaveId) + Logfile.STRLOG_Newline;

                /*
                 * Get status checking
                 */
                XmlNode xmlNodeStatusCheck = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_StatusCheck, false);
                this.checkSpeedEnabled = XmlUtilities.GetChildValueAsBool(xmlNodeStatusCheck, Consts.STRXML_StatusCheckSpeed);
                logMessage += String.Format(STRLOG_CheckSpeedEnabled_arg, this.checkSpeedEnabled.ToString());

                /*
                 * Log the configuration information
                 */
                Logfile.Write(Logfile.Level.Info, logMessage);
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceFlexMotionSimulation(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceFlexMotionSimulation";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Source location to configuration mapping
                 */
                this.mapSourceLocations = new Dictionary<Char, ConfigurationSource>();
                foreach (KeyValuePair<String, ConfigurationSource> item in this.mapSources)
                {
                    this.mapSourceLocations.Add(item.Value.Location, item.Value);
                }

                if (this.absorbersPresent == true)
                {
                    /*
                     * Absorber location to configuration mapping
                     */
                    this.mapAbsorberLocations = new Dictionary<Char, ConfigurationAbsorber>();
                    foreach (KeyValuePair<String, ConfigurationAbsorber> item in this.mapAbsorbers)
                    {
                        this.mapAbsorberLocations.Add(item.Value.Location, item.Value);
                    }
                }

                /*
                 * Initialise properties
                 */
                this.delaysSimulated = true;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public EquipmentEngine(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const string methodName = "EquipmentEngine";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Create instances of the equipment devices
                 */
                this.deviceRedLion = new DeviceRedLion(this.labEquipmentConfiguration);
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        public DeviceSerialLcd(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration, STR_ClassName)
        {
            const String methodName = "DeviceSerialLcd";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * WriteLine time
                 */
                this.writeLineTime = XmlUtilities.GetChildValueAsDouble(this.xmlNodeDevice, Consts.STRXML_WriteLineTime);
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DriverEquipment(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DriverEquipment";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Create an instance of ExperimentValidation
                 */
                this.experimentValidation = ExperimentValidation.XmlParse(labEquipmentConfiguration.XmlValidation);
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        public DeviceSerialLcdSimulation(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceSerialLcdSimulation";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Initialise properties
                 */
                this.delaysSimulated = true;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //-----------------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DriverSpeedVsVoltage(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const string methodName = "DriverSpeedVsVoltage";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Get the number of measurements to take and the delay between measurements
                 */
                this.measurementCount = XmlUtilities.GetChildValueAsInt(this.xmlNodeDriver, Consts.STRXML_Measurements);
                this.measurementDelay = XmlUtilities.GetChildValueAsInt(this.xmlNodeDriver, Consts.STRXML_MeasurementDelay);
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        public DeviceFlexMotion(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration, STR_ClassName)
        {
            const String methodName = "DeviceFlexMotion";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Tube settings
                 */
                XmlNode xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Tube);
                this.tubeOffsetDistance = XmlUtilities.GetChildValueAsInt(xmlNode, Consts.STRXML_OffsetDistance);
                this.tubeDistanceHome = XmlUtilities.GetChildValueAsInt(xmlNode, Consts.STRXML_HomeDistance);
                this.tubeMoveRate = XmlUtilities.GetChildValueAsDouble(xmlNode, Consts.STRXML_MoveRate);

                /*
                 * Source settings
                 */
                xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Sources);
                this.sourceFirstLocation = XmlUtilities.GetChildValueAsChar(xmlNode, Consts.STRXML_FirstLocation);
                this.sourceHomeLocation = XmlUtilities.GetChildValueAsChar(xmlNode, Consts.STRXML_HomeLocation);

                /*
                 * Source name to configuration mapping
                 */
                this.mapSources = new Dictionary<String, ConfigurationSource>();
                ArrayList xmlNodeList = XmlUtilities.GetChildNodeList(xmlNode, Consts.STRXML_Source, false);
                for (int i = 0; i < xmlNodeList.Count; i++)
                {
                    /*
                     * Add the mapping
                     */
                    XmlNode xmlNodeSource = (XmlNode)xmlNodeList[i];
                    ConfigurationSource configurationSource = ConfigurationSource.XmlParse(xmlNodeSource.OuterXml);
                    this.mapSources.Add(configurationSource.Name, configurationSource);

                    /*
                     * Check if this is the home location
                     */
                    if (configurationSource.Location == this.sourceHomeLocation)
                    {
                        this.sourceNameHome = configurationSource.Name;
                    }

                }

                /*
                 * Absorbers may not be present
                 */
                try
                {
                    xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Absorbers, true);

                    /*
                     * Absorber settings
                     */
                    this.absorberFirstLocation = XmlUtilities.GetChildValueAsChar(xmlNode, Consts.STRXML_FirstLocation);
                    this.absorberHomeLocation = XmlUtilities.GetChildValueAsChar(xmlNode, Consts.STRXML_HomeLocation);

                    /*
                     * Absorber name to configuration mapping
                     */
                    this.mapAbsorbers = new Dictionary<String, ConfigurationAbsorber>();
                    xmlNodeList = XmlUtilities.GetChildNodeList(xmlNode, Consts.STRXML_Absorber, false);
                    for (int i = 0; i < xmlNodeList.Count; i++)
                    {
                        /*
                         * Add the mapping
                         */
                        XmlNode xmlNodeAbsorber = (XmlNode)xmlNodeList[i];
                        ConfigurationAbsorber configurationAbsorber = ConfigurationAbsorber.XmlParse(xmlNodeAbsorber.OuterXml);
                        this.mapAbsorbers.Add(configurationAbsorber.Name, configurationAbsorber);

                        /*
                         * Check if this is the home location
                         */
                        if (configurationAbsorber.Location == this.absorberHomeLocation)
                        {
                            this.absorberNameHome = configurationAbsorber.Name;
                        }
                    }

                    /*
                     * Absorbers are present
                     */
                    this.absorbersPresent = true;
                }
                catch (Exception)
                {
                    /*
                     * Absorbers are not present
                     */
                    this.absorbersPresent = false;
                }
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceFlexMotionHardware(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceFlexMotionHardware";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Hardware settings
                 */
                XmlNode xmlNodeHardware = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Hardware);
                this.boardId = (byte)XmlUtilities.GetChildValueAsInt(xmlNodeHardware, Consts.STRXML_BoardId);

                /*
                 * Tube axis
                 */
                XmlNode xmlNodeAxisId = XmlUtilities.GetChildNode(xmlNodeHardware, Consts.STRXML_AxisId);
                int axisId = XmlUtilities.GetChildValueAsInt(xmlNodeAxisId, Consts.STRXML_Tube);
                this.tubeAxis = this.GetNimcAxis(axisId);

                /*
                 * Source axis
                 */
                axisId = XmlUtilities.GetChildValueAsInt(xmlNodeAxisId, Consts.STRXML_Sources);
                this.sourceAxis = this.GetNimcAxis(axisId);

                /*
                 * Absorber axis may not be specified
                 */
                try
                {
                    axisId = XmlUtilities.GetChildValueAsInt(xmlNodeAxisId, Consts.STRXML_Absorbers);
                    this.absorberAxis = this.GetNimcAxis(axisId);
                    axisId = XmlUtilities.GetChildValueAsInt(xmlNodeAxisId, Consts.STRXML_Unused);
                    this.unusedAxis = this.GetNimcAxis(axisId);
                }
                catch
                {
                    this.absorberAxis = Nimc.NOAXIS;
                    this.unusedAxis = Nimc.NOAXIS;
                }

                /*
                 * Set breakpoint axes
                 */
                this.powerEnableBreakpoint = this.tubeAxis;
                this.counterStartBreakpoint = this.sourceAxis;

                /*
                 * Initialise the Flexmotion controller card. Must be done here because a breakpoint on the controller card
                 * is used to powerup the equipment and initialisation is carried out after the equipment is powered up.
                 */
                Logfile.Write(STRLOG_InitialisingController);

                if (this.InitialiseController() == false)
                {
                    throw new ArgumentException(this.lastError);
                }
                Logfile.Write(STRLOG_ControllerInitialised);

                /*
                 * Determine the initialise delay
                 */
                int powerupResetDelay = XmlUtilities.GetChildValueAsInt(xmlNodeHardware, Consts.STRXML_PowerupResetDelay);
                if (this.powerupReset == true)
                {
                    this.initialiseDelay += powerupResetDelay;
                }
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //-------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public LabEquipmentEngine(LabEquipmentConfiguration labEquipmentConfiguration)
        {
            const string methodName = "LabEquipmentEngine";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Check that parameters are valid
                 */
                if (labEquipmentConfiguration == null)
                {
                    throw new ArgumentNullException(LabEquipmentConfiguration.ClassName);
                }

                /*
                 * Save to local variables
                 */
                this.labEquipmentConfiguration = labEquipmentConfiguration;

                /*
                 * Initialise local variables
                 */
                this.signalStartExecution = new WaitNotify();
                if (this.signalStartExecution == null)
                {
                    throw new ArgumentNullException(WaitNotify.STR_ClassName);
                }
                this.runState = States.PowerOff;
                this.powerdownEnabled = this.labEquipmentConfiguration.PowerdownEnabled;
                this.powerdownSuspended = false;
                this.statusReady = false;
                this.statusMessage = STR_NotInitialised;

                /*
                 * Initialise properties
                 */
                this.initialiseDelay = this.labEquipmentConfiguration.InitialiseDelay;
                this.powerdownTimeout = this.labEquipmentConfiguration.PowerdownTimeout;
                this.poweroffDelay = this.labEquipmentConfiguration.PoweroffDelay;
                this.powerupDelay = this.labEquipmentConfiguration.PowerupDelay;
                this.timeUntilPowerdown = 0;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Config, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public EquipmentEngine(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "EquipmentEngine";
            Logfile.WriteCalled(logLevel, STR_ClassName, methodName);

            try
            {
                /*
                 * Create instances of the simulation devices to be used by the simulation drivers
                 * so that both the hardware drivers and simulation drivers are available for the setups
                 */
                this.deviceFlexMotionSimulation = new DeviceFlexMotionSimulation(this.labEquipmentConfiguration);
                this.deviceST360CounterSimulation = new DeviceST360CounterSimulation(this.labEquipmentConfiguration);
                this.deviceSerialLcdSimulation = new DeviceSerialLcdSimulation(this.labEquipmentConfiguration);

                /*
                 * Initialise the simulated devices
                 */
                this.deviceFlexMotionSimulation.Initialise();
                this.deviceST360CounterSimulation.Initialise();
                this.deviceSerialLcdSimulation.Initialise();

                /*
                 * Determine FlexMotion device to use
                 */
                XmlDocument xmlDocument = XmlUtilities.GetDocumentFromString(labEquipmentConfiguration.GetXmlDeviceConfiguration(DeviceFlexMotion.ClassName));
                XmlNode xmlNodeDevice = XmlUtilities.GetRootNode(xmlDocument, LabConsts.STRXML_Device);
                String deviceType = XmlUtilities.GetChildValue(xmlNodeDevice, Consts.STRXML_Type);

                /*
                 * Create instance of the FlexMotion device to use
                 */
                switch (deviceType)
                {
                    case Consts.STRXML_TypeNone:
                        this.deviceFlexMotion = new DeviceFlexMotion(this.labEquipmentConfiguration);
                        break;

                    case Consts.STRXML_TypeSimulation:
                        this.deviceFlexMotion = this.deviceFlexMotionSimulation;
                        break;

                    case Consts.STRXML_TypeHardware:
                        this.deviceFlexMotion = new DeviceFlexMotionHardware(this.labEquipmentConfiguration);
                        break;

                    default:
                        throw new ApplicationException(String.Format(STRERR_InvalidDeviceType_arg2, DeviceFlexMotion.ClassName, deviceType));
                }

                /*
                 * Determine ST360Counter device to use
                 */
                xmlDocument = XmlUtilities.GetDocumentFromString(labEquipmentConfiguration.GetXmlDeviceConfiguration(DeviceST360Counter.ClassName));
                xmlNodeDevice = XmlUtilities.GetRootNode(xmlDocument, LabConsts.STRXML_Device);
                deviceType = XmlUtilities.GetChildValue(xmlNodeDevice, Consts.STRXML_Type);

                /*
                 * Create instance of the ST360Counter device to use
                 */
                switch (deviceType)
                {
                    case Consts.STRXML_TypeNone:
                        this.deviceST360Counter = new DeviceST360Counter(this.labEquipmentConfiguration);
                        break;

                    case Consts.STRXML_TypeSimulation:
                        this.deviceST360Counter = this.deviceST360CounterSimulation;
                        break;

                    case Consts.STRXML_TypeSerial:
                        this.deviceST360Counter = new DeviceST360CounterSerial(this.labEquipmentConfiguration);
                        break;

                    case Consts.STRXML_TypeNetwork:
                        this.deviceST360Counter = new DeviceST360CounterNetwork(this.labEquipmentConfiguration);
                        break;

                    default:
                        throw new ApplicationException(String.Format(STRERR_InvalidDeviceType_arg2, DeviceST360Counter.ClassName, deviceType));
                }

                /*
                 * Determine DeviceSerialLcd device to use
                 */
                xmlDocument = XmlUtilities.GetDocumentFromString(labEquipmentConfiguration.GetXmlDeviceConfiguration(DeviceSerialLcd.ClassName));
                xmlNodeDevice = XmlUtilities.GetRootNode(xmlDocument, LabConsts.STRXML_Device);
                deviceType = XmlUtilities.GetChildValue(xmlNodeDevice, Consts.STRXML_Type);

                /*
                 * Create instance of the DeviceSerialLcd device to use
                 */
                switch (deviceType)
                {
                    case Consts.STRXML_TypeNone:
                        this.deviceSerialLcd = new DeviceSerialLcd(this.labEquipmentConfiguration);
                        break;

                    case Consts.STRXML_TypeSimulation:
                        this.deviceSerialLcd = this.deviceSerialLcdSimulation;
                        break;

                    case Consts.STRXML_TypeSerial:
                        this.deviceSerialLcd = new DeviceSerialLcdSerial(this.labEquipmentConfiguration);
                        break;

                    case Consts.STRXML_TypeNetwork:
                        this.deviceSerialLcd = new DeviceSerialLcdNetwork(this.labEquipmentConfiguration);
                        break;

                    default:
                        throw new ApplicationException(String.Format(STRERR_InvalidDeviceType_arg2, DeviceSerialLcd.ClassName, deviceType));
                }

                /*
                 * Initialise properties
                 */
                this.initialiseDelay = this.deviceFlexMotion.InitialiseDelay + this.deviceST360Counter.InitialiseDelay + this.deviceSerialLcd.InitialiseDelay;
                this.disablePowerdown = false;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(logLevel, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        public DeviceST360Counter(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration, STR_ClassName)
        {
            const String methodName = "DeviceST360Counter";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Get Geiger tube high voltage
                 */
                try
                {
                    this.geigerTubeVoltage = XmlUtilities.GetChildValueAsInt(this.xmlNodeDevice, Consts.STRXML_GeigerTubeVoltage);
                }
                catch
                {
                    this.geigerTubeVoltage = DEFAULT_HighVoltage;
                }

                /*
                 * Make sure that the high voltage is within range
                 */
                if (this.geigerTubeVoltage < MIN_HighVoltage)
                {
                    this.geigerTubeVoltage = MIN_HighVoltage;
                }
                else if (this.geigerTubeVoltage > MAX_HighVoltage)
                {
                    this.geigerTubeVoltage = MAX_HighVoltage;
                }

                /*
                 * Get speaker volume
                 */
                try
                {
                    this.speakerVolume = XmlUtilities.GetChildValueAsInt(this.xmlNodeDevice, Consts.STRXML_SpeakerVolume);
                }
                catch
                {
                    this.speakerVolume = MIN_SpeakerVolume;
                }

                /*
                 * Make sure that the speaker volume is within range
                 */
                if (this.speakerVolume < MIN_SpeakerVolume)
                {
                    this.speakerVolume = MIN_SpeakerVolume;
                }
                else if (this.speakerVolume > MAX_SpeakerVolume)
                {
                    this.speakerVolume = MAX_SpeakerVolume;
                }

                /*
                 * Get capture time adjustment: y = Mx + C
                 */
                XmlNode xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_TimeAdjustment);
                String capture = XmlUtilities.GetChildValue(xmlNode, Consts.STRXML_Capture, false);
                String[] strSplit = capture.Split(new char[] { Consts.CHRCSV_SplitterChar });
                this.timeAdjustmentCapture = new double[strSplit.Length];
                for (int i = 0; i < strSplit.Length; i++)
                {
                    this.timeAdjustmentCapture[i] = Double.Parse(strSplit[i]);
                }

                Logfile.Write(String.Format(STRLOG_HighVoltageSpeakerVolume_arg2, this.geigerTubeVoltage, this.speakerVolume));
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// 
        /// </summary>
        /// <param name="labEquipmentConfiguration"></param>
        public DeviceST360CounterSerial(LabEquipmentConfiguration labEquipmentConfiguration)
            : base(labEquipmentConfiguration)
        {
            const String methodName = "DeviceST360CounterSerial";
            Logfile.WriteCalled(Logfile.Level.Info, STR_ClassName, methodName);

            try
            {
                /*
                 * Serial port settings
                 */
                XmlNode xmlNode = XmlUtilities.GetChildNode(this.xmlNodeDevice, Consts.STRXML_Serial);
                this.serialport = XmlUtilities.GetChildValue(xmlNode, Consts.STRXML_Port);
                this.baudrate = XmlUtilities.GetChildValueAsInt(xmlNode, Consts.STRXML_Baud);

                /*
                 * Create the receive objects
                 */
                this.receiveDataInfo = new ReceiveDataInfo();
                this.responseSignal = new Object();

                /*
                 * Create an instance of the serial port, set read and write timeouts
                 */
                this.serialPort = new SerialPort(serialport, baudrate);
                this.serialPort.ReadTimeout = 1000;
                this.serialPort.WriteTimeout = 3000;

                Logfile.Write(String.Format(STRLOG_SerialPortBaudRate_arg2, serialport, baudrate));
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
                throw ex;
            }

            Logfile.WriteCompleted(Logfile.Level.Info, STR_ClassName, methodName);
        }