/*----- PROTECTED REGION ID(UniversalTest.cpp) ENABLED START -----*/
//=============================================================================
//
// file :        UniversalTest.cpp
//
// description : C++ source for the UniversalTest class 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
//               UniversalTest are implemented in this file.
//
// project :     UniversalTest
//
// This file is part of Tango device class.
// 
// Tango 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 3 of the License, or
// (at your option) any later version.
// 
// Tango 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 Tango.  If not, see <http://www.gnu.org/licenses/>.
// 
// $Author:  $
// Copyright (C): 2015-2019
//                European Synchrotron Radiation Facility
//                BP 220, Grenoble 38043
//                France
//
// $Revision:  $
// $Date:  $
//
// $HeadURL:  $
//
//=============================================================================
//                This file is generated by POGO
//        (Program Obviously used to Generate tango Object)
//=============================================================================


#include "UniversalTest.h"
#include "UniversalTestClass.h"

#include <thread>

using namespace std;

/*----- PROTECTED REGION END -----*/	//	UniversalTest.cpp

/**
 *  UniversalTest class description:
 *    The goal of this device server is to be able to provide attributes of every possible Tango type.
 *    It is possible to change dynamically the Quality Factor of a given attribute.
 *    It is possible to make an attribute throw exceptions.
 *    It is possible to change the behaviour of the attributes (increment at each read, read value always set to the set value, 
 *    read value fluctuating around the set value,...)
 *    Some dynamic expert attributes will be created to be able to control the behaviour of the other attributes.
 *    The attributes named xxx_quality will allow to change the quality factor of the attribute named xxx.
 */

//================================================================
//  The following table gives the correspondence
//  between command and method names.
//
//  Command name  |  Method name
//================================================================
//  State         |  Inherited (no method)
//  Status        |  Inherited (no method)
//================================================================

//================================================================
//  Attributes managed is:
//================================================================
//  setState  |  Tango::DevState	Scalar
//================================================================

namespace UniversalTest_ns
{
/*----- PROTECTED REGION ID(UniversalTest::namespace_starting) ENABLED START -----*/

//	static initializations

/*----- PROTECTED REGION END -----*/	//	UniversalTest::namespace_starting

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::UniversalTest()
 *	Description: Constructors for a Tango device
 *                implementing the classUniversalTest
 */
//--------------------------------------------------------
UniversalTest::UniversalTest(Tango::DeviceClass *cl, std::string &s)
 : TANGO_BASE_CLASS(cl, s.c_str())
{
	/*----- PROTECTED REGION ID(UniversalTest::constructor_1) ENABLED START -----*/
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::constructor_1
}
//--------------------------------------------------------
UniversalTest::UniversalTest(Tango::DeviceClass *cl, const char *s)
 : TANGO_BASE_CLASS(cl, s)
{
	/*----- PROTECTED REGION ID(UniversalTest::constructor_2) ENABLED START -----*/
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::constructor_2
}
//--------------------------------------------------------
UniversalTest::UniversalTest(Tango::DeviceClass *cl, const char *s, const char *d)
 : TANGO_BASE_CLASS(cl, s, d)
{
	/*----- PROTECTED REGION ID(UniversalTest::constructor_3) ENABLED START -----*/
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::constructor_3
}
//--------------------------------------------------------
UniversalTest::~UniversalTest()
{
	delete_device();
}

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::delete_device()
 *	Description: will be called at device destruction or at init command
 */
//--------------------------------------------------------
void UniversalTest::delete_device()
{
	DEBUG_STREAM << "UniversalTest::delete_device() " << device_name << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::delete_device) ENABLED START -----*/
	
	//	Delete device allocated objects
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::delete_device
	delete[] attr_setState_read;
}

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::init_device()
 *	Description: will be called at device initialization.
 */
//--------------------------------------------------------
void UniversalTest::init_device()
{
	DEBUG_STREAM << "UniversalTest::init_device() create device " << device_name << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::init_device_before) ENABLED START -----*/
	
	//	Initialization before get_device_property() call
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::init_device_before

	//	No device property to be read from database

	attr_setState_read = new Tango::DevState[1];
	/*----- PROTECTED REGION ID(UniversalTest::init_device) ENABLED START -----*/
	
	//	Initialize device
	*attr_setState_read = Tango::ON;
	set_state(Tango::ON);
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::init_device
}


//--------------------------------------------------------
/**
 *	Method     : UniversalTest::always_executed_hook()
 *	Description: method always executed before any command is executed
 */
//--------------------------------------------------------
void UniversalTest::always_executed_hook()
{
	DEBUG_STREAM << "UniversalTest::always_executed_hook()  " << device_name << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::always_executed_hook) ENABLED START -----*/
	
	//	code always executed before all requests
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::always_executed_hook
}

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::read_attr_hardware()
 *	Description: Hardware acquisition for attributes
 */
//--------------------------------------------------------
void UniversalTest::read_attr_hardware(TANGO_UNUSED(std::vector<long> &attr_list))
{
	DEBUG_STREAM << "UniversalTest::read_attr_hardware(std::vector<long> &attr_list) entering... " << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::read_attr_hardware) ENABLED START -----*/
	
	//	Add your own code
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::read_attr_hardware
}
//--------------------------------------------------------
/**
 *	Method     : UniversalTest::write_attr_hardware()
 *	Description: Hardware writing for attributes
 */
//--------------------------------------------------------
void UniversalTest::write_attr_hardware(TANGO_UNUSED(std::vector<long> &attr_list))
{
	DEBUG_STREAM << "UniversalTest::write_attr_hardware(std::vector<long> &attr_list) entering... " << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::write_attr_hardware) ENABLED START -----*/
	
	//	Add your own code
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::write_attr_hardware
}

//--------------------------------------------------------
/**
 *	Read attribute setState related method
 *	Description: This represents the state of the device. 
 *               Changing this attribute set_value will invoke the set_state() method with the specified state value.
 *
 *	Data type:	Tango::DevState
 *	Attr type:	Scalar
 */
//--------------------------------------------------------
void UniversalTest::read_setState(Tango::Attribute &attr)
{
	DEBUG_STREAM << "UniversalTest::read_setState(Tango::Attribute &attr) entering... " << std::endl;
	/*----- PROTECTED REGION ID(UniversalTest::read_setState) ENABLED START -----*/
	//	Set the attribute value
	attr.set_value(attr_setState_read);
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::read_setState
}
//--------------------------------------------------------
/**
 *	Write attribute setState related method
 *	Description: This represents the state of the device. 
 *               Changing this attribute set_value will invoke the set_state() method with the specified state value.
 *
 *	Data type:	Tango::DevState
 *	Attr type:	Scalar
 */
//--------------------------------------------------------
void UniversalTest::write_setState(Tango::WAttribute &attr)
{
	DEBUG_STREAM << "UniversalTest::write_setState(Tango::WAttribute &attr) entering... " << std::endl;
	//	Retrieve write value
	        Tango::DevState w_val;
	attr.get_write_value(w_val);
	/*----- PROTECTED REGION ID(UniversalTest::write_setState) ENABLED START -----*/
	*attr_setState_read = w_val;
	set_state(w_val);
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::write_setState
}

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::add_dynamic_attributes()
 *	Description: Create the dynamic attributes if any
 *                for specified device.
 */
