endpoint: Decorates a function to make it a CLI endpoint
        
        The function must be called do_<some>_<action> and accept one 'args'
        parameter. It will be converted into a ./cli some action commandline
        endpoint.
        
        A set of Arguments can be passed to the decorator, the syntax is the
        same than the argparse add_argument function.

def endpoint(self, *args):
        """endpoint: Decorates a function to make it a CLI endpoint
        
        The function must be called do_<some>_<action> and accept one 'args'
        parameter. It will be converted into a ./cli some action commandline
        endpoint.
        
        A set of Arguments can be passed to the decorator, the syntax is the
        same than the argparse add_argument function.
        """
        # Decorator function
        def decorator(func):
            func_name = func.__name__
            func_name = func_name.replace("do_", "")
            actions = func_name.split("_")
            cmd_parser = None
            sub = self.subparsers
            wcount = 0
            # For each word in the command we build the parsing tree
            for word in actions:
                parser_name = '_'.join(actions[:wcount+1])
                # If the parser exist, we use it, otherwise we create it
                if self.parsers.has_key(parser_name):
                    cmd_parser = self.parsers[parser_name]
                else:
                    cmd_parser = sub.add_parser(word)
                    self.parsers[parser_name] = cmd_parser
                # We don't want to add a subparser to the final endpoint,
                # since it would require a void positional argument and
                # fuck up the whole thing.
                if wcount != len(actions) - 1:
                    # Same that with the parsers, it it exist we use it
                    # otherwise we create it. It avoids overwrites
                    if self.parsers.has_key("sub_"+parser_name):
                        sub = self.parsers["sub_"+parser_name]
                    else:
                        sub = cmd_parser.add_subparsers()
                        self.parsers["sub_"+parser_name] = sub
                wcount += 1
            # Bind the endpoint to the function
            cmd_parser.set_defaults(func=func)
            # We add the arguments to the function
            for argument in args:
                if type(argument) == Argument:
                    cmd_parser.add_argument(*argument.args, **argument.kwargs)
                elif type(argument) == ExclusiveGroup:
                    group = cmd_parser.add_mutually_exclusive_group(required=argument.required)
                    for arg in argument.args:
                        group.add_argument(*arg.args, **arg.kwargs)
            
            # Standard inner function
            def inner(*args, **kwargs):
                return func(*args, **kwargs)
                
            return inner
        return decorator