/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#ifndef TANGO_SERVER_COMMAND_H
#define TANGO_SERVER_COMMAND_H

#include <tango/common/tango_const.h>
#include <tango/server/DeviceImpl.h>

#include <memory>
#include <string>

namespace Tango
{

typedef bool (DeviceImpl::*ALLO_PTR)(const CORBA::Any &);

/**
 * This class is a class representing a command in the TANGO device server
 * pattern. it is an abstract class. It is the root class for all command
 * related classes for command implemented with the inheritance model or
 * with the template command model
 *
 *
 * @headerfile tango.h
 * @ingroup Server
 */

class Command
{
  public:
    /**@name Constructors
     * Miscellaneous constructors */
    //@{
    /**
     * Constructs a newly allocated Command object.
     *
     * The default constructor
     */
    Command() :
        ext(new CommandExt)
    {
    }

    /**
     * Constructs a newly allocated Command object for a command from its
     * name and its input and output parameter types.
     * The input and output parameter description are set to the default String
     * "Uninitialised".
     *
     * @param     s    The command name
     * @param    in    The command input parameter type
     * @param    out     The command output parameter type
     * @param    level    The command display level
     *
     */
    Command(const std::string &s,
            Tango::CmdArgType in,
            Tango::CmdArgType out,
            Tango::DispLevel level = Tango::OPERATOR);

    /**
     * Constructs a newly allocated Command object for a command from its
     * name, its input and output parameter types plus parameters description
     *
     * @param     s    The command name
     * @param    in    The command input parameter type
     * @param    out     The command output parameter type
     * @param    in_desc    The input parameter description
     * @param    out_desc The output parameter description
     * @param    level    The command display level
     *
     */
    Command(const std::string &s,
            Tango::CmdArgType in,
            Tango::CmdArgType out,
            const std::string &in_desc,
            const std::string &out_desc,
            Tango::DispLevel level = Tango::OPERATOR);

    //@}

    /**@name Destructor
     * Only one desctructor is defined for this class */
    //@{
    /**
     * The object desctructor.
     */
    virtual ~Command() { }

    //@}

    /**@name Miscellaneous methods */
    //@{
    /**
     * Execute the command.
     *
     * This method is automtically called by the TANGO core classes when the
     * associated command is requested by a client. This method is abstract and must be redefined
     * in each sub-class
     *
     * @param dev The device on which the command must be executed
     * @param in_any The incoming data still packed in a CORBA Any object.
     * @return The CORBA Any object returned to the client.
     * @exception DevFailed If the execution method failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    virtual CORBA::Any *execute(DeviceImpl *dev, const CORBA::Any &in_any) = 0;

    /**
     * Check if the command is allowed in the actual device state.
     *
     * This method is automtically called by the TANGO core classes when the
     * associated command is requested by a client to check if the command is allowed
     * in the actual device state. This method is the default is_allowed method which
     * always allows the command to be executed. It is possible to re-define it
     * if this default behaviour does not fulfill the device needs.
     *
     * @param dev The device on which the command must be executed
     * @param in_any The incoming data still packed in a CORBA Any object. This
     * data is passed to this method in case it is necessary to take the command
     * allowed decision
     * @return A boolean set to true is the command is allowed. Otherwise, the
     * return value is false.
     */
    virtual bool is_allowed(DeviceImpl *dev, const CORBA::Any &in_any)
    {
        (void) dev;
        (void) in_any;
        return true;
    }

    /**
     * Init command parameters type.
     *
     * This method is used only for command implemented using the Tango template
     * command model. In this base class, it does nothing and is re-define in
     * sub-classes.
     *
     */
    virtual void init_types() { }

    //@}

    /**@name Get/Set object members.
     * These methods allows the external world to get/set DeviceImpl instance
     * data members
     */
    //@{
    /**
     * Return the command name.
     *
     * @return The command name
     */
    std::string &get_name()
    {
        return name;
    }

    /**
     * Set the command name.
     *
     * @param new_name The new command name
     */
    void set_name(const std::string &new_name)
    {
        name = new_name;
    }

    /**
     * Return the command name in lower case letters.
     *
     * @return The command name
     */
    std::string &get_lower_name()
    {
        return lower_name;
    }

    /**
     * Return the input parameter type.
     *
     * @return The input parameter type
     */
    Tango::CmdArgType get_in_type()
    {
        return in_type;
    }

    /**
     * Return the output parameter type.
     *
     * @return The output parameter type
     */
    Tango::CmdArgType get_out_type()
    {
        return out_type;
    }