//--------------------------------------------------------
void UniversalTest::add_dynamic_attributes()
{
	/*----- PROTECTED REGION ID(UniversalTest::add_dynamic_attributes) ENABLED START -----*/
	
	//	Add your own code to create and add dynamic attributes if any
	// Create some attributes for each type
	//------------------------------       SCALAR ATTRIBUTES        -----------------------------
	add_scalar_attr("DevBooleanRO",Tango::DEV_BOOLEAN, Tango::READ);
	add_scalar_attr("DevBooleanRW",Tango::DEV_BOOLEAN, Tango::READ_WRITE);
	add_scalar_attr("DevBooleanWO",Tango::DEV_BOOLEAN, Tango::WRITE);
	
	add_scalar_attr("DevUCharRO",Tango::DEV_UCHAR, Tango::READ);
	add_scalar_attr("DevUCharRW",Tango::DEV_UCHAR, Tango::READ_WRITE);
	add_scalar_attr("DevUCharWO",Tango::DEV_UCHAR, Tango::WRITE);
	
	add_scalar_attr("DevUShortRO",Tango::DEV_USHORT, Tango::READ);
	add_scalar_attr("DevUShortRW",Tango::DEV_USHORT, Tango::READ_WRITE);
	add_scalar_attr("DevUShortWO",Tango::DEV_USHORT, Tango::WRITE);
	add_scalar_attr("DevShortRO",Tango::DEV_SHORT, Tango::READ);
	add_scalar_attr("DevShortRW",Tango::DEV_SHORT, Tango::READ_WRITE);
	add_scalar_attr("DevShortWO",Tango::DEV_SHORT, Tango::WRITE);
	
	add_scalar_attr("DevULongRO",Tango::DEV_ULONG, Tango::READ);
	add_scalar_attr("DevULongRW",Tango::DEV_ULONG, Tango::READ_WRITE);
	add_scalar_attr("DevULongWO",Tango::DEV_ULONG, Tango::WRITE);
	add_scalar_attr("DevLongRO",Tango::DEV_LONG, Tango::READ);
	add_scalar_attr("DevLongRW",Tango::DEV_LONG, Tango::READ_WRITE);
	add_scalar_attr("DevLongWO",Tango::DEV_LONG, Tango::WRITE);
	
	add_scalar_attr("DevULong64RO",Tango::DEV_ULONG64, Tango::READ);
	add_scalar_attr("DevULong64RW",Tango::DEV_ULONG64, Tango::READ_WRITE);
	add_scalar_attr("DevULong64WO",Tango::DEV_ULONG64, Tango::WRITE);
	add_scalar_attr("DevLong64RO",Tango::DEV_LONG64, Tango::READ);
	add_scalar_attr("DevLong64RW",Tango::DEV_LONG64, Tango::READ_WRITE);
	add_scalar_attr("DevLong64WO",Tango::DEV_LONG64, Tango::WRITE);
	
	add_scalar_attr("DevFloatRO",Tango::DEV_FLOAT, Tango::READ);
	add_scalar_attr("DevFloatRW",Tango::DEV_FLOAT, Tango::READ_WRITE);
	add_scalar_attr("DevFloatWO",Tango::DEV_FLOAT, Tango::WRITE);
	
	add_scalar_attr("DevDoubleRO",Tango::DEV_DOUBLE, Tango::READ);
	add_scalar_attr("DevDoubleRW",Tango::DEV_DOUBLE, Tango::READ_WRITE);
	add_scalar_attr("DevDoubleWO",Tango::DEV_DOUBLE, Tango::WRITE);
	
	add_scalar_attr("DevStringRO",Tango::DEV_STRING, Tango::READ);
	add_scalar_attr("DevStringRW",Tango::DEV_STRING, Tango::READ_WRITE);
	add_scalar_attr("DevStringWO",Tango::DEV_STRING, Tango::WRITE);
	
	add_scalar_attr("DevStateRO",Tango::DEV_STATE, Tango::READ);
	add_scalar_attr("DevStateRW",Tango::DEV_STATE, Tango::READ_WRITE);
	//add_scalar_attr("DevStateWO",Tango::DEV_STATE, Tango::WRITE);
	
	//------------------------------       SPECTRUM ATTRIBUTES        -----------------------------
	add_spectrum_attribute<Tango::DevBoolean>("DevBooleanSpectrumRO",Tango::DEV_BOOLEAN, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevBoolean>("DevBooleanSpectrumRW",Tango::DEV_BOOLEAN, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevBoolean>("DevBooleanSpectrumWO",Tango::DEV_BOOLEAN, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);

	add_spectrum_attribute<Tango::DevUChar>("DevUCharSpectrumRO",Tango::DEV_UCHAR, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevUChar>("DevUCharSpectrumRW",Tango::DEV_UCHAR, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevUChar>("DevUCharSpectrumWO",Tango::DEV_UCHAR, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevUShort>("DevUShortSpectrumRO",Tango::DEV_USHORT, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevUShort>("DevUShortSpectrumRW",Tango::DEV_USHORT, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevUShort>("DevUShortSpectrumWO",Tango::DEV_USHORT, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevShort>("DevShortSpectrumRO",Tango::DEV_SHORT, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevShort>("DevShortSpectrumRW",Tango::DEV_SHORT, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevShort>("DevShortSpectrumWO",Tango::DEV_SHORT, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevULong>("DevULongSpectrumRO",Tango::DEV_ULONG, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevULong>("DevULongSpectrumRW",Tango::DEV_ULONG, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevULong>("DevULongSpectrumWO",Tango::DEV_ULONG, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong>("DevLongSpectrumRO",Tango::DEV_LONG, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong>("DevLongSpectrumRW",Tango::DEV_LONG, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong>("DevLongSpectrumWO",Tango::DEV_LONG, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevULong64>("DevULong64SpectrumRO",Tango::DEV_ULONG64, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevULong64>("DevULong64SpectrumRW",Tango::DEV_ULONG64, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevULong64>("DevULong64SpectrumWO",Tango::DEV_ULONG64, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong64>("DevLong64SpectrumRO",Tango::DEV_LONG64, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong64>("DevLong64SpectrumRW",Tango::DEV_LONG64, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevLong64>("DevLong64SpectrumWO",Tango::DEV_LONG64, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevFloat>("DevFloatSpectrumRO",Tango::DEV_FLOAT, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevFloat>("DevFloatSpectrumRW",Tango::DEV_FLOAT, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevFloat>("DevFloatSpectrumWO",Tango::DEV_FLOAT, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevDouble>("DevDoubleSpectrumRO",Tango::DEV_DOUBLE, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevDouble>("DevDoubleSpectrumRW",Tango::DEV_DOUBLE, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevDouble>("DevDoubleSpectrumWO",Tango::DEV_DOUBLE, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);

	add_spectrum_attribute<Tango::DevString>("DevStringSpectrumRO",Tango::DEV_STRING, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevString>("DevStringSpectrumRW",Tango::DEV_STRING, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevString>("DevStringSpectrumWO",Tango::DEV_STRING, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	add_spectrum_attribute<Tango::DevState>("DevStateSpectrumRO",Tango::DEV_STATE, Tango::READ,DEFAULT_SPECTRUM_MAX_DIM_X);
	add_spectrum_attribute<Tango::DevState>("DevStateSpectrumRW",Tango::DEV_STATE, Tango::READ_WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	//add_spectrum_attribute<Tango::DevState>("DevStateSpectrumWO",Tango::DEV_STATE, Tango::WRITE,DEFAULT_SPECTRUM_MAX_DIM_X);
	
	//------------------------------       IMAGE ATTRIBUTES        -----------------------------
	add_image_attribute<Tango::DevBoolean>("DevBooleanImageRO",Tango::DEV_BOOLEAN, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevBoolean>("DevBooleanImageRW",Tango::DEV_BOOLEAN, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevBoolean>("DevBooleanImageWO",Tango::DEV_BOOLEAN, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);

	add_image_attribute<Tango::DevUChar>("DevUCharImageRO",Tango::DEV_UCHAR, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevUChar>("DevUCharImageRW",Tango::DEV_UCHAR, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevUChar>("DevUCharImageWO",Tango::DEV_UCHAR, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevUShort>("DevUShortImageRO",Tango::DEV_USHORT, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevUShort>("DevUShortImageRW",Tango::DEV_USHORT, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevUShort>("DevUShortImageWO",Tango::DEV_USHORT, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevShort>("DevShortImageRO",Tango::DEV_SHORT, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevShort>("DevShortImageRW",Tango::DEV_SHORT, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevShort>("DevShortImageWO",Tango::DEV_SHORT, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevULong>("DevULongImageRO",Tango::DEV_ULONG, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevULong>("DevULongImageRW",Tango::DEV_ULONG, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevULong>("DevULongImageWO",Tango::DEV_ULONG, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong>("DevLongImageRO",Tango::DEV_LONG, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong>("DevLongImageRW",Tango::DEV_LONG, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong>("DevLongImageWO",Tango::DEV_LONG, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevULong64>("DevULong64ImageRO",Tango::DEV_ULONG64, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevULong64>("DevULong64ImageRW",Tango::DEV_ULONG64, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevULong64>("DevULong64ImageWO",Tango::DEV_ULONG64, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong64>("DevLong64ImageRO",Tango::DEV_LONG64, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong64>("DevLong64ImageRW",Tango::DEV_LONG64, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevLong64>("DevLong64ImageWO",Tango::DEV_LONG64, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevFloat>("DevFloatImageRO",Tango::DEV_FLOAT, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevFloat>("DevFloatImageRW",Tango::DEV_FLOAT, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevFloat>("DevFloatImageWO",Tango::DEV_FLOAT, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevDouble>("DevDoubleImageRO",Tango::DEV_DOUBLE, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevDouble>("DevDoubleImageRW",Tango::DEV_DOUBLE, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevDouble>("DevDoubleImageWO",Tango::DEV_DOUBLE, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);

	add_image_attribute<Tango::DevString>("DevStringImageRO",Tango::DEV_STRING, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevString>("DevStringImageRW",Tango::DEV_STRING, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevString>("DevStringImageWO",Tango::DEV_STRING, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	
	add_image_attribute<Tango::DevState>("DevStateImageRO",Tango::DEV_STATE, Tango::READ,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	add_image_attribute<Tango::DevState>("DevStateImageRW",Tango::DEV_STATE, Tango::READ_WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	//add_image_attribute<Tango::DevState>("DevStateImageWO",Tango::DEV_STATE, Tango::WRITE,DEFAULT_IMAGE_MAX_DIM_X,DEFAULT_IMAGE_MAX_DIM_Y);
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::add_dynamic_attributes
}

//--------------------------------------------------------
/**
 *	Method     : UniversalTest::add_dynamic_commands()
 *	Description: Create the dynamic commands if any
 *                for specified device.
 */
//--------------------------------------------------------
void UniversalTest::add_dynamic_commands()
{
	/*----- PROTECTED REGION ID(UniversalTest::add_dynamic_commands) ENABLED START -----*/
	
	//	Add your own code to create and add dynamic commands if any
	
	/*----- PROTECTED REGION END -----*/	//	UniversalTest::add_dynamic_commands
}

/*----- PROTECTED REGION ID(UniversalTest::namespace_ending) ENABLED START -----*/

//	Additional Methods
// Methods for dynamic attributes

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_attr_quality_allowed()
 *	Description : Execution allowed for dynamic attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_attr_quality_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_attr_throw_allowed()
 *	Description : Execution allowed for dynamic attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_attr_throw_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_attr_usleep_allowed()
 *	Description : Execution allowed for dynamic attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_attr_usleep_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_scalar_attr_allowed()
 *	Description : Execution allowed for dynamic attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_scalar_attr_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_spectrum_attr_allowed()
 *	Description : Execution allowed for dynamic spectrum attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_spectrum_attr_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//--------------------------------------------------------
/**
 *	Method      : Undulator::is_image_attr_allowed()
 *	Description : Execution allowed for dynamic image attributes.
 */
//--------------------------------------------------------
bool UniversalTest::is_image_attr_allowed(TANGO_UNUSED(Tango::AttReqType type))
{
	/*if ( type == Tango::WRITE_REQ )
	{
		// write forbidden when state is DISABLE
		if ( get_state() == Tango::DISABLE )
		{
			return false;
		}
	}*/
	return true;
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_attr_quality()
// 
// description : 	Set quality factor of the corresponding attributes
//
//-----------------------------------------------------------------------------
void UniversalTest::write_attr_quality(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();

	DEBUG_STREAM << "In write_attr_quality() for attribute : " << attr_name << endl;		

	// get written value
	Tango::AttrQuality qual;
	attr.get_write_value(qual);
	quality_map[attr_name] = qual;
}
//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_attr_quality()
// 
// description : 	Read the current quality factor of the corresponding attribute
//
//-----------------------------------------------------------------------------
void UniversalTest::read_attr_quality(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_attr_quality  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;

	attr.set_value (&quality_map[attr_name]);
}

void UniversalTest::set_quality(Tango::Attribute &attr)
{
	string attr_name_quality_ctrl = attr.get_name() + QUALITY_CONTROL_SUFFIX;
	DEBUG_STREAM << __func__ << ":" << attr_name_quality_ctrl << "=" << quality_map[attr_name_quality_ctrl] << endl;
	switch (quality_map[attr_name_quality_ctrl])
	{
		case Tango::ATTR_VALID:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_VALID" << endl;
			break;
		case Tango::ATTR_INVALID:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_INVALID" << endl;
			break;
		case Tango::ATTR_ALARM:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_ALARM" << endl;
			break;
		case Tango::ATTR_CHANGING:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_CHANGING" << endl;
			break;
		case Tango::ATTR_WARNING:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_WARNING" << endl;
			break;
		default:
			DEBUG_STREAM << attr_name_quality_ctrl << ":UNKOWN??" << endl;
	}
	attr.set_quality(quality_map[attr_name_quality_ctrl]);
}

Tango::AttrQuality UniversalTest::get_quality(Tango::Attribute &attr)
{
	string attr_name_quality_ctrl = attr.get_name() + QUALITY_CONTROL_SUFFIX;
	map<std::string,Tango::AttrQuality>::iterator it;
	it = quality_map.find(attr_name_quality_ctrl);
	if(it == quality_map.end())
	{
		return Tango::ATTR_VALID;
	}
	DEBUG_STREAM << __func__ << ":" << attr_name_quality_ctrl << "=" << it->second << endl;
	switch (it->second)
	{
		case Tango::ATTR_VALID:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_VALID" << endl;
			break;
		case Tango::ATTR_INVALID:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_INVALID" << endl;
			break;
		case Tango::ATTR_ALARM:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_ALARM" << endl;
			break;
		case Tango::ATTR_CHANGING:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_CHANGING" << endl;
			break;
		case Tango::ATTR_WARNING:
			DEBUG_STREAM << attr_name_quality_ctrl << ":ATTR_WARNING" << endl;
			break;
		default:
			DEBUG_STREAM << attr_name_quality_ctrl << ":UNKOWN??" << endl;
	}
	return it->second;

}

void UniversalTest::throw_exception_ctrl(Tango::Attribute &attr)
{
	string attr_name_throw_ctrl = attr.get_name() + EXCEPTION_CONTROL_SUFFIX;
	string attr_name = attr.get_name();
	DEBUG_STREAM << __func__ << ":" << attr_name_throw_ctrl << "=" << throw_map[attr_name_throw_ctrl] << endl;
	if(throw_map[attr_name_throw_ctrl])
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::throw_exception(attr.get_name() + "Exception",desc.str().c_str(),__func__);
	}
}


void UniversalTest::usleep_ctrl(Tango::Attribute &attr)
{
	string attr_name_usleep_ctrl = attr.get_name() + USLEEP_CONTROL_SUFFIX;
	string attr_name = attr.get_name();
	Tango::DevLong usleep_time = usleep_map[attr_name_usleep_ctrl];
	DEBUG_STREAM << __func__ << ":" << attr_name_usleep_ctrl << "=" << usleep_time << endl;
	if(usleep_time)
	{
		std::this_thread::sleep_for(std::chrono::microseconds(usleep_time));
	}
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_attr_throw()
// 
// description : 	Set throw factor of the corresponding attributes
//
//-----------------------------------------------------------------------------
void UniversalTest::write_attr_throw(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();

	DEBUG_STREAM << "In write_attr_throw() for attribute : " << attr_name << endl;		

	// get written value
	Tango::DevBoolean w_val;
	attr.get_write_value(w_val);
	throw_map[attr_name] = w_val;
}
//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_attr_throw()
// 
// description : 	Read the current throw factor of the corresponding attribute
//
//-----------------------------------------------------------------------------
void UniversalTest::read_attr_throw(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_attr_throw  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;

	attr.set_value (&throw_map[attr_name]);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_attr_usleep()
// 
// description : 	Set usleep control of the corresponding attributes
//
//-----------------------------------------------------------------------------
void UniversalTest::write_attr_usleep(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();

	DEBUG_STREAM << "In write_attr_usleep() for attribute : " << attr_name << endl;		

	// get written value
	Tango::DevLong w_val;
	attr.get_write_value(w_val);
	usleep_map[attr_name] = w_val;
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_attr_usleep()
// 
// description : 	Read the current usleep control of the corresponding attribute
//
//-----------------------------------------------------------------------------
void UniversalTest::read_attr_usleep(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_attr_usleep  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;

	attr.set_value (&usleep_map[attr_name]);
}

//+----------------------------------------------------------------------------
//
// function : 		ends_with
// 
// description : 	Return true if the suffix ends the current string
//
//-----------------------------------------------------------------------------
bool ends_with(const std::string &str, const std::string &suffix)
{
    return str.size() >= suffix.size() &&
           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_scalar_attr()
// 
// description : 	Generic method to write attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_scalar_attr(Tango::WAttribute &attr)
{
	string attr_name = attr.get_name();
	DEBUG_STREAM << "In write_scalar_attr() for attribute : " << attr_name << endl;		
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	//	Retrieve write value
	T	w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarRWAttrib<T> * my_attr = static_cast<UniversalScalarRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	*(my_attr->scalar_attr_read) = w_val;
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_scalar_attr<Tango::DevString>()
// 
// description : 	Generic method to write scalar attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_scalar_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_scalar_attr() for attribute : " << attr_name << endl;		
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	//	Retrieve write value
	Tango::DevString	w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarRWAttrib<Tango::DevString> * my_attr = static_cast<UniversalScalarRWAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	if (*(my_attr->scalar_attr_read)) 
	{
		CORBA::string_free(*(my_attr->scalar_attr_read));
	}
	*(my_attr->scalar_attr_read) = CORBA::string_dup(w_val);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_image_attr()
// 
// description : 	Generic method to write image attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_image_attr(Tango::WAttribute &attr)
{
	string attr_name = attr.get_name();
	DEBUG_STREAM << "In write_image_attr() for attribute : " << attr_name << endl;
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time	
	//	Retrieve write value
	const T	* w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageRWAttrib<T> * my_attr = static_cast<UniversalImageRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	my_attr->dim_x = attr.get_w_dim_x();
	my_attr->dim_y = attr.get_w_dim_y();
	long len = my_attr->dim_x * my_attr->dim_y;
	memcpy(my_attr->attr_read,w_val,len * sizeof(T));
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_image_attr<Tango::DevString>()
// 
// description : 	Generic method to write string image attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_image_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	string attr_name = attr.get_name();
	DEBUG_STREAM << "In write_image_attr<Tango::DevString>() for attribute : " << attr_name << endl;		
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	//	Retrieve write value
	const Tango::ConstDevString * w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageRWAttrib<Tango::DevString> * my_attr = static_cast<UniversalImageRWAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	// Free the previously allocated strings
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		for (long y = 0; y < my_attr->dim_y; y++)
		{
			CORBA::string_free(my_attr->attr_read[y*my_attr->dim_x + x]);
		}
	}
	my_attr->dim_x = attr.get_w_dim_x();
	my_attr->dim_y = attr.get_w_dim_y();
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		for (long y = 0; y < my_attr->dim_y; y++)
		{
			my_attr->attr_read[y*my_attr->dim_x + x] = CORBA::string_dup(w_val[y*my_attr->dim_x + x]);
		}
	}
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_spectrum_attr()
// 
// description : 	Generic method to write spectrum attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_spectrum_attr(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_spectrum_attr() for attribute : " << attr_name << endl;		
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	//	Retrieve write value
	const T	* w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumRWAttrib<T> * my_attr = static_cast<UniversalSpectrumRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	my_attr->dim_x = attr.get_write_value_length();
	memcpy(my_attr->attr_read,w_val,my_attr->dim_x * sizeof(T));
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_spectrum_attr<Tango::DevString>()
// 
// description : 	Generic method to write string spectrum attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_spectrum_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_spectrum_attr<Tango::DevString>() for attribute : " << attr_name << endl;		
	
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	//	Retrieve write value
	const Tango::ConstDevString * w_val;
	attr.get_write_value(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumRWAttrib<Tango::DevString> * my_attr = static_cast<UniversalSpectrumRWAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	// Free the previously allocated strings
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		CORBA::string_free(my_attr->attr_read[x]);
	}
	my_attr->dim_x = attr.get_w_dim_x();
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		my_attr->attr_read[x] = CORBA::string_dup(w_val[x]);
	}
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_scalar_RO_Control_attr()
// 
// description : 	Method to write RO Control scalar attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_scalar_RO_Control_attr(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_scalar_RO_Control_attr() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	T	w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalScalarROAttrib<T>&  my_controlled_ro_attr = static_cast<UniversalScalarROAttrib<T> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	*(my_controlled_ro_attr.scalar_attr_read) = w_val;
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarROControlAttrib<T> * my_attr = static_cast<UniversalScalarROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	*(my_attr->scalar_attr_read) = w_val;
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_scalar_RO_Control_attr()
// 
// description : 	Method to write RO Control Tango::DevString scalar attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_scalar_RO_Control_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_scalar_RO_Control_attr<Tango::DevString>() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	Tango::DevString	w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalScalarROAttrib<Tango::DevString>&  my_controlled_ro_attr = static_cast<UniversalScalarROAttrib<Tango::DevString> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	if (*(my_controlled_ro_attr.scalar_attr_read)) 
	{
		CORBA::string_free(*(my_controlled_ro_attr.scalar_attr_read));
	}
	*(my_controlled_ro_attr.scalar_attr_read) = CORBA::string_dup(w_val);
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarROControlAttrib<Tango::DevString> * my_attr = static_cast<UniversalScalarROControlAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	if (*(my_attr->scalar_attr_read)) 
	{
		CORBA::string_free(*(my_attr->scalar_attr_read));
	}
	*(my_attr->scalar_attr_read) = CORBA::string_dup(w_val);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_spectrum_RO_Control_attr()
// 
// description : 	Method to write RO Control spectrum attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_spectrum_RO_Control_attr(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_spectrum_RO_Control_attr() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	const T	* w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalSpectrumROAttrib<T>&  my_controlled_ro_attr = static_cast<UniversalSpectrumROAttrib<T> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	my_controlled_ro_attr.dim_x = attr.get_write_value_length();
	memcpy(my_controlled_ro_attr.attr_read,w_val,my_controlled_ro_attr.dim_x * sizeof(T));
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumROControlAttrib<T> * my_attr = static_cast<UniversalSpectrumROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	my_attr->dim_x = attr.get_write_value_length();
	memcpy(my_attr->attr_read,w_val,my_attr->dim_x * sizeof(T));
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_spectrum_RO_Control_attr()
// 
// description : 	Method to write RO Control Tango::DevString spectrum attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_spectrum_RO_Control_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_spectrum_RO_Control_attr<Tango::DevString>() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	const Tango::ConstDevString * w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalSpectrumROAttrib<Tango::DevString> &  my_controlled_ro_attr = static_cast<UniversalSpectrumROAttrib<Tango::DevString> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	// Free the previously allocated strings
	for (long x = 0; x < my_controlled_ro_attr.dim_x; x++)
	{
		CORBA::string_free(my_controlled_ro_attr.attr_read[x]);
	}
	my_controlled_ro_attr.dim_x = attr.get_w_dim_x();
	for (long x = 0; x < my_controlled_ro_attr.dim_x; x++)
	{
		my_controlled_ro_attr.attr_read[x] = CORBA::string_dup(w_val[x]);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumROControlAttrib<Tango::DevString> * my_attr = static_cast<UniversalSpectrumROControlAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	// Free the previously allocated strings
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		CORBA::string_free(my_attr->attr_read[x]);
	}
	my_attr->dim_x = attr.get_w_dim_x();
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		my_attr->attr_read[x] = CORBA::string_dup(w_val[x]);
	}
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_image_RO_Control_attr()
// 
// description : 	Method to write RO Control image attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::write_image_RO_Control_attr(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_image_RO_Control_attr() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	const T	* w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalImageROAttrib<T>&  my_controlled_ro_attr = static_cast<UniversalImageROAttrib<T> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	my_controlled_ro_attr.dim_x = attr.get_w_dim_x();
	my_controlled_ro_attr.dim_y = attr.get_w_dim_y();
	memcpy(my_controlled_ro_attr.attr_read,w_val,my_controlled_ro_attr.dim_x * my_controlled_ro_attr.dim_y * sizeof(T));
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageROControlAttrib<T> * my_attr = static_cast<UniversalImageROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	my_attr->dim_x = attr.get_w_dim_x();
	my_attr->dim_y = attr.get_w_dim_y();
	memcpy(my_attr->attr_read,w_val,my_attr->dim_x * my_attr->dim_y * sizeof(T));
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::write_image_RO_Control_attr()
// 
// description : 	Method to write RO Control Tango::DevString image attributes
//
//-----------------------------------------------------------------------------
template <>
void UniversalTest::write_image_RO_Control_attr<Tango::DevString>(Tango::WAttribute &attr)
{
	Tango::WAttribute &att = attr;
	string attr_name = att.get_name();
	DEBUG_STREAM << "In write_image_RO_Control_attr<Tango::DevString>() for attribute : " << attr_name << endl;		
	
	//	Retrieve write value
	const Tango::ConstDevString * w_val;
	attr.get_write_value(w_val);
	string controlled_attr_name = attr_name.substr(0,attr_name.size() - RO_READ_VALUE_CONTROL_SUFFIX.size());
	UniversalImageROAttrib<Tango::DevString> &  my_controlled_ro_attr = static_cast<UniversalImageROAttrib<Tango::DevString> &>(get_device_class()->get_class_attr()->get_attr(controlled_attr_name));
	// Free the previously allocated strings
	for (long x = 0; x < my_controlled_ro_attr.dim_x; x++)
	{
		for (long y = 0; y < my_controlled_ro_attr.dim_y; y++)
		{
			CORBA::string_free(my_controlled_ro_attr.attr_read[y*my_controlled_ro_attr.dim_x + x]);
		}
	}
	my_controlled_ro_attr.dim_x = attr.get_w_dim_x();
	my_controlled_ro_attr.dim_y = attr.get_w_dim_y();
	for (long x = 0; x < my_controlled_ro_attr.dim_x; x++)
	{
		for (long y = 0; y < my_controlled_ro_attr.dim_y; y++)
		{
			my_controlled_ro_attr.attr_read[y*my_controlled_ro_attr.dim_x + x] = CORBA::string_dup(w_val[y*my_controlled_ro_attr.dim_x + x]);
		}
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageROControlAttrib<Tango::DevString> * my_attr = static_cast<UniversalImageROControlAttrib<Tango::DevString> *>(att_list[attr.get_attr_idx()]);
	// Free the previously allocated strings
	for (long x = 0; x < my_attr->dim_x; x++)
	{	
		for (long y = 0; y < my_attr->dim_y; y++)
		{
			CORBA::string_free(my_attr->attr_read[y*my_attr->dim_x + x]);
		}
	}
	my_attr->dim_x = attr.get_w_dim_x();
	my_attr->dim_y = attr.get_w_dim_y();
	for (long x = 0; x < my_attr->dim_x; x++)
	{
		for (long y = 0; y < my_attr->dim_y; y++)
		{
			my_attr->attr_read[y*my_attr->dim_x + x] = CORBA::string_dup(w_val[y*my_attr->dim_x + x]);
		}
	}
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_scalar_attr()
// 
// description : 	Generic read scalar attribute method
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_scalar_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_scalar_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarRWAttrib<T> * my_attr = static_cast<UniversalScalarRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->scalar_attr_read);
	}
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_image_attr()
// 
// description : 	Generic read attribute method for image attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_image_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_image_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageRWAttrib<T> * my_attr = static_cast<UniversalImageRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->attr_read,my_attr->dim_x,my_attr->dim_y);
	}
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_spectrum_attr()
// 
// description : 	Generic read attribute method for spectrum attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_spectrum_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_spectrum_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumRWAttrib<T> * my_attr = static_cast<UniversalSpectrumRWAttrib<T> *>(att_list[attr.get_attr_idx()]);
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->attr_read,my_attr->dim_x);
	}
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_ctrl_scalar_attr()
// 
// description : 	Read attribute method for RO_ctrl scalar attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_ctrl_scalar_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_ctrl_scalar_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarROControlAttrib<T> * my_attr = static_cast<UniversalScalarROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	attr.set_value (my_attr->scalar_attr_read);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_ctrl_spectrum_attr()
// 
// description : 	Read attribute method for RO_ctrl spectrum attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_ctrl_spectrum_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_ctrl_spectrum_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumROControlAttrib<T> * my_attr = static_cast<UniversalSpectrumROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	attr.set_value (my_attr->attr_read,my_attr->dim_x);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_ctrl_image_attr()
// 
// description : 	Read attribute method for RO_ctrl image attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_ctrl_image_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_ctrl_image_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageROControlAttrib<T> * my_attr = static_cast<UniversalImageROControlAttrib<T> *>(att_list[attr.get_attr_idx()]);
	attr.set_value (my_attr->attr_read,my_attr->dim_x,my_attr->dim_y);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_scalar_attr()
// 
// description : 	Generic read attribute method
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_scalar_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_scalar_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalScalarROAttrib<T> * my_attr = static_cast<UniversalScalarROAttrib<T> *>(att_list[attr.get_attr_idx()]);
	// TODO : Implement several behaviours
	//*(my_attr->scalar_attr_read) = (*(my_attr->scalar_attr_read)) + 1;
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->scalar_attr_read);
	}
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_spectrum_attr()
// 
// description : 	Generic read attribute method for RO spectrum attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_spectrum_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_spectrum_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalSpectrumROAttrib<T> * my_attr = static_cast<UniversalSpectrumROAttrib<T> *>(att_list[attr.get_attr_idx()]);
	// TODO : Implement several behaviours
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->attr_read,my_attr->dim_x);
	}
	set_quality(attr);
}

//+----------------------------------------------------------------------------
//
// method : 		UniversalTest::read_RO_image_attr()
// 
// description : 	Generic read attribute method for RO image attributes
//
//-----------------------------------------------------------------------------
template <class T>
void UniversalTest::read_RO_image_attr(Tango::Attribute &attr)
{
	string &attr_name = attr.get_name();

	DEBUG_STREAM << "UniversalTest::read_RO_image_attr  - " << device_name << endl;
	DEBUG_STREAM << "for attribute " << attr_name << endl;
	usleep_ctrl(attr); // Eventually sleep for a defined period of time
	try
	{
		throw_exception_ctrl(attr);
	}
	catch(Tango::DevFailed &e)
	{
		stringstream desc;
		desc << "Exception while reading " <<  attr_name << " attribute" << ends;
		Tango::Except::re_throw_exception(e,attr.get_name() + "ReadException",desc.str().c_str(),__func__);
	}
	vector<Tango::Attr *> &att_list = get_device_class()->get_class_attr()->get_attr_list();
	UniversalImageROAttrib<T> * my_attr = static_cast<UniversalImageROAttrib<T> *>(att_list[attr.get_attr_idx()]);
	// TODO : Implement several behaviours
	if(get_quality(attr) != Tango::ATTR_INVALID)
	{
		attr.set_value (my_attr->attr_read,my_attr->dim_x,my_attr->dim_y);
	}
	set_quality(attr);
}

void UniversalTest::add_scalar_attr(const std::string & attr_name,
                                    long data_type,
                                    Tango::AttrWriteType w_type)
{
	switch(data_type)
	{
		case Tango::DEV_BOOLEAN:
			add_scalar_attribute<Tango::DevBoolean>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_UCHAR:
			add_scalar_attribute<Tango::DevUChar>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_USHORT:
			add_scalar_attribute<Tango::DevUShort>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_SHORT:
			add_scalar_attribute<Tango::DevShort>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_ULONG:
			add_scalar_attribute<Tango::DevULong>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_LONG:
			add_scalar_attribute<Tango::DevLong>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_ULONG64:
			add_scalar_attribute<Tango::DevULong64>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_LONG64:
			add_scalar_attribute<Tango::DevLong64>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_FLOAT:
			add_scalar_attribute<Tango::DevFloat>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_DOUBLE:
			add_scalar_attribute<Tango::DevDouble>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_STRING:
			add_scalar_attribute<Tango::DevString>(attr_name,data_type,w_type);
			break;
		case Tango::DEV_STATE:
			add_scalar_attribute<Tango::DevState>(attr_name,data_type,w_type);
			break;
		default:
			ERROR_STREAM << "UniversalTest::add_scalar_attr(" << attr_name << ",...): Unknown data type ("
			             << data_type << ")" << endl;
	}
}


template <class T>
void UniversalTest::add_scalar_attribute(const string & attr_name, 
                                         long data_type,
                                         Tango::AttrWriteType w_type)
{
	Tango::Attr *new_attr;
	DEBUG_STREAM << "creating : " << attr_name << endl;
	if(w_type == Tango::READ)
	{
		new_attr = new UniversalScalarROAttrib<T> (attr_name.c_str(), data_type);
	}
	else
	{
		new_attr = new UniversalScalarRWAttrib<T> (attr_name.c_str(), data_type, w_type);
	}
	/*Tango::UserDefaultAttrProp attr_prop;
	attr_prop.set_description	(new_attr_name + " description");
	new_attr->set_default_properties (attr_prop);*/
	new_attr->set_disp_level(Tango::OPERATOR);
	add_attribute(new_attr);
	// Set the default write value
	if((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE))
	{
		set_default_write_value<T>(attr_name,1,0);
	}
	// Create Usleep Control Attribute
	add_usleep_control_attribute(attr_name);
	if((w_type != Tango::WRITE) && (w_type != Tango::READ_WITH_WRITE))
	{
		// Create Quality Factor Control Attribute
		add_quality_control_attribute(attr_name);
		// Create Exception Throwing Control Attribute
		add_throw_except_control_attribute(attr_name);
		if(w_type == Tango::READ)
		{
			add_RO_attr_read_value_control_attribute<T>(attr_name,data_type);
		}
	}
}

/**
 * UniversalTest::add_image_attribute()
 *
 * This method will create a dynamic spectrum attribute
 * 
 * @param attr_name: name of the attribute to be created
 * @param data_type: The Tango data type of the attribute
 * @param max_dim_x: The maximum X dimension for the image attribute
 * @param max_dim_y: the maximum Y dimension for the image attribute
 * @param w_type: write type of the attribute (Tango::READ, Tango::WRITE, Tango::READ_WRITE)
 */
template <class T>
void UniversalTest::add_image_attribute(const string & attr_name, 
                                        long data_type,
                                        Tango::AttrWriteType w_type,
                                        long max_dim_x,
                                        long max_dim_y)
{
	Tango::ImageAttr *new_attr;
	DEBUG_STREAM << "creating : " << attr_name << endl;
	if(w_type == Tango::READ)
	{
		new_attr = new UniversalImageROAttrib<T> (attr_name.c_str(), data_type,max_dim_x,max_dim_y);
	}
	else
	{
		new_attr = new UniversalImageRWAttrib<T> (attr_name.c_str(), data_type, w_type, max_dim_x, max_dim_y);
	}
	/*Tango::UserDefaultAttrProp attr_prop;
	attr_prop.set_description	(new_attr_name + " description");
	new_attr->set_default_properties (attr_prop);*/
	new_attr->set_disp_level(Tango::OPERATOR);
	add_attribute(new_attr);
	// Set the default write value
	if((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE))
	{
		set_default_write_value<T>(attr_name,max_dim_x,max_dim_y);
	}
	// Create Usleep Control Attribute
	add_usleep_control_attribute(attr_name);
	if((w_type != Tango::WRITE) && (w_type != Tango::READ_WITH_WRITE))
	{
		// Create Quality Factor Control Attribute
		add_quality_control_attribute(attr_name);
		// Create Exception Throwing Control Attribute
		add_throw_except_control_attribute(attr_name);
		if(w_type == Tango::READ)
		{
			add_RO_attr_read_value_control_attribute<T>(attr_name,data_type,max_dim_x,max_dim_y);
		}
	}
}

/**
 * UniversalTest::add_spectrum_attribute()
 *
 * This method will create a dynamic spectrum attribute
 * 
 * @param attr_name: name of the attribute to be created
 * @param data_type: The Tango data type of the attribute
 * @param max_dim_x: The maximum X dimension for the spectrum attribute
 * @param w_type: write type of the attribute (Tango::READ, Tango::WRITE, Tango::READ_WRITE)
 */
template <class T>
void UniversalTest::add_spectrum_attribute(const string & attr_name, 
                                           long data_type,
                                           Tango::AttrWriteType w_type,
                                           long max_dim_x)
{
	Tango::SpectrumAttr *new_attr;
	DEBUG_STREAM << "creating : " << attr_name << endl;
	if(w_type == Tango::READ)
	{
		new_attr = new UniversalSpectrumROAttrib<T> (attr_name.c_str(), data_type,max_dim_x);
	}
	else
	{
		new_attr = new UniversalSpectrumRWAttrib<T> (attr_name.c_str(), data_type, w_type, max_dim_x);
	}
	/*Tango::UserDefaultAttrProp attr_prop;
	attr_prop.set_description	(new_attr_name + " description");
	new_attr->set_default_properties (attr_prop);*/
	new_attr->set_disp_level(Tango::OPERATOR);
	add_attribute(new_attr);
	if((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE))
	{
		// Set the default write value
		set_default_write_value<T>(attr_name,max_dim_x);
	}
	// Create Usleep Control Attribute
	add_usleep_control_attribute(attr_name);
	if((w_type != Tango::WRITE) && (w_type != Tango::READ_WITH_WRITE))
	{
		// Create Quality Factor Control Attribute
		add_quality_control_attribute(attr_name);
		// Create Exception Throwing Control Attribute
		add_throw_except_control_attribute(attr_name);
		if(w_type == Tango::READ)
		{
			add_RO_attr_read_value_control_attribute<T>(attr_name,data_type,max_dim_x);
		}
	}
}

void UniversalTest::add_quality_control_attribute(const string & att_name)
{
	// Create Quality Factor Control Attribute
	DEBUG_STREAM << "ATTRIBUTE TO BE ADDED: " << att_name << QUALITY_CONTROL_SUFFIX << endl;
	Tango::Attr *qual_attr;
	string qual_attr_name = att_name + QUALITY_CONTROL_SUFFIX;
	DEBUG_STREAM << "creating : " << qual_attr_name << endl;
	qual_attr = new UniversalScalarQualityAttrib (qual_attr_name.c_str());
	Tango::UserDefaultAttrProp qual_attr_prop;
	stringstream quality_ctrl_desc;
	quality_ctrl_desc << "Attribute to control " << att_name << " attribute quality factor." << ends;
	qual_attr_prop.set_description	(quality_ctrl_desc.str().c_str());
	vector<string> labels;
	labels.push_back("VALID");
	labels.push_back("INVALID");
	labels.push_back("ALARM");
	labels.push_back("CHANGING");
	labels.push_back("WARNING");
	qual_attr_prop.set_enum_labels(labels);
	qual_attr->set_default_properties (qual_attr_prop);
	qual_attr->set_disp_level(Tango::EXPERT);
	quality_map[qual_attr_name] = Tango::ATTR_VALID;
	add_attribute(qual_attr);
	// initialize set value to ATTR_VALID
	Tango::WAttribute &qual_ctrl_attr =  get_device_attr()->get_w_attr_by_name(qual_attr_name.c_str());
	qual_ctrl_attr.set_write_value(static_cast<short>(Tango::ATTR_VALID));
}

void UniversalTest::add_usleep_control_attribute(const string & att_name)
{
	// Create Sleep Control Attribute
	DEBUG_STREAM << "ATTRIBUTE TO BE ADDED: " << att_name << USLEEP_CONTROL_SUFFIX << endl;
	Tango::Attr *usleep_attr;
	string usleep_attr_name = att_name + USLEEP_CONTROL_SUFFIX;
	DEBUG_STREAM << "creating : " << usleep_attr_name << endl;
	usleep_attr = new UniversalScalarUSleepAttrib (usleep_attr_name.c_str());
	Tango::UserDefaultAttrProp usleep_attr_prop;
	stringstream usleep_ctrl_desc;
	usleep_ctrl_desc << "Attribute to control " << att_name << " sleep time when the attribute is read (and/or written for writable attributes)" << ends;
	usleep_attr_prop.set_description	(usleep_ctrl_desc.str().c_str());
	usleep_attr_prop.set_unit("us");
	usleep_attr_prop.set_format("%10d");
	usleep_attr->set_default_properties (usleep_attr_prop);
	usleep_attr->set_disp_level(Tango::EXPERT);
	usleep_map[usleep_attr_name] = 0;
	add_attribute(usleep_attr);
	// initialize set value to 0
	set_default_write_value<Tango::DevLong>(usleep_attr_name,1,0);
}

void UniversalTest::add_throw_except_control_attribute(const string & att_name)
{
	// Create Throw Exception Control Attribute
	DEBUG_STREAM << "ATTRIBUTE TO BE ADDED: " << att_name << EXCEPTION_CONTROL_SUFFIX << endl;
	Tango::Attr *throw_attr;
	string throw_attr_name = att_name + EXCEPTION_CONTROL_SUFFIX;
	DEBUG_STREAM << "creating : " << throw_attr_name << endl;
	throw_attr = new UniversalScalarThrowExceptionAttrib (throw_attr_name.c_str());
	Tango::UserDefaultAttrProp throw_attr_prop;
	stringstream desc;
	desc << "Attribute to control whether " << att_name << " attribute will throw exceptions or not." << endl;
	desc << "True  => an exception will be thrown when " << att_name << " attribute will be read." << endl;
	desc << "False => no exception will be thrown when " << att_name << " attribute will be read." << endl;
	throw_attr_prop.set_description	(desc.str().c_str());
	throw_attr->set_default_properties (throw_attr_prop);
	throw_attr->set_disp_level(Tango::EXPERT);
	throw_map[throw_attr_name] = false;
	add_attribute(throw_attr);
	// initialize set value to false
	Tango::WAttribute &throw_ctrl_attr =  get_device_attr()->get_w_attr_by_name(throw_attr_name.c_str());
	throw_ctrl_attr.set_write_value(false);
}

template <class T>
void UniversalTest::add_RO_attr_read_value_control_attribute(const string & att_name,
                                                             long data_type,
                                                             long max_dim_x,
                                                             long max_dim_y)
{
	// Create RO Read value Control Attribute
	DEBUG_STREAM << "ATTRIBUTE TO BE ADDED: " << att_name << RO_READ_VALUE_CONTROL_SUFFIX << endl;
	Tango::Attr *ro_read_value_ctrl_attr;
	string ro_read_value_ctrl_attr_name = att_name + RO_READ_VALUE_CONTROL_SUFFIX;
	DEBUG_STREAM << "creating : " << ro_read_value_ctrl_attr_name << endl;
	if((max_dim_x == 0) && (max_dim_y == 0))
	{
		// Scalar attribute
		ro_read_value_ctrl_attr = new UniversalScalarROControlAttrib<T> (ro_read_value_ctrl_attr_name.c_str(),data_type);
	}
	else if ((max_dim_x >= 1) && (max_dim_y == 0))
	{
		// Spectrum attribute
		ro_read_value_ctrl_attr = new UniversalSpectrumROControlAttrib<T> (ro_read_value_ctrl_attr_name.c_str(),data_type, max_dim_x);
	}
	else if ((max_dim_x >= 1) && (max_dim_y >= 1))
	{
		// Image attribute
		ro_read_value_ctrl_attr = new UniversalImageROControlAttrib<T> (ro_read_value_ctrl_attr_name.c_str(),
		                                                                data_type, 
		                                                                max_dim_x,
		                                                                max_dim_y);
	}
	else
	{
		stringstream desc;
		desc << "add_RO_attr_read_value_control_attribute("<< att_name << "," 
		     << data_type << "," << max_dim_x << "," << max_dim_y << "): max_dim_x or max_dim_y argin parameter is out of range." << ends;
		Tango::Except::throw_exception("OutOfBoundException",desc.str().c_str(),__func__);
	}
	Tango::UserDefaultAttrProp ro_read_value_ctrl_attr_prop;
	stringstream desc;
	desc << "Attribute to control the read value returned by " << att_name << " attribute." << ends;
	ro_read_value_ctrl_attr_prop.set_description	(desc.str().c_str());
	ro_read_value_ctrl_attr->set_default_properties (ro_read_value_ctrl_attr_prop);
	ro_read_value_ctrl_attr->set_disp_level(Tango::EXPERT);
	add_attribute(ro_read_value_ctrl_attr);
	// set default write value
	set_default_write_value<T>(ro_read_value_ctrl_attr_name,max_dim_x,max_dim_y);
}

/**
 * set_default_write_value(): Will initialize the corresponding attribute set value to a default value
 *
 * @param attr_name: name of the attribute on which we want to set the default write value
 * @param dim_x: X dimension of the attribute default write value
 * @param dim_y: Y dimension of the attribute default write value
 */
template <class T> 
void UniversalTest::set_default_write_value(const string & attr_name, long dim_x, long dim_y)
{
	DEBUG_STREAM << "set_default_write_value(" << attr_name << "," << dim_x << "," << dim_y << ")" << endl;
	Tango::WAttribute & my_attr =  get_device_attr()->get_w_attr_by_name(attr_name.c_str());
	// Set the default write value
	if((dim_x <=1) && (dim_y <= 1))
	{
		// Scalar Attribute
		T attr_def_set_val = 0;
		my_attr.set_write_value(attr_def_set_val);
	}
	else if (dim_y == 0)
	{
		// Spectrum attribute
		T * attr_def_set_val = new T[dim_x];
		std::memset(attr_def_set_val,0,dim_x * sizeof(T));
		my_attr.set_write_value(attr_def_set_val,dim_x);
		delete [] attr_def_set_val;
	}
	else
	{
		// Spectrum or Image attribute
		T * attr_def_set_val = new T[dim_x * dim_y];
		std::memset(attr_def_set_val,0,dim_x * dim_y * sizeof(T));
		my_attr.set_write_value(attr_def_set_val,dim_x,dim_y);
		delete [] attr_def_set_val;
	}
}

/**
 * set_default_write_value<Tango::DevString>(): Will initialize the corresponding attribute set value to a default value
 *
 * @param attr_name: name of the attribute on which we want to set the default write value
 * @param dim_x: X dimension of the attribute default write value
 * @param dim_y: Y dimension of the attribute default write value
 */
template <> 
void UniversalTest::set_default_write_value<Tango::DevString>(const string & attr_name, long dim_x, long dim_y)
{
	DEBUG_STREAM << "set_default_write_value<Tango::DevString>(" << attr_name << "," << dim_x << "," << dim_y << ")" << endl;
	// Set the default write value
	Tango::WAttribute & my_attr =  get_device_attr()->get_w_attr_by_name(attr_name.c_str());
	if((dim_x <=1) && (dim_y <= 1))
	{
		// Scalar Attribute
		string attr_def_set_val = "Rock n Roll";
		my_attr.set_write_value(attr_def_set_val);
	}
	else if (dim_y == 0)
	{
		// Spectrum attribute
		Tango::DevString * attr_def_set_val = new Tango::DevString[dim_x];
		for(long x = 0; x < dim_x; x++)
		{
			stringstream ss;
			ss << "default_string[" << x << "]" << ends;
			attr_def_set_val[x] = CORBA::string_dup(ss.str().c_str());
		}
		my_attr.set_write_value(attr_def_set_val,dim_x);
		for(long x = 0; x < dim_x; x++)
		{
			CORBA::string_free(attr_def_set_val[x]);
		}
		delete [] attr_def_set_val;
	}
	else
	{
		Tango::DevString * attr_def_set_val = new Tango::DevString[dim_x * dim_y];
		for(long x = 0; x < dim_x; x++)
		{
			for(long y=0; y < dim_y; y++)
			{
				stringstream ss;
				ss << "default_string[" << y << "][" << x << "]" << ends;
				attr_def_set_val[(y*dim_x) + x] = CORBA::string_dup(ss.str().c_str());
			}
		}
		my_attr.set_write_value(attr_def_set_val,dim_x,dim_y);
		for(long x = 0; x < dim_x; x++)
		{
			for(long y=0; y < dim_y; y++)
			{
				CORBA::string_free(attr_def_set_val[(y*dim_x) + x]);
			}
		}
		delete [] attr_def_set_val;
	}
}

/**
 * set_default_write_value<Tango::DevState>(): Will initialize the corresponding attribute set value to a default value
 *
 * @param attr_name: name of the attribute on which we want to set the default write value
 * @param dim_x: X dimension of the attribute default write value
 * @param dim_y: Y dimension of the attribute default write value
 */
template <> 
void UniversalTest::set_default_write_value<Tango::DevState>(const string & attr_name, long dim_x, long dim_y)
{
	DEBUG_STREAM << "Entering set_default_write_value<Tango::DevState>(" << attr_name << ")" << endl;
	// Set the default write value
	Tango::WAttribute & my_attr =  get_device_attr()->get_w_attr_by_name(attr_name.c_str());
	if((dim_x <=1) && (dim_y <= 1))
	{
		// Scalar Attribute
		DEBUG_STREAM << "set_default_write_value<Tango::DevState>(" << attr_name << "): scalar attribute" << endl;
		my_attr.set_write_value(DEFAULT_STATE_VALUE);
	}
	else if (dim_y == 0)
	{
		// Spectrum attribute
		Tango::DevState * attr_def_set_val = new Tango::DevState[dim_x];
		for(long x = 0; x < dim_x; x++)
		{
			attr_def_set_val[x] = DEFAULT_STATE_VALUE;
		}
		DEBUG_STREAM << "set_default_write_value<Tango::DevState>(" << attr_name << "): spectrum attribute" << endl;
		my_attr.set_write_value(attr_def_set_val,dim_x);
		delete [] attr_def_set_val;
	}
	else
	{
		Tango::DevState * attr_def_set_val = new Tango::DevState[dim_x * dim_y];
		for(long x = 0; x < dim_x; x++)
		{
			for(long y=0; y < dim_y; y++)
			{
				attr_def_set_val[(y*dim_x) + x] = DEFAULT_STATE_VALUE;
			}
		}
		DEBUG_STREAM << "set_default_write_value<Tango::DevState>(" << attr_name << "): image attribute" << endl;
		my_attr.set_write_value(attr_def_set_val,dim_x,dim_y);
		delete [] attr_def_set_val;
	}
}

template <>
UniversalScalarRWAttrib<Tango::DevString>::UniversalScalarRWAttrib(const char *name,long data_type,Tango::AttrWriteType w_type)
		:Attr(name,data_type,w_type)
{
		scalar_attr_read = new Tango::DevString;
		*scalar_attr_read = CORBA::string_dup("Rock n Roll");
}

template <>
UniversalScalarRWAttrib<Tango::DevState>::UniversalScalarRWAttrib(const char *name,long data_type,Tango::AttrWriteType w_type)
		:Attr(name,data_type,w_type)
{
		scalar_attr_read = new Tango::DevState;
		*scalar_attr_read = UniversalTest::DEFAULT_STATE_VALUE;
}

template <>
UniversalScalarRWAttrib<Tango::DevString>::~UniversalScalarRWAttrib ()
{
	if (*scalar_attr_read) 
	{
		CORBA::string_free(*scalar_attr_read);
    }
	delete scalar_attr_read;
}


template <>
UniversalScalarROControlAttrib<Tango::DevString>::UniversalScalarROControlAttrib(const char *name,long data_type)
		:Attr(name,data_type,Tango::READ_WRITE)
{
		scalar_attr_read = new Tango::DevString;
		*scalar_attr_read = CORBA::string_dup("Rock n Roll");
}

template <>
UniversalScalarROControlAttrib<Tango::DevState>::UniversalScalarROControlAttrib(const char *name,long data_type)
		:Attr(name,data_type,Tango::READ_WRITE)
{
		scalar_attr_read = new Tango::DevState;
		*scalar_attr_read = UniversalTest::DEFAULT_STATE_VALUE;
}

template <>
UniversalScalarROControlAttrib<Tango::DevString>::~UniversalScalarROControlAttrib ()
{
	if (*scalar_attr_read) 
	{
		CORBA::string_free(*scalar_attr_read);
    }
	delete scalar_attr_read;
}

template <>
UniversalSpectrumROControlAttrib<Tango::DevString>::UniversalSpectrumROControlAttrib(const char *name,long data_type,long max_dim_x)
		:SpectrumAttr(name,data_type,Tango::READ_WRITE,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevString[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		stringstream ss;
		ss << "default_string[" << x << "]" << ends;
		attr_read[x] = CORBA::string_dup(ss.str().c_str());
	}
}

template <>
UniversalSpectrumROControlAttrib<Tango::DevState>::UniversalSpectrumROControlAttrib(const char *name,long data_type, long max_dim_x)
		:SpectrumAttr(name,data_type,Tango::READ_WRITE,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevState[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		attr_read[x] = UniversalTest::DEFAULT_STATE_VALUE;
	}
}

template <>
UniversalSpectrumROControlAttrib<Tango::DevString>::~UniversalSpectrumROControlAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		CORBA::string_free(attr_read[x]);
	}
	delete [] attr_read;
}

template <>
UniversalImageROControlAttrib<Tango::DevString>::UniversalImageROControlAttrib(const char *name,
                                                                               long data_type,
                                                                               long max_dim_x,
                                                                               long max_dim_y)
		:ImageAttr(name,data_type,Tango::READ_WRITE,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevString[dim_x*dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y = 0; y < dim_y; y++)
		{
			stringstream ss;
			ss << "default_string[" << x << "][" << y << "]" << ends;
			attr_read[y*dim_x + x] = CORBA::string_dup(ss.str().c_str());
		}
	}
}

template <>
UniversalImageROControlAttrib<Tango::DevState>::UniversalImageROControlAttrib(const char *name,
                                                                              long data_type,
                                                                              long max_dim_x,
                                                                              long max_dim_y)
		:ImageAttr(name,data_type,Tango::READ_WRITE,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevState[dim_x*dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y = 0; y < dim_y; y++)
		{
			attr_read[y*dim_x + x] = UniversalTest::DEFAULT_STATE_VALUE;
		}
	}
}

template <>
UniversalImageROControlAttrib<Tango::DevString>::~UniversalImageROControlAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		for(long y=0; y < dim_y; y++)
		{
			CORBA::string_free(attr_read[(y*dim_x) + x]);
		}
	}
	delete [] attr_read;
}

template <>
UniversalScalarROAttrib<Tango::DevString>::UniversalScalarROAttrib (const char *name,long data_type)
	:Attr(name,data_type,Tango::READ)
{
	scalar_attr_read = new Tango::DevString;
	*scalar_attr_read = CORBA::string_dup("Rock n Roll");
}

template <>
UniversalScalarROAttrib<Tango::DevState>::UniversalScalarROAttrib (const char *name,long data_type)
	:Attr(name,data_type,Tango::READ)
{
	scalar_attr_read = new Tango::DevState;
	*scalar_attr_read = UniversalTest::DEFAULT_STATE_VALUE;
}

template <>
UniversalScalarROAttrib<Tango::DevString>::~UniversalScalarROAttrib ()
{
	if (*scalar_attr_read) 
	{
		CORBA::string_free(*scalar_attr_read);
    }
	delete scalar_attr_read;
}

template <>
UniversalSpectrumROAttrib<Tango::DevString>::UniversalSpectrumROAttrib (const char *name,long data_type, long max_dim_x)
	:SpectrumAttr(name,data_type,Tango::READ,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevString[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		stringstream ss;
		ss << "default_string[" << x << "]" << ends;
		attr_read[x] = CORBA::string_dup(ss.str().c_str());
	}
}

template <>
UniversalSpectrumROAttrib<Tango::DevState>::UniversalSpectrumROAttrib (const char *name,long data_type, long max_dim_x)
	:SpectrumAttr(name,data_type,Tango::READ,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevState[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		attr_read[x] = UniversalTest::DEFAULT_STATE_VALUE;
	}
}

template <>
UniversalSpectrumROAttrib<Tango::DevString>::~UniversalSpectrumROAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		CORBA::string_free(attr_read[x]);
	}
	delete [] attr_read;
}

template <>
UniversalImageROAttrib<Tango::DevString>::UniversalImageROAttrib (const char *name,
                                                                  long data_type,
                                                                  long max_dim_x,
                                                                  long max_dim_y)
	:ImageAttr(name,data_type,Tango::READ,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevString[dim_x*dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y = 0; y < dim_y; y++)
		{
			stringstream ss;
			ss << "default_string[" << x << "][" << y << "]" << ends;
			attr_read[y*dim_x + x] = CORBA::string_dup(ss.str().c_str());
		}
	}
}

template <>
UniversalImageROAttrib<Tango::DevState>::UniversalImageROAttrib (const char *name,
                                                                  long data_type,
                                                                  long max_dim_x,
                                                                  long max_dim_y)
	:ImageAttr(name,data_type,Tango::READ,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevState[dim_x*dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y = 0; y < dim_y; y++)
		{
			attr_read[y*dim_x + x] = UniversalTest::DEFAULT_STATE_VALUE;
		}
	}
}
template <>
UniversalImageROAttrib<Tango::DevString>::~UniversalImageROAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		for(long y=0; y < dim_y; y++)
		{
			CORBA::string_free(attr_read[(y*dim_x) + x]);
		}
	}
	delete [] attr_read;
}

template <>
UniversalSpectrumRWAttrib<Tango::DevString>::UniversalSpectrumRWAttrib (const char *name,long data_type,Tango::AttrWriteType w_type,long max_dim_x)
	:SpectrumAttr(name,data_type,w_type,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevString[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		stringstream ss;
		ss << "default_string[" << x << "]" << ends;
		attr_read[x] = CORBA::string_dup(ss.str().c_str());
	}
}

template <>
UniversalSpectrumRWAttrib<Tango::DevState>::UniversalSpectrumRWAttrib (const char *name,long data_type,Tango::AttrWriteType w_type,long max_dim_x)
	:SpectrumAttr(name,data_type,w_type,max_dim_x)
{
	dim_x = max_dim_x? max_dim_x:1;
	attr_read = new Tango::DevState[dim_x];
	for(long x = 0; x < dim_x; x++)
	{
		attr_read[x] = UniversalTest::DEFAULT_STATE_VALUE;
	}
}

template <>
UniversalSpectrumRWAttrib<Tango::DevString>::~UniversalSpectrumRWAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		CORBA::string_free(attr_read[x]);
	}
	delete [] attr_read;
}

template <>
UniversalImageRWAttrib<Tango::DevString>::UniversalImageRWAttrib (const char *name,long data_type,Tango::AttrWriteType w_type,long max_dim_x,long max_dim_y)
	:ImageAttr(name,data_type,w_type,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevString[dim_x * dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y=0; y < dim_y; y++)
		{
			stringstream ss;
			ss << "default_string[" << y << "][" << x << "]" << ends;
			attr_read[(y*dim_x) + x] = CORBA::string_dup(ss.str().c_str());
		}
	}
}

template <>
UniversalImageRWAttrib<Tango::DevState>::UniversalImageRWAttrib (const char *name,long data_type,Tango::AttrWriteType w_type,long max_dim_x,long max_dim_y)
	:ImageAttr(name,data_type,w_type,max_dim_x,max_dim_y)
{
	dim_x = max_dim_x? max_dim_x:1;
	dim_y = max_dim_y? max_dim_y:1;
	attr_read = new Tango::DevState[dim_x * dim_y];
	for(long x = 0; x < dim_x; x++)
	{
		for(long y=0; y < dim_y; y++)
		{
			attr_read[(y*dim_x) + x] = UniversalTest::DEFAULT_STATE_VALUE;
		}
	}
}

template <>
UniversalImageRWAttrib<Tango::DevString>::~UniversalImageRWAttrib ()
{
	for(long x = 0; x < dim_x; x++)
	{
		for(long y=0; y < dim_y; y++)
		{
			CORBA::string_free(attr_read[(y*dim_x) + x]);
		}
	}
	delete [] attr_read;
}

/*----- PROTECTED REGION END -----*/	//	UniversalTest::namespace_ending
} //	namespace
