/*----- PROTECTED REGION ID(TangoAccessControlClass.cpp) ENABLED START -----*/
//=============================================================================
//
// file :        TangoAccessControlClass.cpp
//
// description : C++ source for the TangoAccessControlClass. A singleton
//               class derived from DeviceClass. It implements the
//               command list and all properties and methods required
//               by the �name� once per process.
//
// project :     Tango Access Control Management.
//
//
// Copyright (C) :      2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
//						European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// 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$
//
// $Revision$
// $Date$
//
//=============================================================================
//                This file is generated by POGO
//        (Program Obviously used to Generate tango Object)
//=============================================================================


#include <tango/tango.h>
#include "TangoAccessControl.h"
#include "TangoAccessControlClass.h"

#include "Logging.h"

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

//-------------------------------------------------------------------
/**
 *	Create TangoAccessControlClass singleton and
 *	return it in a C function for Python usage
 */
//-------------------------------------------------------------------
extern "C" {
#ifdef _TG_WINDOWS_

__declspec(dllexport)

#endif

	Tango::DeviceClass *_create_TangoAccessControl_class(const char *name) {
		return TangoAccessControl_ns::TangoAccessControlClass::init(name);
	}
}

namespace TangoAccessControl_ns
{
//===================================================================
//	Initialize pointer for singleton pattern
//===================================================================
TangoAccessControlClass *TangoAccessControlClass::_instance = NULL;

//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::TangoAccessControlClass(std::string &s)
 * description : 	constructor for the TangoAccessControlClass
 *
 * @param s	The class name
 */
//--------------------------------------------------------
TangoAccessControlClass::TangoAccessControlClass(std::string &s):AccessControl_ns::AccessControlClass(s)
{
	TANGO_LOG_INFO << "Entering TangoAccessControlClass constructor" << std::endl;
	set_default_property();
	write_class_property();

	/*----- PROTECTED REGION ID(TangoAccessControlClass::constructor) ENABLED START -----*/	
	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::constructor

	TANGO_LOG_INFO << "Leaving TangoAccessControlClass constructor" << std::endl;
}

//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::~TangoAccessControlClass()
 * description : 	destructor for the TangoAccessControlClass
 */
//--------------------------------------------------------
TangoAccessControlClass::~TangoAccessControlClass()
{
	/*----- PROTECTED REGION ID(TangoAccessControlClass::destructor) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::destructor

	_instance = NULL;
}


//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::init
 * description : 	Create the object if not already done.
 *                  Otherwise, just return a pointer to the object
 *
 * @param	name	The class name
 */
//--------------------------------------------------------
TangoAccessControlClass *TangoAccessControlClass::init(const char *name)
{
	if (_instance == NULL)
	{
		try
		{
			std::string s(name);
			_instance = new TangoAccessControlClass(s);
		}
		catch (std::bad_alloc &)
		{
			throw;
		}
	}
	return _instance;
}

//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::instance
 * description : 	Check if object already created,
 *                  and return a pointer to the object
 */
//--------------------------------------------------------
TangoAccessControlClass *TangoAccessControlClass::instance()
{
	if (_instance == NULL)
	{
		std::cerr << "Class is not initialised !!" << std::endl;
		exit(-1);
	}
	return _instance;
}



//===================================================================
//	Command execution method calls
//===================================================================
//--------------------------------------------------------
/**
 * method : 		AddAddressForUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *AddAddressForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "AddAddressForUserClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->add_address_for_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		AddDeviceForUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *AddDeviceForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "AddDeviceForUserClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->add_device_for_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		CloneUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *CloneUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "CloneUserClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->clone_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		GetAccessClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetAccessClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetAccessClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_access(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetAccessForMultiIPClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetAccessForMultiIPClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetAccessForMultiIPClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_access_for_multi_ip(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetAddressByUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetAddressByUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetAddressByUserClass::execute(): arrived" << std::endl;
	Tango::DevString argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_address_by_user(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetAllowedCommandClassListClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetAllowedCommandClassListClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
	TANGO_LOG_INFO << "GetAllowedCommandClassListClass::execute(): arrived" << std::endl;
	return insert((static_cast<TangoAccessControl *>(device))->get_allowed_command_class_list());
}

//--------------------------------------------------------
/**
 * method : 		GetAllowedCommandsClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetAllowedCommandsClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetAllowedCommandsClass::execute(): arrived" << std::endl;
	Tango::DevString argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_allowed_commands(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetDeviceByUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetDeviceByUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetDeviceByUserClass::execute(): arrived" << std::endl;
	Tango::DevString argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_device_by_user(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetDeviceClassClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetDeviceClassClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "GetDeviceClassClass::execute(): arrived" << std::endl;
	Tango::DevString argin;
	extract(in_any, argin);
	return insert((static_cast<TangoAccessControl *>(device))->get_device_class(argin));
}

//--------------------------------------------------------
/**
 * method : 		GetUsersClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *GetUsersClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
	TANGO_LOG_INFO << "GetUsersClass::execute(): arrived" << std::endl;
	return insert((static_cast<TangoAccessControl *>(device))->get_users());
}

//--------------------------------------------------------
/**
 * method : 		RegisterServiceClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *RegisterServiceClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
	TANGO_LOG_INFO << "RegisterServiceClass::execute(): arrived" << std::endl;
	((static_cast<TangoAccessControl *>(device))->register_service());
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		RemoveAddressForUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *RemoveAddressForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "RemoveAddressForUserClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->remove_address_for_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		RemoveDeviceForUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *RemoveDeviceForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "RemoveDeviceForUserClass::execute(): arrived" << std::endl;
	const Tango::DevVarStringArray *argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->remove_device_for_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		RemoveUserClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *RemoveUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{
	TANGO_LOG_INFO << "RemoveUserClass::execute(): arrived" << std::endl;
	Tango::DevString argin;
	extract(in_any, argin);
	((static_cast<TangoAccessControl *>(device))->remove_user(argin));
	return new CORBA::Any();
}

//--------------------------------------------------------
/**
 * method : 		UnregisterServiceClass::execute()
 * description : 	method to trigger the execution of the command.
 *
 * @param	device	The device on which the command must be executed
 * @param	in_any	The command input data
 *
 *	returns The command output data (packed in the Any object)
 */
//--------------------------------------------------------
CORBA::Any *UnregisterServiceClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{
	TANGO_LOG_INFO << "UnregisterServiceClass::execute(): arrived" << std::endl;
	((static_cast<TangoAccessControl *>(device))->unregister_service());
	return new CORBA::Any();
}


//===================================================================
//	Properties management
//===================================================================
//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::get_class_property()
 *	Description : Get the class property for specified name.
 */
//--------------------------------------------------------
Tango::DbDatum TangoAccessControlClass::get_class_property(std::string &prop_name)
{
	for (unsigned int i=0 ; i<cl_prop.size() ; i++)
		if (cl_prop[i].name == prop_name)
			return cl_prop[i];
	//	if not found, returns  an empty DbDatum
	return Tango::DbDatum(prop_name);
}

//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::get_default_device_property()
 *	Description : Return the default value for device property.
 */
//--------------------------------------------------------
Tango::DbDatum TangoAccessControlClass::get_default_device_property(std::string &prop_name)
{
	for (unsigned int i=0 ; i<dev_def_prop.size() ; i++)
		if (dev_def_prop[i].name == prop_name)
			return dev_def_prop[i];
	//	if not found, return  an empty DbDatum
	return Tango::DbDatum(prop_name);
}

//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::get_default_class_property()
 *	Description : Return the default value for class property.
 */
//--------------------------------------------------------
Tango::DbDatum TangoAccessControlClass::get_default_class_property(std::string &prop_name)
{
	for (unsigned int i=0 ; i<cl_def_prop.size() ; i++)
		if (cl_def_prop[i].name == prop_name)
			return cl_def_prop[i];
	//	if not found, return  an empty DbDatum
	return Tango::DbDatum(prop_name);
}


//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::set_default_property()
 *	Description : Set default property (class and device) for wizard.
 *                For each property, add to wizard property name and description.
 *                If default value has been set, add it to wizard property and
 *                store it in a DbDatum.
 */
//--------------------------------------------------------
void TangoAccessControlClass::set_default_property()
{
	std::string	prop_name;
	std::string	prop_desc;
	std::string	prop_def;
	std::vector<std::string>	vect_data;

	//	Set Default Class Properties

	//	Set Default device Properties
}

//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::write_class_property()
 *	Description : Set class description fields as property in database
 */
//--------------------------------------------------------
void TangoAccessControlClass::write_class_property()
{
	//	First time, check if database used
	if (Tango::Util::_UseDb == false)
		return;

	Tango::DbData	data;
	std::string	classname = get_name();
	std::string	header;

	//	Put title
	Tango::DbDatum	title("ProjectTitle");
	std::string	str_title("Tango Access Control Management");
	title << str_title;
	data.push_back(title);

	//	Put Description
	Tango::DbDatum	description("Description");
	std::vector<std::string>	str_desc;
	str_desc.push_back("This class is a conceate class inherited from AccessControl abstract class.<Br>");
	str_desc.push_back("<Br>");
	str_desc.push_back("This class defines how to manage the TANGO access control.<Br>");
	str_desc.push_back("It implements commands for tool to defines access for users, devices and IP addresses.<Br>");
	str_desc.push_back("It implements also commands used by client API to check access for specified user, device and address.<Br>");
	str_desc.push_back("And it implements register and unregister it as TANGO service.");
	description << str_desc;
	data.push_back(description);

	//  Put inheritance
	Tango::DbDatum	inher_datum("InheritedFrom");
	std::vector<std::string> inheritance;
	inheritance.push_back("TANGO_BASE_CLASS");
	inher_datum << inheritance;
	data.push_back(inher_datum);

	//	Call database and and values
	get_db_class()->put_property(data);
}

//===================================================================
//	Factory methods
//===================================================================

//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::device_factory()
 *	Description : Create the device object(s)
 *                and store them in the device list
 */
//--------------------------------------------------------
void TangoAccessControlClass::device_factory(const Tango::DevVarStringArray *devlist_ptr)
{
	/*----- PROTECTED REGION ID(TangoAccessControlClass::device_factory_before) ENABLED START -----*/

	//	Add your own code
	

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::device_factory_before

	//	Create devices and add it into the device list
	for (unsigned long i=0 ; i<devlist_ptr->length() ; i++)
	{
		TANGO_LOG_DEBUG << "Device name : " << (*devlist_ptr)[i].in() << std::endl;
		device_list.push_back(new TangoAccessControl(this, (*devlist_ptr)[i]));
	}

	//	Manage dynamic attributes if any
	erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list());

	//	Export devices to the outside world
	for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++)
	{
		//	Add dynamic attributes if any
		TangoAccessControl *dev = static_cast<TangoAccessControl *>(device_list[device_list.size()-i]);
		dev->add_dynamic_attributes();

		//	Check before if database used.
		if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false))
			export_device(dev);
		else
			export_device(dev, dev->get_name().c_str());
	}

	/*----- PROTECTED REGION ID(TangoAccessControlClass::device_factory_after) ENABLED START -----*/

	//	Add your own code
	

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::device_factory_after
}
//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::attribute_factory()
 *	Description : Create the attribute object(s)
 *                and store them in the attribute list
 */