    /**
     * Return the input parameter description.
     *
     * @return The input parameter description
     */
    std::string &get_in_type_desc()
    {
        return in_type_desc;
    }

    /**
     * Return the output parameter description.
     *
     * @return The output parameter description
     */
    std::string &get_out_type_desc()
    {
        return out_type_desc;
    }

    /**
     * Return the command display level.
     *
     * @return The command display level
     */
    Tango::DispLevel get_disp_level()
    {
        return cmd_disp_level;
    }

    /**
     * Set the input parameter description field.
     *
     * @param desc The input parameter description
     */
    void set_in_type_desc(std::string desc)
    {
        in_type_desc = desc;
    }

    /**
     * Set the output parameter description field.
     *
     * @param desc The output parameter description
     */
    void set_out_type_desc(std::string desc)
    {
        out_type_desc = desc;
    }

    /**
     * Set the command display level.
     *
     * @param level The command display level
     */
    void set_disp_level(Tango::DispLevel level)
    {
        cmd_disp_level = level;
    }

    /**
     * Set the command polling period.
     *
     * @param per The command polling period (in mS)
     */
    void set_polling_period(long per)
    {
        poll_period = per;
    }

    /**
     * Get the command polling period.
     *
     * @return The command polling period (in mS)
     */
    long get_polling_period()
    {
        return poll_period;
    }

    //@}

