def __create_command(self, deviceimpl_class, cmd_name, cmd_info):
    """for internal usage only"""
    name = self.get_name()

    # check for well defined command info

    # check parameter
    if not isinstance(cmd_info, collections_abc.Sequence):
        msg = "Wrong data type for value for describing command %s in " \
              "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
        __throw_create_command_exception(msg)

    if len(cmd_info) < 2 or len(cmd_info) > 3:
        msg = "Wrong number of argument for describing command %s in " \
              "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
        __throw_create_command_exception(msg)

    param_info, result_info = cmd_info[0], cmd_info[1]

    if not isinstance(param_info, collections_abc.Sequence):
        msg = "Wrong data type in command argument for command %s in " \
              "class %s\nCommand parameter (first element) must be a sequence" % (cmd_name, name)
        __throw_create_command_exception(msg)

    if len(param_info) < 1 or len(param_info) > 2:
        msg = "Wrong data type in command argument for command %s in " \
              "class %s\nSequence describing command parameters must contain " \
              "1 or 2 elements"
        __throw_create_command_exception(msg)

    param_type = CmdArgType.DevVoid
    try:
        param_type = CmdArgType(param_info[0])
    except:
        msg = "Wrong data type in command argument for command %s in " \
              "class %s\nCommand parameter type (first element in first " \
              "sequence) must be a tango.CmdArgType"
        __throw_create_command_exception(msg)

    param_desc = ""
    if len(param_info) > 1:
        param_desc = param_info[1]
        if not is_pure_str(param_desc):
            msg = "Wrong data type in command parameter for command %s in " \
                  "class %s\nCommand parameter description (second element " \
                  "in first sequence), when given, must be a string"
            __throw_create_command_exception(msg)

    # Check result
    if not isinstance(result_info, collections_abc.Sequence):
        msg = "Wrong data type in command result for command %s in " \
              "class %s\nCommand result (second element) must be a sequence" % (cmd_name, name)
        __throw_create_command_exception(msg)

    if len(result_info) < 1 or len(result_info) > 2:
        msg = "Wrong data type in command result for command %s in " \
              "class %s\nSequence describing command result must contain " \
              "1 or 2 elements" % (cmd_name, name)
        __throw_create_command_exception(msg)

    result_type = CmdArgType.DevVoid
    try:
        result_type = CmdArgType(result_info[0])
    except:
        msg = "Wrong data type in command result for command %s in " \
              "class %s\nCommand result type (first element in second " \
              "sequence) must be a tango.CmdArgType" % (cmd_name, name)
        __throw_create_command_exception(msg)

    result_desc = ""
    if len(result_info) > 1:
        result_desc = result_info[1]
        if not is_pure_str(result_desc):
            msg = "Wrong data type in command result for command %s in " \
                  "class %s\nCommand parameter description (second element " \
                  "in second sequence), when given, must be a string" % (cmd_name, name)
            __throw_create_command_exception(msg)

    # If it is defined, get addictional dictionnary used for optional parameters
    display_level, default_command, polling_period = DispLevel.OPERATOR, False, -1

    if len(cmd_info) == 3:
        extra_info = cmd_info[2]
        if not isinstance(extra_info, collections_abc.Mapping):
            msg = "Wrong data type in command information for command %s in " \
                  "class %s\nCommand information (third element in sequence), " \
                  "when given, must be a dictionary" % (cmd_name, name)
            __throw_create_command_exception(msg)

        if len(extra_info) > 3:
            msg = "Wrong data type in command information for command %s in " \
                  "class %s\nThe optional dictionary can not have more than " \
                  "three elements" % (cmd_name, name)
            __throw_create_command_exception(msg)

        for info_name, info_value in extra_info.items():
            info_name_lower = info_name.lower()
            if info_name_lower == "display level":
                try:
                    display_level = DispLevel(info_value)
                except:
                    msg = "Wrong data type in command information for command %s in " \
                          "class %s\nCommand information for display level is not a " \
                          "tango.DispLevel" % (cmd_name, name)
                    __throw_create_command_exception(msg)
            elif info_name_lower == "default command":
                if not is_pure_str(info_value):
                    msg = "Wrong data type in command information for command %s in " \
                          "class %s\nCommand information for default command is not a " \
                          "string" % (cmd_name, name)
                    __throw_create_command_exception(msg)
                v = info_value.lower()
                default_command = v == 'true'
            elif info_name_lower == "polling period":
                try:
                    polling_period = int(info_value)
                except:
                    msg = "Wrong data type in command information for command %s in " \
                          "class %s\nCommand information for polling period is not an " \
                          "integer" % (cmd_name, name)
                    __throw_create_command_exception(msg)
            else:
                msg = "Wrong data type in command information for command %s in " \
                      "class %s\nCommand information has unknown key " \
                      "%s" % (cmd_name, name, info_name)
                __throw_create_command_exception(msg)

    # check that the method to be executed exists
    try:
        cmd = getattr(deviceimpl_class, cmd_name)
        if not isinstance(cmd, collections_abc.Callable):
            msg = "Wrong definition of command %s in " \
                  "class %s\nThe object exists in class but is not " \
                  "a method!" % (cmd_name, name)
            __throw_create_command_exception(msg)
    except AttributeError:
        msg = "Wrong definition of command %s in " \
              "class %s\nThe command method does not exist!" % (cmd_name, name)
        __throw_create_command_exception(msg)

    is_allowed_name = "is_%s_allowed" % cmd_name
    try:
        is_allowed = getattr(deviceimpl_class, is_allowed_name)
        if not isinstance(is_allowed, collections_abc.Callable):
            msg = "Wrong definition of command %s in " \
                  "class %s\nThe object '%s' exists in class but is " \
                  "not a method!" % (cmd_name, name, is_allowed_name)
            __throw_create_command_exception(msg)
    except:
        is_allowed_name = ""

    self._create_command(cmd_name, param_type, result_type,
                         param_desc, result_desc,
                         display_level, default_command,
                         polling_period, is_allowed_name)
for internal usage only