//--------------------------------------------------------
void TangoAccessControlClass::attribute_factory(std::vector<Tango::Attr *> &att_list)
{
	/*----- PROTECTED REGION ID(TangoAccessControlClass::attribute_factory_before) ENABLED START -----*/

	//	Add your own code

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::attribute_factory_before
	//	Call atribute_factory for inherited class
	AccessControl_ns::AccessControlClass::attribute_factory(att_list);


	//	Create a list of static attributes
	create_static_attribute_list(get_class_attr()->get_attr_list());
	/*----- PROTECTED REGION ID(TangoAccessControlClass::attribute_factory_after) ENABLED START -----*/

	//	Add your own code

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::attribute_factory_after
}
//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::pipe_factory()
 *	Description : Create the pipe object(s)
 *                and store them in the pipe list
 */
//--------------------------------------------------------
void TangoAccessControlClass::pipe_factory()
{
	/*----- PROTECTED REGION ID(TangoAccessControlClass::pipe_factory_before) ENABLED START -----*/

	//	Add your own code

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::pipe_factory_before
	/*----- PROTECTED REGION ID(TangoAccessControlClass::pipe_factory_after) ENABLED START -----*/

	//	Add your own code

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::pipe_factory_after
}
//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::command_factory()
 *	Description : Create the command object(s)
 *                and store them in the command list
 */