    /**@name Extract methods.
     * All these methods extract data from the CORBA Any object received as
     * command input data
     */
    //@{
    /**
     * Extract a boolean data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted boolean data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevBoolean &data);

    /**
     * Extract a short data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted short data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevShort &data);

    /**
     * Extract a long data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted long data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevLong &data);

    /**
     * Extract a 64 bits long data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted 64 bits long data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevLong64 &data);

    /**
     * Extract a float data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted float data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevFloat &data);

    /**
     * Extract a double data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted double data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevDouble &data);

    /**
     * Extract an unsigned short data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned short data
     * @exception DevFailed If the Any object does not contanis a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevUShort &data);

    /**
     * Extract an unsigned long data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned long data
     * @exception DevFailed If the Any object does not contanis a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevULong &data);

    /**
     * Extract an unsigned 64 bits long data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned 64 bits long data
     * @exception DevFailed If the Any object does not contanis a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevULong64 &data);

    /**
     * Extract a string from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted string data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevString &data);

    /**
     * Extract a const string from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted string data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const char *&data);

    /**
     * Extract a char array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted char array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarCharArray *&data);

    /**
     * Extract a short array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted short array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarShortArray *&data);

    /**
     * Extract a long array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted long array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarLongArray *&data);

    /**
     * Extract a 64 bits long array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted 64 bits long array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarLong64Array *&data);

    /**
     * Extract a float array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted float array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarFloatArray *&data);

    /**
     * Extract a double array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted double array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarDoubleArray *&data);

    /**
     * Extract a unsigned short array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned char array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarUShortArray *&data);

    /**
     * Extract a unsigned long array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned long array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarULongArray *&data);

    /**
     * Extract a unsigned 64 bits long array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted unsigned 64 bits long array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarULong64Array *&data);

    /**
     * Extract a string array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted string array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarStringArray *&data);

    /**
     * Extract a string array from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted string array
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarBooleanArray *&data);

    /**
     * Extract a DevVarLongStringArray data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted DevVarLongStringArray data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarLongStringArray *&data);

    /**
     * Extract a DevVarDoubleStringArray data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted DevVarDoubleStringArray data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevVarDoubleStringArray *&data);

    /**
     * Extract a Tango device state data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted device state data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, Tango::DevState &data);

    /**
     * Extract a Tango DevEncoded data from a CORBA Any object.
     *
     * @param in The CORBA Any object
     * @param data Reference to the extracted DevEncoded data
     * @exception DevFailed If the Any object does not contains a data of the
     * waited type.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    void extract(const CORBA::Any &in, const Tango::DevEncoded *&data);
    //@}

    /**@name Insert methods.
     * All these methods create a CORBA Any object and insert data into this object
     */
    //@{
    /**
     * Create an  empty CORBA Any object.
     *
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert();

    /**
     * Create a CORBA Any object and insert a Tango::DevBoolean data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevBoolean data);

    /**
     * Create a CORBA Any object and insert a Tango::DevShort data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevShort data);

    /**
     * Create a CORBA Any object and insert a Tango::DevLong data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevLong data);

    /**
     * Create a CORBA Any object and insert a Tango::DevLong64 data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevLong64 data);

    /**
     * Create a CORBA Any object and insert a Tango::DevFloat data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevFloat data);

    /**
     * Create a CORBA Any object and insert a Tango::DevDouble data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevDouble data);

    /**
     * Create a CORBA Any object and insert a Tango::DevUShort data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevUShort data);

    /**
     * Create a CORBA Any object and insert a Tango::DevULong data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevULong data);

    /**
     * Create a CORBA Any object and insert a Tango::DevULong64 data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevULong64 data);

    /**
     * Create a CORBA Any object and insert a Tango::DevString data in it.
     *
     * This method will also de-allocate the string passed as parameter.
     *
     * @param data The string to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevString data);

    /**
     * Create a CORBA Any object and insert a Tango::DevString data in it.
     * Te parameter type is char * and not Tango::DevString because the const
     * C++ modifier applied to a Tango::DevString make the pointer constant and
     * not the pointed to characters to be constant.
     *
     * @param data The string to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(const char *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarCharArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarCharArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarCharArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarCharArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarCharArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarShortArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarShortArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarShortArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarShortArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarShortArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLongArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLongArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLongArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarLongArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLongArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLong64Array data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLong64Array &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLong64Array data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarLongArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLong64Array *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarFloatArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarFloatArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarFloatArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarFloatArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarFloatArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarDoubleArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarDoubleArray &data);

    /**
     * Create a CORBA CORBA::Any object and insert a Tango::DevVarDoubleArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarDoubleArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarDoubleArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarUShortArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarUShortArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarUShortArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarUShortArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarUShortArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarULongArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarULongArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarULongArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarULongArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarULongArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarULong64Array data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarULong64Array &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarULong64Array data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarULongArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarULong64Array *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarStringArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarStringArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarStringArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarStringArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarStringArray *data);

    // TODO templates
    /**
     * Create a CORBA Any object and insert a Tango::DevVarBooleanArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(DevVarBooleanArray *data);
    /**
     * Create a CORBA Any object and insert a Tango::DevVarBooleanArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarBooleanArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(DevVarBooleanArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLongStringArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLongStringArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarLongStringArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarLongStringArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarLongStringArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarDoubleStringArray data in it.
     *
     * This method will do a <b>deep copy</b> of the array into the Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarDoubleStringArray &data);

    /**
     * Create a CORBA Any object and insert a Tango::DevVarDoubleStringArray data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarDoubleStringArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevVarDoubleStringArray *data);

    /**
     * Create a CORBA Any object and insert a Tango::DevState data in it.
     *
     * @param data The data to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevState data);

    /**
     * Create a CORBA Any object and insert a Tango::DevEncoded data in it.
     *
     * This method <b>consumes</b> the memory used by the array.
     * When the CORBA layer will destroy the Any object, the memory allocated
     * for the array will also be freed. This is the recommended method to
     * insert Tango::DevVarDoubleStringArray data type into a CORBA Any object.
     *
     * @param data The array to be inserted into the Any object
     * @exception DevFailed If the Any object creation failed.
     * Click <a href="https://tango-controls.readthedocs.io/en/latest/development/advanced/IDL.html#exceptions">here</a>
     * to read <b>DevFailed</b> exception specification
     */
    CORBA::Any *insert(Tango::DevEncoded *data);
    //@}

  protected:
    /**@name Class data members */
    //@{
    /**
     * The command name
     */
    std::string name;
    /**
     * The command name in lower case
     */
    std::string lower_name;
    /**
     * The command input parameter type
     */
    Tango::CmdArgType in_type;
    /**
     * The command output parameter type
     */
    Tango::CmdArgType out_type;
    /**
     * The command input parameter description
     */
    std::string in_type_desc;
    /**
     * The command output parameter type
     */
    std::string out_type_desc;
    //@}

  private:
    class CommandExt
    {
      public:
        CommandExt() { }
    };

    void alloc_any(CORBA::Any *&);
    void throw_bad_type(const char *);

    std::unique_ptr<CommandExt> ext; // Class extension

    //
    // Ported from the extension class
    //

    Tango::DispLevel cmd_disp_level; // Display  level
    long poll_period;                // Polling period
};

} // namespace Tango

#endif // TANGO_SERVER_COMMAND_H
