Register a method to a command.

        NOTE: Method registered here is unbound method,
              e.g. registered `run` command -> `KngetShell.run`
              So we call it should add `self` at first.

            See also: KngetShell.execute()

        :param argtypes: a str of the command args type.
            M: Myself -> self
            S: String -> str
            I: Integer -> int
            H: placeHolder -> pass or anything
        :param help_msg: a short help string of commands.
        :return: a callable function or method.

def register(self, argtypes=r'M', help_msg=None):
        """Register a method to a command.

        NOTE: Method registered here is unbound method,
              e.g. registered `run` command -> `KngetShell.run`
              So we call it should add `self` at first.

            See also: KngetShell.execute()

        :param argtypes: a str of the command args type.
            M: Myself -> self
            S: String -> str
            I: Integer -> int
            H: placeHolder -> pass or anything
        :param help_msg: a short help string of commands.
        :return: a callable function or method.
        """

        def format_args(method):
            def wrapped_method(*args, **kwargs):
                args_count = len(args)  # + len(kwargs)
                argtypes_count = len(argtypes)
                placeholder_count = argtypes.count('H') + argtypes.count('h')

                # We check the placeholder count to select a way to
                # format the args. If placeholder is not equals zero
                # then we calculate the minimum args count at first.

                if placeholder_count:
                    min_args_count = (argtypes_count - placeholder_count)

                    # If args_count less than minimum args count or bigger
                    # than argtypes count then we raise a Exception to exit.
                    if args_count < min_args_count or args_count > argtypes_count:
                        raise KngetError("args count is invalid.",
                                         reason='args count is {0}'.format(args_count))

                # Otherwise, we just check if args count equals argtypes count
                elif args_count != argtypes_count:
                    raise KngetError("args count is invalid",
                                     reason='args count is {0}'.format(args_count))

                argv = []  # NOTE: We cannot modify the args.
                for i in range(args_count):
                    if argtypes[i] in ('m', 'M'):
                        argv.append(args[i])
                    elif argtypes[i] in ('i', 'I'):
                        argv.append(int(args[i]))
                    elif argtypes[i] in ('s', 'S'):
                        argv.append(str(args[i]))
                    elif argtypes[i] in ('h', 'H'):
                        argv.append(args[i])
                    else:
                        raise KngetError('argtype {0} is invalid!'.format(argtypes[i]))

                return method(*argv, **kwargs)

            # Keep the docs.
            wrapped_method.__doc__ = method.__doc__

            self._commands[method.__name__] = (
                wrapped_method, help_msg
            )
            return wrapped_method

        # only format_args touched the method
        return format_args