//--------------------------------------------------------
void TangoAccessControlClass::command_factory()
{
	/*----- PROTECTED REGION ID(TangoAccessControlClass::command_factory_before) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::command_factory_before
	//	Call command_factory for inherited class
	AccessControl_ns::AccessControlClass::command_factory();



	//	Get inherited Command object AddAddressForUser if already created
	try
	{
		get_cmd_by_name("AddAddressForUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create AddAddressForUser command object
		AddAddressForUserClass	*pAddAddressForUserCmd =
			new AddAddressForUserClass("AddAddressForUser",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
				"user name, address",
				"",
				Tango::OPERATOR);
		command_list.push_back(pAddAddressForUserCmd);
	}

	//	Get inherited Command object AddDeviceForUser if already created
	try
	{
		get_cmd_by_name("AddDeviceForUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create AddDeviceForUser command object
		AddDeviceForUserClass	*pAddDeviceForUserCmd =
			new AddDeviceForUserClass("AddDeviceForUser",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
				"user name, device adn value",
				"",
				Tango::OPERATOR);
		command_list.push_back(pAddDeviceForUserCmd);
	}

	//	Get inherited Command object CloneUser if already created
	try
	{
		get_cmd_by_name("CloneUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create CloneUser command object
		CloneUserClass	*pCloneUserCmd =
			new CloneUserClass("CloneUser",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
				"[0] - source user name.\n[1] - target user name.",
				"",
				Tango::OPERATOR);
		command_list.push_back(pCloneUserCmd);
	}

	//	Get inherited Command object GetAccess if already created
	try
	{
		get_cmd_by_name("GetAccess");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetAccess command object
		GetAccessClass	*pGetAccessCmd =
			new GetAccessClass("GetAccess",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_STRING,
				"[0] - User name\n[1] - IP Address\n[2] - Device",
				"access for specified inputs  read/write.",
				Tango::OPERATOR);
		command_list.push_back(pGetAccessCmd);
	}

	//	Get inherited Command object GetAccessForMultiIP if already created
	try
	{
		get_cmd_by_name("GetAccessForMultiIP");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetAccessForMultiIP command object
		GetAccessForMultiIPClass	*pGetAccessForMultiIPCmd =
			new GetAccessForMultiIPClass("GetAccessForMultiIP",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_STRING,
				"[0] - User name\n[1] - Device\n[2] - IP Address #1\n[3] - IP Address #2\n[4] - IP Address #3\n[5] - IP Address #4\n......",
				"access for specified inputs  read/write.",
				Tango::OPERATOR);
		command_list.push_back(pGetAccessForMultiIPCmd);
	}

	//	Get inherited Command object GetAddressByUser if already created
	try
	{
		get_cmd_by_name("GetAddressByUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetAddressByUser command object
		GetAddressByUserClass	*pGetAddressByUserCmd =
			new GetAddressByUserClass("GetAddressByUser",
				Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY,
				"user name.",
				"Addresses found for the specified user.",
				Tango::OPERATOR);
		command_list.push_back(pGetAddressByUserCmd);
	}

	//	Get inherited Command object GetAllowedCommandClassList if already created
	try
	{
		get_cmd_by_name("GetAllowedCommandClassList");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetAllowedCommandClassList command object
		GetAllowedCommandClassListClass	*pGetAllowedCommandClassListCmd =
			new GetAllowedCommandClassListClass("GetAllowedCommandClassList",
				Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY,
				"",
				"Class names which have AllowedAccessCmd property defined.",
				Tango::OPERATOR);
		command_list.push_back(pGetAllowedCommandClassListCmd);
	}

	//	Get inherited Command object GetAllowedCommands if already created
	try
	{
		get_cmd_by_name("GetAllowedCommands");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetAllowedCommands command object
		GetAllowedCommandsClass	*pGetAllowedCommandsCmd =
			new GetAllowedCommandsClass("GetAllowedCommands",
				Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY,
				"Device name OR Device Class name",
				"Allowed commands found in database for specified device",
				Tango::OPERATOR);
		command_list.push_back(pGetAllowedCommandsCmd);
	}

	//	Get inherited Command object GetDeviceByUser if already created
	try
	{
		get_cmd_by_name("GetDeviceByUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetDeviceByUser command object
		GetDeviceByUserClass	*pGetDeviceByUserCmd =
			new GetDeviceByUserClass("GetDeviceByUser",
				Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY,
				"user name.",
				"devices and rights found for the specified user.",
				Tango::OPERATOR);
		command_list.push_back(pGetDeviceByUserCmd);
	}

	//	Get inherited Command object GetDeviceClass if already created
	try
	{
		get_cmd_by_name("GetDeviceClass");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetDeviceClass command object
		GetDeviceClassClass	*pGetDeviceClassCmd =
			new GetDeviceClassClass("GetDeviceClass",
				Tango::DEV_STRING, Tango::DEV_STRING,
				"Device name",
				"Class found in database for specified device",
				Tango::OPERATOR);
		command_list.push_back(pGetDeviceClassCmd);
	}

	//	Get inherited Command object GetUsers if already created
	try
	{
		get_cmd_by_name("GetUsers");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create GetUsers command object
		GetUsersClass	*pGetUsersCmd =
			new GetUsersClass("GetUsers",
				Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY,
				"",
				"Users find in table access_address.",
				Tango::OPERATOR);
		command_list.push_back(pGetUsersCmd);
	}

	//	Get inherited Command object RegisterService if already created
	try
	{
		get_cmd_by_name("RegisterService");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create RegisterService command object
		RegisterServiceClass	*pRegisterServiceCmd =
			new RegisterServiceClass("RegisterService",
				Tango::DEV_VOID, Tango::DEV_VOID,
				"",
				"",
				Tango::OPERATOR);
		command_list.push_back(pRegisterServiceCmd);
	}

	//	Get inherited Command object RemoveAddressForUser if already created
	try
	{
		get_cmd_by_name("RemoveAddressForUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create RemoveAddressForUser command object
		RemoveAddressForUserClass	*pRemoveAddressForUserCmd =
			new RemoveAddressForUserClass("RemoveAddressForUser",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
				"user name, address",
				"",
				Tango::OPERATOR);
		command_list.push_back(pRemoveAddressForUserCmd);
	}

	//	Get inherited Command object RemoveDeviceForUser if already created
	try
	{
		get_cmd_by_name("RemoveDeviceForUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create RemoveDeviceForUser command object
		RemoveDeviceForUserClass	*pRemoveDeviceForUserCmd =
			new RemoveDeviceForUserClass("RemoveDeviceForUser",
				Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID,
				"user name, device and value",
				"",
				Tango::OPERATOR);
		command_list.push_back(pRemoveDeviceForUserCmd);
	}

	//	Get inherited Command object RemoveUser if already created
	try
	{
		get_cmd_by_name("RemoveUser");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create RemoveUser command object
		RemoveUserClass	*pRemoveUserCmd =
			new RemoveUserClass("RemoveUser",
				Tango::DEV_STRING, Tango::DEV_VOID,
				"user name",
				"",
				Tango::OPERATOR);
		command_list.push_back(pRemoveUserCmd);
	}

	//	Get inherited Command object UnregisterService if already created
	try
	{
		get_cmd_by_name("UnregisterService");
	}
	catch (Tango::DevFailed &e)
	{
		//	Create UnregisterService command object
		UnregisterServiceClass	*pUnregisterServiceCmd =
			new UnregisterServiceClass("UnregisterService",
				Tango::DEV_VOID, Tango::DEV_VOID,
				"",
				"",
				Tango::OPERATOR);
		command_list.push_back(pUnregisterServiceCmd);
	}

	/*----- PROTECTED REGION ID(TangoAccessControlClass::command_factory_after) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::command_factory_after
}

//===================================================================
//	Dynamic attributes related methods
//===================================================================

//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::create_static_attribute_list
 * description : 	Create the a list of static attributes
 *
 * @param	att_list	the ceated attribute list
 */
//--------------------------------------------------------
void TangoAccessControlClass::create_static_attribute_list(std::vector<Tango::Attr *> &att_list)
{
	for (unsigned long i=0 ; i<att_list.size() ; i++)
	{
		std::string att_name(att_list[i]->get_name());
		transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower);
		defaultAttList.push_back(att_name);
	}

	TANGO_LOG_INFO << defaultAttList.size() << " attributes in default list" << std::endl;

	/*----- PROTECTED REGION ID(TangoAccessControlClass::create_static_att_list) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::create_static_att_list
}


//--------------------------------------------------------
/**
 * method : 		TangoAccessControlClass::erase_dynamic_attributes
 * description : 	delete the dynamic attributes if any.
 *
 * @param	devlist_ptr	the device list pointer
 * @param	list of all attributes
 */
//--------------------------------------------------------
void TangoAccessControlClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, std::vector<Tango::Attr *> &att_list)
{
	Tango::Util *tg = Tango::Util::instance();

	for (unsigned long i=0 ; i<devlist_ptr->length() ; i++)
	{
		Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((std::string)(*devlist_ptr)[i]).c_str());
		TangoAccessControl *dev = static_cast<TangoAccessControl *> (dev_impl);

		std::vector<Tango::Attribute *> &dev_att_list = dev->get_device_attr()->get_attribute_list();
		std::vector<Tango::Attribute *>::iterator ite_att;
		for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att)
		{
			std::string att_name((*ite_att)->get_name_lower());
			if ((att_name == "state") || (att_name == "status"))
				continue;
			std::vector<std::string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name);
			if (ite_str == defaultAttList.end())
			{
				TANGO_LOG_INFO << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << std::endl;
				Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str());
				dev->remove_attribute(att_list[att.get_attr_idx()], true, false);
				--ite_att;
			}
		}
	}
	/*----- PROTECTED REGION ID(TangoAccessControlClass::erase_dynamic_attributes) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::erase_dynamic_attributes
}

//--------------------------------------------------------
/**
 *	Method      : TangoAccessControlClass::get_attr_object_by_name()
 *	Description : returns Tango::Attr * object found by name
 */
//--------------------------------------------------------
Tango::Attr *TangoAccessControlClass::get_attr_object_by_name(std::vector<Tango::Attr *> &att_list, std::string attname)
{
	std::vector<Tango::Attr *>::iterator it;
	for (it=att_list.begin() ; it<att_list.end() ; ++it)
		if ((*it)->get_name()==attname)
			return (*it);
	//	Attr does not exist
	return NULL;
}


/*----- PROTECTED REGION ID(TangoAccessControlClass::Additional Methods) ENABLED START -----*/

	/*----- PROTECTED REGION END -----*/	//	TangoAccessControlClass::Additional Methods
} //	namespace
